mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b7b01fd788 | |||
| 2c07a242ea | |||
| a63c77a977 | |||
| 43219e50e0 | |||
| 49b9860899 | |||
| 0388d79770 | |||
| c0fa1aec66 | |||
| 6e61b7f6ef | |||
| a76e778804 |
@@ -25,7 +25,6 @@ CompileFlags:
|
|||||||
Diagnostics:
|
Diagnostics:
|
||||||
Suppress:
|
Suppress:
|
||||||
- pp_including_mainfile_in_preamble
|
- pp_including_mainfile_in_preamble
|
||||||
- unused-includes
|
|
||||||
---
|
---
|
||||||
# Amalgamated files that require or partly define an implementation
|
# Amalgamated files that require or partly define an implementation
|
||||||
If:
|
If:
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
name: Doxygen GitHub Pages
|
name: Doxygen GitHub Pages
|
||||||
|
|
||||||
on:
|
on:
|
||||||
release:
|
push:
|
||||||
types: [created]
|
branches:
|
||||||
|
- master
|
||||||
# Allows you to run this workflow manually from the Actions tab
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
implementations: haswell westmere fallback
|
implementations: haswell westmere fallback
|
||||||
UBSAN_OPTIONS: halt_on_error=1
|
UBSAN_OPTIONS: halt_on_error=1
|
||||||
MAXLEN: -max_len=4000
|
MAXLEN: -max_len=4000
|
||||||
CLANGVERSION: 19
|
CLANGVERSION: 15
|
||||||
# which optimization level to use for the sanitizer build (see build_fuzzer.variants.sh)
|
# which optimization level to use for the sanitizer build (see build_fuzzer.variants.sh)
|
||||||
OPTLEVEL: -O3
|
OPTLEVEL: -O3
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
- msystem: "MINGW64"
|
- msystem: "MINGW64"
|
||||||
install: mingw-w64-x86_64-libxml2 mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-clang
|
install: mingw-w64-x86_64-libxml2 mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-clang
|
||||||
type: Debug
|
type: Debug
|
||||||
- msystem: "MINGW64"
|
- msystem: "MINGW64"
|
||||||
install: mingw-w64-x86_64-libxml2 mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-clang
|
install: mingw-w64-x86_64-libxml2 mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-clang
|
||||||
type: RelWithDebInfo
|
type: RelWithDebInfo
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
- {arch: ARM}
|
||||||
- {arch: ARM64}
|
- {arch: ARM64}
|
||||||
- {arch: ARM64EC}
|
- {arch: ARM64EC}
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
+10
-20
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
|
|||||||
project(
|
project(
|
||||||
simdjson
|
simdjson
|
||||||
# The version number is modified by tools/release.py
|
# The version number is modified by tools/release.py
|
||||||
VERSION 3.11.6
|
VERSION 3.10.0
|
||||||
DESCRIPTION "Parsing gigabytes of JSON per second"
|
DESCRIPTION "Parsing gigabytes of JSON per second"
|
||||||
HOMEPAGE_URL "https://simdjson.org/"
|
HOMEPAGE_URL "https://simdjson.org/"
|
||||||
LANGUAGES CXX C
|
LANGUAGES CXX C
|
||||||
@@ -20,14 +20,10 @@ string(
|
|||||||
# ---- Options, variables ----
|
# ---- Options, variables ----
|
||||||
|
|
||||||
# These version numbers are modified by tools/release.py
|
# These version numbers are modified by tools/release.py
|
||||||
set(SIMDJSON_LIB_VERSION "24.0.0" CACHE STRING "simdjson library version")
|
set(SIMDJSON_LIB_VERSION "23.0.0" CACHE STRING "simdjson library version")
|
||||||
set(SIMDJSON_LIB_SOVERSION "24" CACHE STRING "simdjson library soversion")
|
set(SIMDJSON_LIB_SOVERSION "23" CACHE STRING "simdjson library soversion")
|
||||||
|
|
||||||
option(SIMDJSON_BUILD_STATIC_LIB "Build simdjson_static library along with simdjson (only makes sense if BUILD_SHARED_LIBS=ON)" OFF)
|
option(SIMDJSON_BUILD_STATIC_LIB "Build simdjson_static library along with simdjson" OFF)
|
||||||
if(SIMDJSON_BUILD_STATIC_LIB AND NOT BUILD_SHARED_LIBS)
|
|
||||||
message(WARNING "SIMDJSON_BUILD_STATIC_LIB only makes sense if BUILD_SHARED_LIBS is set to ON")
|
|
||||||
message(WARNING "You might be building and installing a two identical static libraries.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(SIMDJSON_ENABLE_THREADS "Link with thread support" ON)
|
option(SIMDJSON_ENABLE_THREADS "Link with thread support" ON)
|
||||||
|
|
||||||
@@ -55,7 +51,6 @@ endif()
|
|||||||
if(is_top_project)
|
if(is_top_project)
|
||||||
option(SIMDJSON_DEVELOPER_MODE "Enable targets for developing simdjson" OFF)
|
option(SIMDJSON_DEVELOPER_MODE "Enable targets for developing simdjson" OFF)
|
||||||
option(BUILD_SHARED_LIBS "Build simdjson as a shared library" OFF)
|
option(BUILD_SHARED_LIBS "Build simdjson as a shared library" OFF)
|
||||||
option(SIMDJSON_SINGLEHEADER "Disable singleheader generation" ON)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(cmake/handle-deprecations.cmake)
|
include(cmake/handle-deprecations.cmake)
|
||||||
@@ -160,13 +155,11 @@ endif()
|
|||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
if(SIMDJSON_SINGLEHEADER)
|
install(
|
||||||
install(
|
FILES singleheader/simdjson.h
|
||||||
FILES singleheader/simdjson.h
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
COMPONENT simdjson_Development
|
||||||
COMPONENT simdjson_Development
|
)
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS simdjson
|
TARGETS simdjson
|
||||||
@@ -210,7 +203,6 @@ if(SIMDJSON_BUILD_STATIC_LIB)
|
|||||||
TARGETS simdjson_static
|
TARGETS simdjson_static
|
||||||
EXPORT simdjson_staticTargets
|
EXPORT simdjson_staticTargets
|
||||||
ARCHIVE COMPONENT simdjson_Development
|
ARCHIVE COMPONENT simdjson_Development
|
||||||
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
|
||||||
)
|
)
|
||||||
install(
|
install(
|
||||||
EXPORT simdjson_staticTargets
|
EXPORT simdjson_staticTargets
|
||||||
@@ -287,7 +279,6 @@ enable_testing()
|
|||||||
add_custom_target(all_tests)
|
add_custom_target(all_tests)
|
||||||
|
|
||||||
add_subdirectory(windows)
|
add_subdirectory(windows)
|
||||||
include(cmake/CPM.cmake)
|
|
||||||
add_subdirectory(dependencies) ## This needs to be before tools because of cxxopts
|
add_subdirectory(dependencies) ## This needs to be before tools because of cxxopts
|
||||||
add_subdirectory(tools) ## This needs to be before tests because of cxxopts
|
add_subdirectory(tools) ## This needs to be before tests because of cxxopts
|
||||||
|
|
||||||
@@ -295,9 +286,8 @@ add_subdirectory(tools) ## This needs to be before tests because of cxxopts
|
|||||||
# most of the data has been moved to https://github.com/simdjson/simdjson-data
|
# most of the data has been moved to https://github.com/simdjson/simdjson-data
|
||||||
add_subdirectory(jsonexamples)
|
add_subdirectory(jsonexamples)
|
||||||
|
|
||||||
if(SIMDJSON_SINGLEHEADER)
|
|
||||||
add_subdirectory(singleheader)
|
add_subdirectory(singleheader)
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = "3.11.6"
|
PROJECT_NUMBER = "3.10.0"
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ Table of Contents
|
|||||||
* [Documentation](#documentation)
|
* [Documentation](#documentation)
|
||||||
* [Godbolt](#godbolt)
|
* [Godbolt](#godbolt)
|
||||||
* [Performance results](#performance-results)
|
* [Performance results](#performance-results)
|
||||||
* [Packages](#packages)
|
|
||||||
* [Bindings and Ports of simdjson](#bindings-and-ports-of-simdjson)
|
* [Bindings and Ports of simdjson](#bindings-and-ports-of-simdjson)
|
||||||
* [About simdjson](#about-simdjson)
|
* [About simdjson](#about-simdjson)
|
||||||
* [Funding](#funding)
|
* [Funding](#funding)
|
||||||
@@ -144,9 +143,6 @@ speed for [synthetic files over various sizes generated with a script](https://g
|
|||||||
For NDJSON files, we can exceed 3 GB/s with [our multithreaded parsing functions](https://github.com/simdjson/simdjson/blob/master/doc/parse_many.md).
|
For NDJSON files, we can exceed 3 GB/s with [our multithreaded parsing functions](https://github.com/simdjson/simdjson/blob/master/doc/parse_many.md).
|
||||||
|
|
||||||
|
|
||||||
Packages
|
|
||||||
------------------------------
|
|
||||||
[](https://repology.org/project/simdjson/versions)
|
|
||||||
|
|
||||||
|
|
||||||
Bindings and Ports of simdjson
|
Bindings and Ports of simdjson
|
||||||
@@ -205,8 +201,8 @@ For the video inclined, <br />
|
|||||||
Funding
|
Funding
|
||||||
-------
|
-------
|
||||||
|
|
||||||
The work is supported by the Natural Sciences and Engineering Research Council of Canada under grants
|
The work is supported by the Natural Sciences and Engineering Research Council of Canada under grant
|
||||||
RGPIN-2017-03910 and RGPIN-2024-03787.
|
number RGPIN-2017-03910.
|
||||||
|
|
||||||
[license]: LICENSE
|
[license]: LICENSE
|
||||||
[license img]: https://img.shields.io/badge/License-Apache%202-blue.svg
|
[license img]: https://img.shields.io/badge/License-Apache%202-blue.svg
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
|
||||||
#
|
|
||||||
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors
|
|
||||||
|
|
||||||
set(CPM_DOWNLOAD_VERSION 0.40.2)
|
|
||||||
set(CPM_HASH_SUM "c8cdc32c03816538ce22781ed72964dc864b2a34a310d3b7104812a5ca2d835d")
|
|
||||||
|
|
||||||
if(CPM_SOURCE_CACHE)
|
|
||||||
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
|
|
||||||
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
|
|
||||||
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
|
|
||||||
else()
|
|
||||||
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Expand relative path. This is important if the provided path contains a tilde (~)
|
|
||||||
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
|
|
||||||
|
|
||||||
file(DOWNLOAD
|
|
||||||
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
|
|
||||||
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
|
|
||||||
)
|
|
||||||
|
|
||||||
include(${CPM_DOWNLOAD_LOCATION})
|
|
||||||
Vendored
+37
-76
@@ -1,4 +1,5 @@
|
|||||||
include(CMakeDependentOption)
|
include(CMakeDependentOption)
|
||||||
|
include(import.cmake)
|
||||||
|
|
||||||
option(SIMDJSON_ALLOW_DOWNLOADS
|
option(SIMDJSON_ALLOW_DOWNLOADS
|
||||||
"Allow dependencies to be downloaded during configure time"
|
"Allow dependencies to be downloaded during configure time"
|
||||||
@@ -10,21 +11,17 @@ cmake_dependent_option(SIMDJSON_GOOGLE_BENCHMARKS "compile the Google Benchmark
|
|||||||
SIMDJSON_ALLOW_DOWNLOADS OFF)
|
SIMDJSON_ALLOW_DOWNLOADS OFF)
|
||||||
|
|
||||||
if(SIMDJSON_GOOGLE_BENCHMARKS)
|
if(SIMDJSON_GOOGLE_BENCHMARKS)
|
||||||
CPMAddPackage(
|
set_off(BENCHMARK_ENABLE_TESTING)
|
||||||
NAME google_benchmarks
|
set_off(BENCHMARK_ENABLE_INSTALL)
|
||||||
URL https://github.com/google/benchmark/archive/refs/tags/v1.7.1.zip
|
set_off(BENCHMARK_ENABLE_WERROR)
|
||||||
OPTIONS
|
|
||||||
"BENCHMARK_ENABLE_TESTING OFF"
|
import_dependency(google_benchmarks google/benchmark v1.7.1)
|
||||||
"BENCHMARK_ENABLE_INSTALL OFF"
|
add_dependency(google_benchmarks)
|
||||||
"BENCHMARK_ENABLE_WERROR OFF"
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
CPMAddPackage(
|
# The bulk of our benchmarking and testing data has been moved simdjson/simdjson-data
|
||||||
NAME simdjson-data
|
import_dependency(simdjson-data simdjson/simdjson-data a5b13babe65c1bba7186b41b43d4cbdc20a5c470)
|
||||||
URL https://github.com/simdjson/simdjson-data/archive/a5b13babe65c1bba7186b41b43d4cbdc20a5c470.zip
|
add_dependency(simdjson-data)
|
||||||
)
|
|
||||||
|
|
||||||
option(SIMDJSON_USE_BOOST_JSON "Try to include BOOST_JSON, this may break your binaries under some systems." OFF)
|
option(SIMDJSON_USE_BOOST_JSON "Try to include BOOST_JSON, this may break your binaries under some systems." OFF)
|
||||||
# This prevents variables declared with set() from unnecessarily escaping and
|
# This prevents variables declared with set() from unnecessarily escaping and
|
||||||
# should not be called more than once
|
# should not be called more than once
|
||||||
@@ -41,30 +38,20 @@ function(competition_scope_)
|
|||||||
int main() {}
|
int main() {}
|
||||||
]] SIMDJSON_FOUND_STRING_VIEW)
|
]] SIMDJSON_FOUND_STRING_VIEW)
|
||||||
if(SIMDJSON_FOUND_STRING_VIEW AND SIMDJSON_USE_BOOST_JSON)
|
if(SIMDJSON_FOUND_STRING_VIEW AND SIMDJSON_USE_BOOST_JSON)
|
||||||
CPMAddPackage(
|
import_dependency(boostjson boostorg/json ee8d72d)
|
||||||
NAME boostjson
|
|
||||||
URL https://github.com/boostorg/json/archive/ee8d72d8502b409b5561200299cad30ccdb91415.zip
|
|
||||||
)
|
|
||||||
add_library(boostjson STATIC "${boostjson_SOURCE_DIR}/src/src.cpp")
|
add_library(boostjson STATIC "${boostjson_SOURCE_DIR}/src/src.cpp")
|
||||||
target_compile_definitions(boostjson PUBLIC BOOST_JSON_STANDALONE)
|
target_compile_definitions(boostjson PUBLIC BOOST_JSON_STANDALONE)
|
||||||
target_include_directories(boostjson SYSTEM PUBLIC
|
target_include_directories(boostjson SYSTEM PUBLIC
|
||||||
"${boostjson_SOURCE_DIR}/include")
|
"${boostjson_SOURCE_DIR}/include")
|
||||||
target_compile_definitions(boostjson INTERFACE SIMDJSON_COMPETITION_BOOSTJSON)
|
target_compile_definitions(boostjson INTERFACE SIMDJSON_COMPETITION_BOOSTJSON)
|
||||||
endif()
|
endif()
|
||||||
CPMAddPackage(
|
|
||||||
NAME cjson
|
import_dependency(cjson DaveGamble/cJSON c69134d)
|
||||||
URL https://github.com/DaveGamble/cJSON/archive/c69134d01746dcf551dd7724b4edb12f922eb0d1.zip
|
|
||||||
DOWNLOAD_ONLY YES
|
|
||||||
)
|
|
||||||
add_library(cjson STATIC "${cjson_SOURCE_DIR}/cJSON.c")
|
add_library(cjson STATIC "${cjson_SOURCE_DIR}/cJSON.c")
|
||||||
target_include_directories(cjson SYSTEM PUBLIC "${cjson_SOURCE_DIR}")
|
target_include_directories(cjson SYSTEM PUBLIC "${cjson_SOURCE_DIR}")
|
||||||
target_compile_definitions(cjson INTERFACE SIMDJSON_COMPETITION_CJSON)
|
target_compile_definitions(cjson INTERFACE SIMDJSON_COMPETITION_CJSON)
|
||||||
|
|
||||||
CPMAddPackage(
|
import_dependency(fastjson mikeando/fastjson 485f994)
|
||||||
NAME fastjson
|
|
||||||
URL https://github.com/mikeando/fastjson/archive/485f994a61a64ac73fa6a40d4d639b99b463563b.zip
|
|
||||||
DOWNLOAD_ONLY YES
|
|
||||||
)
|
|
||||||
add_library(fastjson STATIC
|
add_library(fastjson STATIC
|
||||||
"${fastjson_SOURCE_DIR}/src/fastjson.cpp"
|
"${fastjson_SOURCE_DIR}/src/fastjson.cpp"
|
||||||
"${fastjson_SOURCE_DIR}/src/fastjson2.cpp"
|
"${fastjson_SOURCE_DIR}/src/fastjson2.cpp"
|
||||||
@@ -73,36 +60,28 @@ int main() {}
|
|||||||
"${fastjson_SOURCE_DIR}/include")
|
"${fastjson_SOURCE_DIR}/include")
|
||||||
target_compile_definitions(fastjson INTERFACE SIMDJSON_COMPETITION_FASTJSON)
|
target_compile_definitions(fastjson INTERFACE SIMDJSON_COMPETITION_FASTJSON)
|
||||||
|
|
||||||
CPMAddPackage(
|
import_dependency(gason vivkin/gason 7aee524)
|
||||||
NAME gason
|
|
||||||
URL https://github.com/vivkin/gason/archive/7aee524189da1c1ecd19f67981e3d903dae25470.zip
|
|
||||||
DOWNLOAD_ONLY YES
|
|
||||||
)
|
|
||||||
add_library(gason STATIC "${gason_SOURCE_DIR}/src/gason.cpp")
|
add_library(gason STATIC "${gason_SOURCE_DIR}/src/gason.cpp")
|
||||||
target_include_directories(gason SYSTEM PUBLIC "${gason_SOURCE_DIR}/src")
|
target_include_directories(gason SYSTEM PUBLIC "${gason_SOURCE_DIR}/src")
|
||||||
target_compile_definitions(gason INTERFACE SIMDJSON_COMPETITION_GASON)
|
target_compile_definitions(gason INTERFACE SIMDJSON_COMPETITION_GASON)
|
||||||
|
|
||||||
CPMAddPackage(
|
import_dependency(jsmn zserge/jsmn 18e9fe4)
|
||||||
NAME jsmn
|
|
||||||
URL https://github.com/zserge/jsmn/archive/18e9fe42cbfe21d65076f5c77ae2be379ad1270f.zip
|
|
||||||
DOWNLOAD_ONLY YES
|
|
||||||
)
|
|
||||||
add_library(jsmn STATIC "${jsmn_SOURCE_DIR}/jsmn.c")
|
add_library(jsmn STATIC "${jsmn_SOURCE_DIR}/jsmn.c")
|
||||||
target_include_directories(jsmn SYSTEM PUBLIC "${jsmn_SOURCE_DIR}")
|
target_include_directories(jsmn SYSTEM PUBLIC "${jsmn_SOURCE_DIR}")
|
||||||
target_compile_definitions(jsmn INTERFACE SIMDJSON_COMPETITION_JSMN)
|
target_compile_definitions(jsmn INTERFACE SIMDJSON_COMPETITION_JSMN)
|
||||||
|
|
||||||
CPMAddPackage(
|
message(STATUS "Importing json (nlohmann/json@v3.10.5)")
|
||||||
NAME nlohmann_json
|
set(nlohmann_json_SOURCE_DIR "${dep_root}/json")
|
||||||
URL https://github.com/nlohmann/json/archive/refs/tags/v3.10.5.zip
|
if(NOT EXISTS "${nlohmann_json_SOURCE_DIR}")
|
||||||
)
|
file(DOWNLOAD
|
||||||
|
"https://github.com/nlohmann/json/releases/download/v3.10.5/json.hpp"
|
||||||
|
"${nlohmann_json_SOURCE_DIR}/nlohmann/json.hpp")
|
||||||
|
endif()
|
||||||
|
add_library(nlohmann_json INTERFACE)
|
||||||
|
target_include_directories(nlohmann_json SYSTEM INTERFACE "${nlohmann_json_SOURCE_DIR}")
|
||||||
|
target_compile_definitions(nlohmann_json INTERFACE SIMDJSON_COMPETITION_NLOHMANN_JSON)
|
||||||
|
|
||||||
set_property(TARGET nlohmann_json APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS SIMDJSON_COMPETITION_NLOHMANN_JSON)
|
import_dependency(json11 dropbox/json11 ec4e452)
|
||||||
|
|
||||||
CPMAddPackage(
|
|
||||||
NAME json11
|
|
||||||
URL https://github.com/dropbox/json11/archive/ec4e45219af1d7cde3d58b49ed762376fccf1ace.zip
|
|
||||||
DOWNLOAD_ONLY YES
|
|
||||||
)
|
|
||||||
add_library(json11 STATIC "${json11_SOURCE_DIR}/json11.cpp")
|
add_library(json11 STATIC "${json11_SOURCE_DIR}/json11.cpp")
|
||||||
target_include_directories(json11 SYSTEM PUBLIC "${json11_SOURCE_DIR}")
|
target_include_directories(json11 SYSTEM PUBLIC "${json11_SOURCE_DIR}")
|
||||||
target_compile_definitions(json11 INTERFACE SIMDJSON_COMPETITION_JSON11)
|
target_compile_definitions(json11 INTERFACE SIMDJSON_COMPETITION_JSON11)
|
||||||
@@ -112,11 +91,7 @@ int main() {}
|
|||||||
target_include_directories(jsoncpp SYSTEM PUBLIC "${jsoncpp_SOURCE_DIR}")
|
target_include_directories(jsoncpp SYSTEM PUBLIC "${jsoncpp_SOURCE_DIR}")
|
||||||
target_compile_definitions(jsoncpp INTERFACE SIMDJSON_COMPETITION_JSONCPP)
|
target_compile_definitions(jsoncpp INTERFACE SIMDJSON_COMPETITION_JSONCPP)
|
||||||
|
|
||||||
CPMAddPackage(
|
import_dependency(rapidjson Tencent/rapidjson f54b0e4)
|
||||||
NAME rapidjson
|
|
||||||
URL https://github.com/Tencent/rapidjson/archive/f54b0e47a08782a6131cc3d60f94d038fa6e0a51.zip
|
|
||||||
DOWNLOAD_ONLY YES
|
|
||||||
)
|
|
||||||
add_library(rapidjson INTERFACE)
|
add_library(rapidjson INTERFACE)
|
||||||
target_compile_definitions(rapidjson INTERFACE RAPIDJSON_HAS_STDSTRING)
|
target_compile_definitions(rapidjson INTERFACE RAPIDJSON_HAS_STDSTRING)
|
||||||
include (TestBigEndian)
|
include (TestBigEndian)
|
||||||
@@ -135,22 +110,14 @@ int main() {}
|
|||||||
target_compile_definitions(rapidjson INTERFACE SIMDJSON_COMPETITION_RAPIDJSON)
|
target_compile_definitions(rapidjson INTERFACE SIMDJSON_COMPETITION_RAPIDJSON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
CPMAddPackage(
|
import_dependency(sajson chadaustin/sajson 2dcfd35)
|
||||||
NAME sajson
|
|
||||||
URL https://github.com/chadaustin/sajson/archive/2dcfd350586375f9910f74821d4f07d67ae455ba.zip
|
|
||||||
DOWNLOAD_ONLY YES
|
|
||||||
)
|
|
||||||
add_library(sajson INTERFACE)
|
add_library(sajson INTERFACE)
|
||||||
target_compile_definitions(sajson INTERFACE SAJSON_UNSORTED_OBJECT_KEYS)
|
target_compile_definitions(sajson INTERFACE SAJSON_UNSORTED_OBJECT_KEYS)
|
||||||
target_include_directories(sajson SYSTEM INTERFACE
|
target_include_directories(sajson SYSTEM INTERFACE
|
||||||
"${sajson_SOURCE_DIR}/include")
|
"${sajson_SOURCE_DIR}/include")
|
||||||
target_compile_definitions(sajson INTERFACE SIMDJSON_COMPETITION_SAJSON)
|
target_compile_definitions(sajson INTERFACE SIMDJSON_COMPETITION_SAJSON)
|
||||||
|
|
||||||
CPMAddPackage(
|
import_dependency(ujson4c esnme/ujson4c e14f3fd)
|
||||||
NAME ujson4c
|
|
||||||
URL https://github.com/esnme/ujson4c/archive/e14f3fd5207fe30d1bdea723f260609e69d1abfa.zip
|
|
||||||
DOWNLOAD_ONLY YES
|
|
||||||
)
|
|
||||||
add_library(ujson4c STATIC
|
add_library(ujson4c STATIC
|
||||||
"${ujson4c_SOURCE_DIR}/src/ujdecode.c"
|
"${ujson4c_SOURCE_DIR}/src/ujdecode.c"
|
||||||
"${ujson4c_SOURCE_DIR}/3rdparty/ultrajsondec.c")
|
"${ujson4c_SOURCE_DIR}/3rdparty/ultrajsondec.c")
|
||||||
@@ -159,11 +126,7 @@ int main() {}
|
|||||||
"${ujson4c_SOURCE_DIR}/3rdparty")
|
"${ujson4c_SOURCE_DIR}/3rdparty")
|
||||||
target_compile_definitions(ujson4c INTERFACE SIMDJSON_COMPETITION_UJSON4C)
|
target_compile_definitions(ujson4c INTERFACE SIMDJSON_COMPETITION_UJSON4C)
|
||||||
|
|
||||||
CPMAddPackage(
|
import_dependency(yyjson ibireme/yyjson c385651)
|
||||||
NAME yyjson
|
|
||||||
URL https://github.com/ibireme/yyjson/archive/c3856514de0a67d7b66939bf3ed491a2d6e61277.zip
|
|
||||||
DOWNLOAD_ONLY YES
|
|
||||||
)
|
|
||||||
add_library(yyjson STATIC "${yyjson_SOURCE_DIR}/src/yyjson.c")
|
add_library(yyjson STATIC "${yyjson_SOURCE_DIR}/src/yyjson.c")
|
||||||
target_include_directories(yyjson SYSTEM PUBLIC "${yyjson_SOURCE_DIR}/src")
|
target_include_directories(yyjson SYSTEM PUBLIC "${yyjson_SOURCE_DIR}/src")
|
||||||
target_compile_definitions(yyjson INTERFACE SIMDJSON_COMPETITION_YYJSON)
|
target_compile_definitions(yyjson INTERFACE SIMDJSON_COMPETITION_YYJSON)
|
||||||
@@ -188,12 +151,10 @@ cmake_dependent_option(SIMDJSON_CXXOPTS "Download cxxopts (necessary for tools)"
|
|||||||
SIMDJSON_ALLOW_DOWNLOADS OFF)
|
SIMDJSON_ALLOW_DOWNLOADS OFF)
|
||||||
|
|
||||||
if(SIMDJSON_CXXOPTS)
|
if(SIMDJSON_CXXOPTS)
|
||||||
CPMAddPackage(
|
set_off(CXXOPTS_BUILD_EXAMPLES)
|
||||||
NAME cxxopts
|
set_off(CXXOPTS_BUILD_TESTS)
|
||||||
URL https://github.com/jarro2783/cxxopts/archive/59656709c0c58fcd0ed18b38e02938dbe05284c5.zip
|
set_off(CXXOPTS_ENABLE_INSTALL)
|
||||||
OPTIONS
|
|
||||||
"CXXOPTS_BUILD_EXAMPLES OFF"
|
import_dependency(cxxopts jarro2783/cxxopts 5965670)
|
||||||
"CXXOPTS_BUILD_TESTS OFF"
|
add_dependency(cxxopts)
|
||||||
"CXXOPTS_ENABLE_INSTALL OFF"
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
Vendored
+48
@@ -0,0 +1,48 @@
|
|||||||
|
set(dep_root "${simdjson_SOURCE_DIR}/dependencies/.cache")
|
||||||
|
if(DEFINED ENV{simdjson_DEPENDENCY_CACHE_DIR})
|
||||||
|
set(dep_root "$ENV{simdjson_DEPENDENCY_CACHE_DIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
function(import_dependency NAME GITHUB_REPO COMMIT)
|
||||||
|
message(STATUS "Importing ${NAME} (${GITHUB_REPO}@${COMMIT})")
|
||||||
|
set(target "${dep_root}/${NAME}")
|
||||||
|
|
||||||
|
# If the folder exists in the cache, then we assume that everything is as
|
||||||
|
# should be and do nothing
|
||||||
|
if(EXISTS "${target}")
|
||||||
|
set("${NAME}_SOURCE_DIR" "${target}" PARENT_SCOPE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(zip_url "https://github.com/${GITHUB_REPO}/archive/${COMMIT}.zip")
|
||||||
|
set(archive "${dep_root}/archive.zip")
|
||||||
|
set(dest "${dep_root}/_extract")
|
||||||
|
|
||||||
|
file(DOWNLOAD "${zip_url}" "${archive}")
|
||||||
|
file(MAKE_DIRECTORY "${dest}")
|
||||||
|
execute_process(
|
||||||
|
WORKING_DIRECTORY "${dest}"
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E tar xf "${archive}")
|
||||||
|
file(REMOVE "${archive}")
|
||||||
|
|
||||||
|
# GitHub archives only ever have one folder component at the root, so this
|
||||||
|
# will always match that single folder
|
||||||
|
file(GLOB dir LIST_DIRECTORIES YES "${dest}/*")
|
||||||
|
|
||||||
|
file(RENAME "${dir}" "${target}")
|
||||||
|
|
||||||
|
set("${NAME}_SOURCE_DIR" "${target}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Delegates to the dependency
|
||||||
|
macro(add_dependency NAME)
|
||||||
|
if(NOT DEFINED "${NAME}_SOURCE_DIR")
|
||||||
|
message(FATAL_ERROR "Missing ${NAME}_SOURCE_DIR variable")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory("${${NAME}_SOURCE_DIR}" "${PROJECT_BINARY_DIR}/_deps/${NAME}" EXCLUDE_FROM_ALL)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
function(set_off NAME)
|
||||||
|
set("${NAME}" OFF CACHE INTERNAL "")
|
||||||
|
endfunction()
|
||||||
+9
-48
@@ -48,7 +48,7 @@ Requirements
|
|||||||
------------------
|
------------------
|
||||||
|
|
||||||
- A recent compiler (LLVM clang 6 or better, GNU GCC 7.4 or better, Xcode 11 or better) on a 64-bit (PPC, ARM or x64 Intel/AMD) POSIX systems such as macOS, freeBSD or Linux. We require that the compiler supports the C++11 standard or better.
|
- A recent compiler (LLVM clang 6 or better, GNU GCC 7.4 or better, Xcode 11 or better) on a 64-bit (PPC, ARM or x64 Intel/AMD) POSIX systems such as macOS, freeBSD or Linux. We require that the compiler supports the C++11 standard or better.
|
||||||
- Visual Studio 2017 or better under 64-bit Windows. Users should target a 64-bit build (x64 or ARM64) instead of a 32-bit build (x86). We support the LLVM clang compiler under Visual Studio (clang-cl) as well as as the regular Visual Studio compiler. For better release performance (both compile time and execution time), we recommend Visual Studio users adopt LLVM (clang-cl). We also support MinGW 64-bit under Windows.
|
- Visual Studio 2017 or better under 64-bit Windows. Users should target a 64-bit build (x64 or ARM64) instead of a 32-bit build (x86). We support the LLVM clang compiler under Visual Studio (clangcl) as well as as the regular Visual Studio compiler. We also support MinGW 64-bit under Windows.
|
||||||
|
|
||||||
|
|
||||||
Support for AVX-512 require a processor with AVX512-VBMI2 support (Ice Lake or better, AMD Zen 4 or better) under a 64-bit system and a recent compiler (LLVM clang 6 or better, GCC 8 or better, Visual Studio 2019 or better). You need a correspondingly recent assembler such as gas (2.30+) or nasm (2.14+): recent compilers usually come with recent assemblers. If you mix a recent compiler with an incompatible/old assembler (e.g., when using a recent compiler with an old Linux distribution), you may get errors at build time because the compiler produces instructions that the assembler does not recognize: you should update your assembler to match your compiler (e.g., upgrade binutils to version 2.30 or better under Linux) or use an older compiler matching the capabilities of your assembler.
|
Support for AVX-512 require a processor with AVX512-VBMI2 support (Ice Lake or better, AMD Zen 4 or better) under a 64-bit system and a recent compiler (LLVM clang 6 or better, GCC 8 or better, Visual Studio 2019 or better). You need a correspondingly recent assembler such as gas (2.30+) or nasm (2.14+): recent compilers usually come with recent assemblers. If you mix a recent compiler with an incompatible/old assembler (e.g., when using a recent compiler with an old Linux distribution), you may get errors at build time because the compiler produces instructions that the assembler does not recognize: you should update your assembler to match your compiler (e.g., upgrade binutils to version 2.30 or better under Linux) or use an older compiler matching the capabilities of your assembler.
|
||||||
@@ -209,25 +209,6 @@ std::string data = "my data";
|
|||||||
simdjson::padded_string my_padded_data(data); // copies to a padded buffer
|
simdjson::padded_string my_padded_data(data); // copies to a padded buffer
|
||||||
```
|
```
|
||||||
|
|
||||||
You can then parse the JSON data from the `simdjson::padded_string` instance:
|
|
||||||
|
|
||||||
|
|
||||||
```c++
|
|
||||||
ondemand::document doc = parser.iterate(my_padded_data);
|
|
||||||
```
|
|
||||||
|
|
||||||
Whenever you pass an `std::string` reference to `parser::iterate`,
|
|
||||||
the parser will access the bytes beyond the end of
|
|
||||||
the string but before the end of the allocated memory (`std::string::capacity()`).
|
|
||||||
If you are using a sanitizer that checks for reading uninitialized bytes or `std::string`'s
|
|
||||||
container-overflow checks, you may encounter sanitizer warnings.
|
|
||||||
You can safely ignore these warnings. Or you can call `simdjson::pad(std::string&)` to pad the
|
|
||||||
string with `SIMDJSON_PADDING` spaces: this function returns a `simdjson::padding_string_view` which can be be passed to the parser's iterator function:
|
|
||||||
|
|
||||||
```c++
|
|
||||||
std::string json = "[1]";
|
|
||||||
ondemand::document doc = parser.iterate(simdjson::pad(json));
|
|
||||||
```
|
|
||||||
|
|
||||||
We recommend against creating many `std::string` or many `std::padding_string` instances in your application to store your JSON data.
|
We recommend against creating many `std::string` or many `std::padding_string` instances in your application to store your JSON data.
|
||||||
Consider reusing the same buffers and limiting memory allocations.
|
Consider reusing the same buffers and limiting memory allocations.
|
||||||
@@ -268,7 +249,7 @@ documents.
|
|||||||
For code safety, you should keep (1) the `parser` instance, (2) the input string and (3) the document instance alive throughout your parsing. Additionally, you should follow the following rules:
|
For code safety, you should keep (1) the `parser` instance, (2) the input string and (3) the document instance alive throughout your parsing. Additionally, you should follow the following rules:
|
||||||
|
|
||||||
- A `parser` may have at most one document open at a time, since it holds allocated memory used for the parsing.
|
- A `parser` may have at most one document open at a time, since it holds allocated memory used for the parsing.
|
||||||
- By design, you should only have one `document` instance per JSON document. Thus, if you must pass a document instance to a function, you should avoid passing it by value: choose to pass it by reference instance to avoid the copy. In any case, the `document` class does not have a copy constructor.
|
- By design, you should only have one `document` instance per JSON document. Thus, if you must pass a document instance to a function, you should avoid passing it by value: choose to pass it by reference instance to avoid the copy. (We also provide a `document_reference` class if you need to pass by value.)
|
||||||
|
|
||||||
During the `iterate` call, the original JSON text is never modified--only read. After you are done
|
During the `iterate` call, the original JSON text is never modified--only read. After you are done
|
||||||
with the document, the source (whether file or string) can be safely discarded.
|
with the document, the source (whether file or string) can be safely discarded.
|
||||||
@@ -422,13 +403,9 @@ support for users who avoid exceptions. See [the simdjson error handling documen
|
|||||||
of the object: to warn you, an OUT_OF_ORDER_ITERATION error is generated [when development checks](#avoiding-pitfalls-enable-development-checks) are active. If you need to access an object more
|
of the object: to warn you, an OUT_OF_ORDER_ITERATION error is generated [when development checks](#avoiding-pitfalls-enable-development-checks) are active. If you need to access an object more
|
||||||
than once, you may call `reset()` on it although we discourage this practice. Keep in mind that
|
than once, you may call `reset()` on it although we discourage this practice. Keep in mind that
|
||||||
you should consume each value at most once.
|
you should consume each value at most once.
|
||||||
|
|
||||||
When you are iterating through an object, you are advancing through its keys and values. You should not also access the object or other objects. E.g. within a loop over `myobject`, you should not be accessing `myobject`. The following is an anti-pattern: `for(auto value: myobject) {myobject["mykey"]}`.
|
|
||||||
|
|
||||||
You should never reset an object as you are iterating through it. The following is an anti-pattern: `for(auto value: myobject) {myobject.reset()}`.
|
|
||||||
* **Array Index:** Because it is forward-only, you cannot look up an array element by index by index. Instead,
|
* **Array Index:** Because it is forward-only, you cannot look up an array element by index by index. Instead,
|
||||||
you should iterate through the array and keep an index yourself. Exceptionally, if need a single value
|
you should iterate through the array and keep an index yourself. Exceptionally, if need a single value
|
||||||
out of the array, you may use an array access (e.g., `array[1]`). You should never reset an array as you are iterating through it. The following is an anti-pattern: `for(auto value: myarray) {myarray.reset()}`.
|
out of the array, you may use an array access (e.g., `array[1]`).
|
||||||
* **Field Access:** To get the value of the "foo" field in an object, use `object["foo"]`. This will
|
* **Field Access:** To get the value of the "foo" field in an object, use `object["foo"]`. This will
|
||||||
scan through the object looking for the field with the matching string, doing a character-by-character
|
scan through the object looking for the field with the matching string, doing a character-by-character
|
||||||
comparison. It may generate the error `simdjson::NO_SUCH_FIELD` if there is no such key in the object, it may throw an exception (see [Error handling](#error-handling)). For efficiency reason, you should avoid looking up the same field repeatedly: e.g., do
|
comparison. It may generate the error `simdjson::NO_SUCH_FIELD` if there is no such key in the object, it may throw an exception (see [Error handling](#error-handling)). For efficiency reason, you should avoid looking up the same field repeatedly: e.g., do
|
||||||
@@ -561,7 +538,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
|
|||||||
For this purpose, `array` instances have a `count_elements` method. Users should be
|
For this purpose, `array` instances have a `count_elements` method. Users should be
|
||||||
aware that the `count_elements` method can be costly since it requires scanning the
|
aware that the `count_elements` method can be costly since it requires scanning the
|
||||||
whole array. You should only call `count_elements` as a last resort as it may
|
whole array. You should only call `count_elements` as a last resort as it may
|
||||||
require scanning the document twice or more. You should never use the `count_elements` as part of an attempt to iterate through the array: use a `for` loop to iterate through arrays. In the spirit of On-Demand, the `count_elements` function does not validate the values in the array: they are validated when they are consumed. You may use it as follows if your document is itself an array:
|
require scanning the document twice or more. You may use it as follows if your document is itself an array:
|
||||||
|
|
||||||
```C++
|
```C++
|
||||||
auto cars_json = R"( [ 40.1, 39.9, 37.7, 40.4 ] )"_padded;
|
auto cars_json = R"( [ 40.1, 39.9, 37.7, 40.4 ] )"_padded;
|
||||||
@@ -1451,11 +1428,9 @@ be represented as `value` instances. You can check that a document is a scalar w
|
|||||||
JSONPath
|
JSONPath
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The simdjson library supports a subset of [JSONPath](https://datatracker.ietf.org/doc/html/draft-normington-jsonpath-00) through the `at_path()` method, allowing you to reach further into the document in a single call. The subset of JSONPath that is implemented is the subset that is trivially convertible into the JSON Pointer format, using `.` to access a field and `[]` to access a specific index.
|
The simdjson library now supports a subset of [JSONPath](https://datatracker.ietf.org/doc/html/draft-normington-jsonpath-00) through the `at_path()` method, allowing you to reach further into the document in a single call. The subset of JSONPath that is implemented is the subset that is trivially convertible into the JSON Pointer format, using `.` to access a field and `[]` to access a specific index.
|
||||||
|
|
||||||
This implementation relies on `at_path()` converting its argument to JSON Pointer and then calling `at_pointer`, which makes use of
|
This implementation relies on `at_path()` converting its argument to JSON Pointer and then calling `at_pointer`, which makes use of [`rewind`](#rewind) to reset the parser at the beginning of the document. Hence, it invalidates all previously parsed values, objects and arrays: make sure to consume the values between each call to `at_path`.
|
||||||
[`rewind`](#rewind) to reset the parser at the beginning of the document. Hence, it invalidates all previously parsed values, objects
|
|
||||||
and arrays: make sure to consume the values between each call to `at_path`.
|
|
||||||
|
|
||||||
Consider the following example:
|
Consider the following example:
|
||||||
|
|
||||||
@@ -1496,18 +1471,6 @@ doc.at_path(".\\u00E9") == 123; // true
|
|||||||
doc.at_path((const char*)u8".\u00E9") // returns an error (NO_SUCH_FIELD)
|
doc.at_path((const char*)u8".\u00E9") // returns an error (NO_SUCH_FIELD)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
We also support the `$` prefix. When you start a JSONPath expression with $, you are indicating that the path starts from the root of the JSON document. E.g.,
|
|
||||||
|
|
||||||
```c++
|
|
||||||
auto json = R"( { "c" :{ "foo": { "a": [ 10, 20, 30 ] }}, "d": { "foo2": { "a": [ 10, 20, 30 ] }} , "e": 120 })"_padded;
|
|
||||||
ondemand::parser parser;
|
|
||||||
ondemand::document doc = parser.iterate(json);
|
|
||||||
ondemand::object obj = doc.get_object();
|
|
||||||
int64_t x = obj.at_path("$.c.foo.a[1]"); // 20
|
|
||||||
x = obj.at_path("$.d.foo2.a.2"); // 30
|
|
||||||
```
|
|
||||||
|
|
||||||
Error handling
|
Error handling
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
@@ -1629,7 +1592,7 @@ The following is a similar example where one wants to get the id of the first tw
|
|||||||
triggering exceptions. To do this, we use `["statuses"].at(0)["id"]`. We break that expression down:
|
triggering exceptions. To do this, we use `["statuses"].at(0)["id"]`. We break that expression down:
|
||||||
|
|
||||||
- Get the list of tweets (the `"statuses"` key of the document) using `["statuses"]`). The result is expected to be an array.
|
- Get the list of tweets (the `"statuses"` key of the document) using `["statuses"]`). The result is expected to be an array.
|
||||||
- Get the first tweet using `.at(0)`. The result is expected to be an object. Observe that the `at` method can only be called once on an array (it cannot be used for iteration).
|
- Get the first tweet using `.at(0)`. The result is expected to be an object.
|
||||||
- Get the id of the tweet using ["id"]. We expect the value to be a non-negative integer.
|
- Get the id of the tweet using ["id"]. We expect the value to be a non-negative integer.
|
||||||
|
|
||||||
Observe how we use the `at` method when querying an index into an array, and not the bracket operator.
|
Observe how we use the `at` method when querying an index into an array, and not the bracket operator.
|
||||||
@@ -1654,8 +1617,8 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
*Important remark*: The `at` method can only be called once on an array. It cannot be used
|
The `at` method can only be called once on an array. It cannot be used
|
||||||
to iterate through the values of an array. We deliberately forbid this usage to avoid performance antipatterns. If you need to iterate through the values of an array, you should use a `for` loop.
|
to iterate through the values of an array.
|
||||||
|
|
||||||
### Error handling examples without exceptions
|
### Error handling examples without exceptions
|
||||||
|
|
||||||
@@ -1974,7 +1937,6 @@ to the document `rewind()` method, except that it does not rewind the
|
|||||||
internal string buffer. Thus you should consume values only once
|
internal string buffer. Thus you should consume values only once
|
||||||
even if you can iterate through the array or object more than once.
|
even if you can iterate through the array or object more than once.
|
||||||
If you unescape a string within an array more than once, you have unsafe code.
|
If you unescape a string within an array more than once, you have unsafe code.
|
||||||
You must not call `reset()` on an object or an array as you are iterating through it.
|
|
||||||
|
|
||||||
|
|
||||||
Newline-Delimited JSON (ndjson) and JSON lines
|
Newline-Delimited JSON (ndjson) and JSON lines
|
||||||
@@ -2914,7 +2876,6 @@ Performance tips
|
|||||||
std::string_view year = data["year"];
|
std::string_view year = data["year"];
|
||||||
std::string_view rating = data["rating"];
|
std::string_view rating = data["rating"];
|
||||||
```
|
```
|
||||||
- You will get better performance if you seek the keys in the order in which they appear in the document. So if processing `{"a":1, "b":2, "c":3}`, do `value1 = data["a"]; value2 = data["b"]; value3 data["c"];` and not `value2 = data["b"]; value1 = data["a"]; value3 data["c"];`. Of course, it is not always possible to know for sure in which order the keys appear.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
-64
@@ -8,7 +8,6 @@ An overview of what you need to know to use simdjson, with examples.
|
|||||||
* [Using the Parsed JSON](#using-the-parsed-json)
|
* [Using the Parsed JSON](#using-the-parsed-json)
|
||||||
* [C++17 Support](#c17-support)
|
* [C++17 Support](#c17-support)
|
||||||
* [JSON Pointer](#json-pointer)
|
* [JSON Pointer](#json-pointer)
|
||||||
* [JSONPath](#jsonpath)
|
|
||||||
* [Error Handling](#error-handling)
|
* [Error Handling](#error-handling)
|
||||||
* [Error Handling Example](#error-handling-example)
|
* [Error Handling Example](#error-handling-example)
|
||||||
* [Exceptions](#exceptions)
|
* [Exceptions](#exceptions)
|
||||||
@@ -60,26 +59,6 @@ std::string data = "my data";
|
|||||||
simdjson::padded_string my_padded_data(data); // copies to a padded buffer
|
simdjson::padded_string my_padded_data(data); // copies to a padded buffer
|
||||||
```
|
```
|
||||||
|
|
||||||
You can then parse the JSON document from the `simdjson::padded_string` instance:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
simdjson::dom::parser parser;
|
|
||||||
simdjson::dom::element doc = parser.parse(my_padded_data);
|
|
||||||
```
|
|
||||||
|
|
||||||
Whenever you pass an `std::string` reference to `parser::parse`,
|
|
||||||
the parser will access the bytes beyond the end of
|
|
||||||
the string but before the end of the allocated memory (`std::string::capacity()`).
|
|
||||||
If you are using a sanitizer that checks for reading uninitialized bytes or `std::string`'s
|
|
||||||
container-overflow checks, you may encounter sanitizer warnings.
|
|
||||||
You can safely ignore these warnings. Or you can call `simdjson::pad(std::string&)` to pad the
|
|
||||||
string with `SIMDJSON_PADDING` spaces: this function returns a `simdjson::padding_string_view` which can be be passed to the parser's iterator function:
|
|
||||||
|
|
||||||
```c++
|
|
||||||
std::string json = "[1]";
|
|
||||||
dom::element doc = parser.parse(simdjson::pad(json));
|
|
||||||
```
|
|
||||||
|
|
||||||
The parsed document resulting from the `parser.load` and `parser.parse` calls depends on the `parser` instance. Thus the `parser` instance must remain in scope. Furthermore, you must have at most one parsed document in play per `parser` instance.
|
The parsed document resulting from the `parser.load` and `parser.parse` calls depends on the `parser` instance. Thus the `parser` instance must remain in scope. Furthermore, you must have at most one parsed document in play per `parser` instance.
|
||||||
You cannot copy a `parser` instance, you may only move it.
|
You cannot copy a `parser` instance, you may only move it.
|
||||||
|
|
||||||
@@ -278,49 +257,6 @@ for (dom::element car_element : cars) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
JSONPath
|
|
||||||
------------
|
|
||||||
|
|
||||||
|
|
||||||
The simdjson library supports a subset of [JSONPath](https://datatracker.ietf.org/doc/html/draft-normington-jsonpath-00) through the `at_path()` method, allowing you to reach further into the document in a single call. The subset of JSONPath that is implemented is the subset that is trivially convertible into the JSON Pointer format, using `.` to access a field and `[]` to access a specific index.
|
|
||||||
|
|
||||||
Consider the following example:
|
|
||||||
|
|
||||||
```c++
|
|
||||||
auto cars_json = R"( [
|
|
||||||
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
|
|
||||||
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
|
|
||||||
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
|
|
||||||
] )"_padded;
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element doc;
|
|
||||||
auto error = parser.parse(cars_json).get(doc);
|
|
||||||
if(error) { /*won't happen*/ }
|
|
||||||
double p;
|
|
||||||
error = doc.at_path("[0].tire_pressure[1]").get(p);
|
|
||||||
if(error) { /*won't happen*/ }
|
|
||||||
cout << p << endl; // Prints 39.9
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
We also support the `$` prefix. When you start a JSONPath expression with $, you are indicating that the path starts from the root of the JSON document. E.g.,
|
|
||||||
|
|
||||||
```c++
|
|
||||||
auto json = R"( { "c" :{ "foo": { "a": [ 10, 20, 30 ] }}, "d": { "foo2": { "a": [ 10, 20, 30 ] }} , "e": 120 })"_padded;
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element doc;
|
|
||||||
auto error = parser.parse(json).get(doc);
|
|
||||||
if(error) { /*won't happen*/ }
|
|
||||||
dom::object obj;
|
|
||||||
error = doc.get_object().get(obj);
|
|
||||||
if(error) { /*won't happen*/ }
|
|
||||||
int64_t x;
|
|
||||||
error = obj.at_path("$[3].foo.a[1]").get(x);
|
|
||||||
if(error) { /*won't happen*/ }
|
|
||||||
if(x != 20) { /*won't happen*/ }
|
|
||||||
x = obj.at_path("$.d.foo2.a.2");
|
|
||||||
if(error) { /*won't happen*/ }
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Error Handling
|
Error Handling
|
||||||
|
|||||||
+1
-6
@@ -103,12 +103,7 @@ remove almost entirely its cost and replaces it by the overhead of a thread, whi
|
|||||||
cheaper. Ain't that awesome!
|
cheaper. Ain't that awesome!
|
||||||
|
|
||||||
Thread support is only active if thread supported is detected in which case the macro
|
Thread support is only active if thread supported is detected in which case the macro
|
||||||
SIMDJSON_THREADS_ENABLED is set. You can also manually pass `SIMDJSON_THREADS_ENABLED=1` flag
|
SIMDJSON_THREADS_ENABLED is set. Otherwise the library runs in single-thread mode.
|
||||||
to the library. Otherwise the library runs in single-thread mode.
|
|
||||||
|
|
||||||
You should be consistent. If you link against the simdjson library built for multithreading
|
|
||||||
(i.e., with `SIMDJSON_THREADS_ENABLED`), then you should build your application with multithreading
|
|
||||||
system (setting `SIMDJSON_THREADS_ENABLED=1` and linking against a thread library).
|
|
||||||
|
|
||||||
A `document_stream` instance uses at most two threads: there is a main thread and a worker thread.
|
A `document_stream` instance uses at most two threads: there is a main thread and a worker thread.
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ or indexing (`object["key"]`). In some cases, the values are even deserialized d
|
|||||||
maps.
|
maps.
|
||||||
|
|
||||||
The DOM approach is conceptually simple and "programmer friendly". Using the
|
The DOM approach is conceptually simple and "programmer friendly". Using the
|
||||||
DOM tree is often easy enough that many users process the DOM as-is instead of creating
|
DOM tree is often easy enough that many users use the DOM as-is instead of creating
|
||||||
their own custom data structures.
|
their own custom data structures.
|
||||||
|
|
||||||
The DOM approach was the only way to parse JSON documents up to version 0.6 of the simdjson library.
|
The DOM approach was the only way to parse JSON documents up to version 0.6 of the simdjson library.
|
||||||
|
|||||||
+2
-7
@@ -103,12 +103,7 @@ cases, remove almost entirely its cost and replaces it by the overhead of a thre
|
|||||||
of magnitude cheaper. Ain't that awesome!
|
of magnitude cheaper. Ain't that awesome!
|
||||||
|
|
||||||
Thread support is only active if thread supported is detected in which case the macro
|
Thread support is only active if thread supported is detected in which case the macro
|
||||||
SIMDJSON_THREADS_ENABLED is set. You can also manually pass `SIMDJSON_THREADS_ENABLED=1` flag
|
SIMDJSON_THREADS_ENABLED is set. Otherwise the library runs in single-thread mode.
|
||||||
to the library. Otherwise the library runs in single-thread mode.
|
|
||||||
|
|
||||||
You should be consistent. If you link against the simdjson library built for multithreading
|
|
||||||
(i.e., with `SIMDJSON_THREADS_ENABLED`), then you should build your application with multithreading
|
|
||||||
system (setting `SIMDJSON_THREADS_ENABLED=1` and linking against a thread library).
|
|
||||||
|
|
||||||
A `document_stream` instance uses at most two threads: there is a main thread and a worker thread.
|
A `document_stream` instance uses at most two threads: there is a main thread and a worker thread.
|
||||||
You should expect the main thread to be fully occupied while the worker thread is partially busy
|
You should expect the main thread to be fully occupied while the worker thread is partially busy
|
||||||
@@ -130,7 +125,7 @@ Whitespace Characters:
|
|||||||
- **Nothing**
|
- **Nothing**
|
||||||
|
|
||||||
Some official formats **(non-exhaustive list)**:
|
Some official formats **(non-exhaustive list)**:
|
||||||
- [Newline-Delimited JSON (NDJSON)](https://github.com/ndjson/ndjson-spec)
|
- [Newline-Delimited JSON (NDJSON)](http://ndjson.org/)
|
||||||
- [JSON lines (JSONL)](http://jsonlines.org/)
|
- [JSON lines (JSONL)](http://jsonlines.org/)
|
||||||
- [Record separator-delimited JSON (RFC 7464)](https://tools.ietf.org/html/rfc7464) <- Not supported by JsonStream!
|
- [Record separator-delimited JSON (RFC 7464)](https://tools.ietf.org/html/rfc7464) <- Not supported by JsonStream!
|
||||||
- [More on Wikipedia...](https://en.wikipedia.org/wiki/JSON_streaming)
|
- [More on Wikipedia...](https://en.wikipedia.org/wiki/JSON_streaming)
|
||||||
|
|||||||
+3
-5
@@ -158,9 +158,7 @@ On Intel and AMD Windows platforms, Microsoft Visual Studio enables programmers
|
|||||||
|
|
||||||
When compiling with Visual Studio, we recommend the flags `/Ob2 /O2` or better. We do not recommend that you compile simdjson with architecture-specific flags such as `arch:AVX2`. The simdjson library automatically selects the best execution kernel at runtime.
|
When compiling with Visual Studio, we recommend the flags `/Ob2 /O2` or better. We do not recommend that you compile simdjson with architecture-specific flags such as `arch:AVX2`. The simdjson library automatically selects the best execution kernel at runtime.
|
||||||
|
|
||||||
Recent versions of Microsoft Visual Studio on Windows provides support for the LLVM Clang compiler. You only need to install the "Clang compiler" optional component (clang-cl). You may also get a copy of the 64-bit LLVM CLang compiler for [Windows directly from LLVM](https://releases.llvm.org/download.html). The simdjson library fully supports the LLVM Clang compiler under Windows. In fact, you may get better performance out of simdjson with the LLVM Clang compiler than with the regular Visual Studio compiler. Meanwhile the [LLVM CLang compiler is binary compatible with Visual Studio](https://clang.llvm.org/docs/MSVCCompatibility.html) which means that you can combine their binaries (executables and libraries).
|
Recent versions of Microsoft Visual Studio on Windows provides support for the LLVM Clang compiler. You only need to install the "Clang compiler" optional component (ClangCL). You may also get a copy of the 64-bit LLVM CLang compiler for [Windows directly from LLVM](https://releases.llvm.org/download.html). The simdjson library fully supports the LLVM Clang compiler under Windows. In fact, you may get better performance out of simdjson with the LLVM Clang compiler than with the regular Visual Studio compiler. Meanwhile the [LLVM CLang compiler is binary compatible with Visual Studio](https://clang.llvm.org/docs/MSVCCompatibility.html) which means that you can combine their binaries (executables and libraries).
|
||||||
|
|
||||||
We recommend Visual Studio users prefer LLVM (clang-cl). It compiles to faster release binaries. Furthermore, it compilers faster in release mode.
|
|
||||||
|
|
||||||
Under Windows, we also support the GNU GCC compiler via MSYS2. The performance of 64-bit MSYS2 under Windows is excellent (on par with Linux).
|
Under Windows, we also support the GNU GCC compiler via MSYS2. The performance of 64-bit MSYS2 under Windows is excellent (on par with Linux).
|
||||||
|
|
||||||
@@ -243,8 +241,8 @@ long page_size() {
|
|||||||
// Returns true if the buffer + len + simdjson::SIMDJSON_PADDING crosses the
|
// Returns true if the buffer + len + simdjson::SIMDJSON_PADDING crosses the
|
||||||
// page boundary.
|
// page boundary.
|
||||||
bool need_allocation(const char *buf, size_t len) {
|
bool need_allocation(const char *buf, size_t len) {
|
||||||
return ((reinterpret_cast<uintptr_t>(buf + len - 1) % page_size())
|
return ((reinterpret_cast<uintptr_t>(buf + len - 1) % page_size()) <
|
||||||
+ simdjson::SIMDJSON_PADDING > static_cast<uintptr_t>(page_size()));
|
simdjson::SIMDJSON_PADDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson::padded_string_view
|
simdjson::padded_string_view
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ SIMDJSON_NO_SANITIZE_UNDEFINED
|
|||||||
// See issue https://github.com/simdjson/simdjson/issues/1965
|
// See issue https://github.com/simdjson/simdjson/issues/1965
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
SIMDJSON_NO_SANITIZE_MEMORY
|
||||||
simdjson_inline int trailing_zeroes(uint64_t input_num) {
|
simdjson_inline int trailing_zeroes(uint64_t input_num) {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
// Search the mask data from least significant bit (LSB)
|
// Search the mask data from least significant bit (LSB)
|
||||||
// to the most significant bit (MSB) for a set bit (1).
|
// to the most significant bit (MSB) for a set bit (1).
|
||||||
@@ -35,15 +35,9 @@ simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
|||||||
return input_num & (input_num-1);
|
return input_num & (input_num-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We sometimes call leading_zeroes 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.
|
|
||||||
// Applies only when SIMDJSON_PREFER_REVERSE_BITS is defined and true.
|
|
||||||
// (See below.)
|
|
||||||
SIMDJSON_NO_SANITIZE_UNDEFINED
|
|
||||||
/* result might be undefined when input_num is zero */
|
/* result might be undefined when input_num is zero */
|
||||||
simdjson_inline int leading_zeroes(uint64_t input_num) {
|
simdjson_inline int leading_zeroes(uint64_t input_num) {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
unsigned long leading_zero = 0;
|
unsigned long leading_zero = 0;
|
||||||
// Search the mask data from most significant bit (MSB)
|
// Search the mask data from most significant bit (MSB)
|
||||||
// to least significant bit (LSB) for a set bit (1).
|
// to least significant bit (LSB) for a set bit (1).
|
||||||
@@ -96,7 +90,7 @@ simdjson_inline uint64_t zero_leading_bit(uint64_t rev_bits, int leading_zeroes)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) {
|
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
*result = value1 + value2;
|
*result = value1 + value2;
|
||||||
return *result < value1;
|
return *result < value1;
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -51,12 +51,6 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace arm64
|
} // namespace arm64
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_ARM64_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_ARM64_NUMBERPARSING_DEFS_H
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace arm64 {
|
|||||||
namespace {
|
namespace {
|
||||||
namespace simd {
|
namespace simd {
|
||||||
|
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
namespace {
|
namespace {
|
||||||
// Start of private section with Visual Studio workaround
|
// Start of private section with Visual Studio workaround
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ namespace {
|
|||||||
// We return uint32_t instead of uint16_t because that seems to be more efficient for most
|
// 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).
|
// purposes (cutting it down to uint16_t costs performance in some compilers).
|
||||||
simdjson_inline uint32_t to_bitmask() const {
|
simdjson_inline uint32_t to_bitmask() const {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
const uint8x16_t bit_mask = simdjson_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
|
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);
|
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80);
|
||||||
#else
|
#else
|
||||||
@@ -152,7 +152,7 @@ namespace {
|
|||||||
// Splat constructor
|
// Splat constructor
|
||||||
simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
|
simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
|
||||||
// Member-by-member initialization
|
// Member-by-member initialization
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
simdjson_inline simd8(
|
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 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 v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15
|
||||||
@@ -246,7 +246,7 @@ namespace {
|
|||||||
uint64x2_t shufmask64 = {thintable_epi8[mask1], thintable_epi8[mask2]};
|
uint64x2_t shufmask64 = {thintable_epi8[mask1], thintable_epi8[mask2]};
|
||||||
uint8x16_t shufmask = vreinterpretq_u8_u64(shufmask64);
|
uint8x16_t shufmask = vreinterpretq_u8_u64(shufmask64);
|
||||||
// we increment by 0x08 the second half of the mask
|
// we increment by 0x08 the second half of the mask
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#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);
|
uint8x16_t inc = simdjson_make_uint8x16_t(0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08);
|
||||||
#else
|
#else
|
||||||
uint8x16_t inc = {0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
|
uint8x16_t inc = {0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
|
||||||
@@ -276,7 +276,7 @@ namespace {
|
|||||||
uint8x8_t compactmask1 = vcreate_u8(thintable_epi8[mask1]);
|
uint8x8_t compactmask1 = vcreate_u8(thintable_epi8[mask1]);
|
||||||
uint8x8_t compactmask2 = vcreate_u8(thintable_epi8[mask2]);
|
uint8x8_t compactmask2 = vcreate_u8(thintable_epi8[mask2]);
|
||||||
// we increment by 0x08 the second half of the mask
|
// we increment by 0x08 the second half of the mask
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
uint8x8_t inc = simdjson_make_uint8x8_t(0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08);
|
uint8x8_t inc = simdjson_make_uint8x8_t(0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08);
|
||||||
#else
|
#else
|
||||||
uint8x8_t inc = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
|
uint8x8_t inc = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
|
||||||
@@ -328,7 +328,7 @@ namespace {
|
|||||||
// Array constructor
|
// Array constructor
|
||||||
simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {}
|
simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {}
|
||||||
// Member-by-member initialization
|
// Member-by-member initialization
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
simdjson_inline simd8(
|
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 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 v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15
|
||||||
@@ -449,7 +449,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
simdjson_inline uint64_t to_bitmask() const {
|
simdjson_inline uint64_t to_bitmask() const {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
const uint8x16_t bit_mask = simdjson_make_uint8x16_t(
|
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,
|
||||||
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80
|
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80
|
||||||
|
|||||||
@@ -50,8 +50,6 @@ double from_chars(const char *first, const char* end) noexcept;
|
|||||||
#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
|
#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
|
||||||
|
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
// We could use [[deprecated]] but it requires C++14
|
|
||||||
#define simdjson_deprecated __declspec(deprecated)
|
|
||||||
|
|
||||||
#define simdjson_really_inline __forceinline
|
#define simdjson_really_inline __forceinline
|
||||||
#define simdjson_never_inline __declspec(noinline)
|
#define simdjson_never_inline __declspec(noinline)
|
||||||
@@ -90,8 +88,6 @@ double from_chars(const char *first, const char* end) noexcept;
|
|||||||
#define SIMDJSON_POP_DISABLE_UNUSED_WARNINGS
|
#define SIMDJSON_POP_DISABLE_UNUSED_WARNINGS
|
||||||
|
|
||||||
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
|
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
// We could use [[deprecated]] but it requires C++14
|
|
||||||
#define simdjson_deprecated __attribute__((deprecated))
|
|
||||||
|
|
||||||
#define simdjson_really_inline inline __attribute__((always_inline))
|
#define simdjson_really_inline inline __attribute__((always_inline))
|
||||||
#define simdjson_never_inline inline __attribute__((noinline))
|
#define simdjson_never_inline inline __attribute__((noinline))
|
||||||
|
|||||||
@@ -56,22 +56,10 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__apple_build_version__)
|
#ifdef __cpp_concepts
|
||||||
#if __apple_build_version__ < 14000000
|
|
||||||
#define SIMDJSON_CONCEPT_DISABLED 1 // apple-clang/13 doesn't support std::convertible_to
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cpp_concepts) && !defined(SIMDJSON_CONCEPT_DISABLED)
|
|
||||||
#if __cpp_concepts >= 201907L
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#define SIMDJSON_SUPPORTS_DESERIALIZATION 1
|
#define SIMDJSON_SUPPORTS_DESERIALIZATION 1
|
||||||
#else
|
#else // __cpp_concepts
|
||||||
#define SIMDJSON_SUPPORTS_DESERIALIZATION 0
|
#define SIMDJSON_SUPPORTS_DESERIALIZATION 0
|
||||||
#endif
|
#endif
|
||||||
#else // defined(__cpp_concepts) && !defined(SIMDJSON_CONCEPT_DISABLED)
|
|
||||||
#define SIMDJSON_SUPPORTS_DESERIALIZATION 0
|
|
||||||
#endif // defined(__cpp_concepts) && !defined(SIMDJSON_CONCEPT_DISABLED)
|
|
||||||
|
|
||||||
#endif // SIMDJSON_COMPILER_CHECK_H
|
#endif // SIMDJSON_COMPILER_CHECK_H
|
||||||
|
|||||||
@@ -20,14 +20,14 @@ namespace details {
|
|||||||
}; \
|
}; \
|
||||||
};
|
};
|
||||||
|
|
||||||
SIMDJSON_IMPL_CONCEPT(emplace_back, emplace_back)
|
SIMDJSON_IMPL_CONCEPT(emplace_back, emplace_back);
|
||||||
SIMDJSON_IMPL_CONCEPT(emplace, emplace)
|
SIMDJSON_IMPL_CONCEPT(emplace, emplace);
|
||||||
SIMDJSON_IMPL_CONCEPT(push_back, push_back)
|
SIMDJSON_IMPL_CONCEPT(push_back, push_back);
|
||||||
SIMDJSON_IMPL_CONCEPT(add, add)
|
SIMDJSON_IMPL_CONCEPT(add, add);
|
||||||
SIMDJSON_IMPL_CONCEPT(push, push)
|
SIMDJSON_IMPL_CONCEPT(push, push);
|
||||||
SIMDJSON_IMPL_CONCEPT(append, append)
|
SIMDJSON_IMPL_CONCEPT(append, append);
|
||||||
SIMDJSON_IMPL_CONCEPT(insert, insert)
|
SIMDJSON_IMPL_CONCEPT(insert, insert);
|
||||||
SIMDJSON_IMPL_CONCEPT(op_append, operator+=)
|
SIMDJSON_IMPL_CONCEPT(op_append, operator+=);
|
||||||
|
|
||||||
#undef SIMDJSON_IMPL_CONCEPT
|
#undef SIMDJSON_IMPL_CONCEPT
|
||||||
} // namespace details
|
} // namespace details
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include "simdjson/dom/array.h"
|
#include "simdjson/dom/array.h"
|
||||||
#include "simdjson/dom/element.h"
|
#include "simdjson/dom/element.h"
|
||||||
#include "simdjson/error-inl.h"
|
#include "simdjson/error-inl.h"
|
||||||
#include "simdjson/jsonpathutil.h"
|
|
||||||
#include "simdjson/internal/tape_ref-inl.h"
|
#include "simdjson/internal/tape_ref-inl.h"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@@ -45,13 +44,6 @@ inline simdjson_result<dom::element> simdjson_result<dom::array>::at_pointer(std
|
|||||||
if (error()) { return error(); }
|
if (error()) { return error(); }
|
||||||
return first.at_pointer(json_pointer);
|
return first.at_pointer(json_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline simdjson_result<dom::element> simdjson_result<dom::array>::at_path(std::string_view json_path) const noexcept {
|
|
||||||
auto json_pointer = json_path_to_pointer_conversion(json_path);
|
|
||||||
if (json_pointer == "-1") { return INVALID_JSON_POINTER; }
|
|
||||||
return at_pointer(json_pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline simdjson_result<dom::element> simdjson_result<dom::array>::at(size_t index) const noexcept {
|
inline simdjson_result<dom::element> simdjson_result<dom::array>::at(size_t index) const noexcept {
|
||||||
if (error()) { return error(); }
|
if (error()) { return error(); }
|
||||||
return first.at(index);
|
return first.at(index);
|
||||||
@@ -121,12 +113,6 @@ inline simdjson_result<element> array::at_pointer(std::string_view json_pointer)
|
|||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline simdjson_result<element> array::at_path(std::string_view json_path) const noexcept {
|
|
||||||
auto json_pointer = json_path_to_pointer_conversion(json_path);
|
|
||||||
if (json_pointer == "-1") { return INVALID_JSON_POINTER; }
|
|
||||||
return at_pointer(json_pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline simdjson_result<element> array::at(size_t index) const noexcept {
|
inline simdjson_result<element> array::at(size_t index) const noexcept {
|
||||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||||
size_t i=0;
|
size_t i=0;
|
||||||
|
|||||||
@@ -108,21 +108,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline simdjson_result<element> at_pointer(std::string_view json_pointer) const noexcept;
|
inline simdjson_result<element> at_pointer(std::string_view json_pointer) const noexcept;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value associated with the given JSONPath expression. We only support
|
|
||||||
* JSONPath queries that trivially convertible to JSON Pointer queries: key
|
|
||||||
* names and array indices.
|
|
||||||
*
|
|
||||||
* https://datatracker.ietf.org/doc/html/draft-normington-jsonpath-00
|
|
||||||
*
|
|
||||||
* @return The value associated with the given JSONPath expression, or:
|
|
||||||
* - INVALID_JSON_POINTER if the JSONPath to JSON Pointer conversion fails
|
|
||||||
* - 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
|
|
||||||
*/
|
|
||||||
inline simdjson_result<element> at_path(std::string_view json_path) const noexcept;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value at the given index. This function has linear-time complexity and
|
* Get the value at the given index. This function has linear-time complexity and
|
||||||
* is equivalent to the following:
|
* is equivalent to the following:
|
||||||
@@ -167,7 +152,6 @@ public:
|
|||||||
simdjson_inline simdjson_result(error_code error) noexcept; ///< @private
|
simdjson_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||||
|
|
||||||
inline simdjson_result<dom::element> at_pointer(std::string_view json_pointer) const noexcept;
|
inline simdjson_result<dom::element> at_pointer(std::string_view json_pointer) const noexcept;
|
||||||
inline simdjson_result<dom::element> at_path(std::string_view json_path) const noexcept;
|
|
||||||
inline simdjson_result<dom::element> at(size_t index) const noexcept;
|
inline simdjson_result<dom::element> at(size_t index) const noexcept;
|
||||||
|
|
||||||
#if SIMDJSON_EXCEPTIONS
|
#if SIMDJSON_EXCEPTIONS
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include "simdjson/dom/object-inl.h"
|
#include "simdjson/dom/object-inl.h"
|
||||||
#include "simdjson/error-inl.h"
|
#include "simdjson/error-inl.h"
|
||||||
#include "simdjson/jsonpathutil.h"
|
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@@ -123,11 +122,6 @@ simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_
|
|||||||
if (error()) { return error(); }
|
if (error()) { return error(); }
|
||||||
return first.at_pointer(json_pointer);
|
return first.at_pointer(json_pointer);
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_path(const std::string_view json_path) const noexcept {
|
|
||||||
auto json_pointer = json_path_to_pointer_conversion(json_path);
|
|
||||||
if (json_pointer == "-1") { return INVALID_JSON_POINTER; }
|
|
||||||
return at_pointer(json_pointer);
|
|
||||||
}
|
|
||||||
#ifndef SIMDJSON_DISABLE_DEPRECATED_API
|
#ifndef SIMDJSON_DISABLE_DEPRECATED_API
|
||||||
[[deprecated("For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]]
|
[[deprecated("For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]]
|
||||||
simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at(const std::string_view json_pointer) const noexcept {
|
simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at(const std::string_view json_pointer) const noexcept {
|
||||||
@@ -418,11 +412,6 @@ inline simdjson_result<element> element::at_pointer(std::string_view json_pointe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline simdjson_result<element> element::at_path(std::string_view json_path) const noexcept {
|
|
||||||
auto json_pointer = json_path_to_pointer_conversion(json_path);
|
|
||||||
if (json_pointer == "-1") { return INVALID_JSON_POINTER; }
|
|
||||||
return at_pointer(json_pointer);
|
|
||||||
}
|
|
||||||
#ifndef SIMDJSON_DISABLE_DEPRECATED_API
|
#ifndef SIMDJSON_DISABLE_DEPRECATED_API
|
||||||
[[deprecated("For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]]
|
[[deprecated("For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]]
|
||||||
inline simdjson_result<element> element::at(std::string_view json_pointer) const noexcept {
|
inline simdjson_result<element> element::at(std::string_view json_pointer) const noexcept {
|
||||||
|
|||||||
@@ -372,8 +372,6 @@ public:
|
|||||||
* - INCORRECT_TYPE if this is not an object
|
* - INCORRECT_TYPE if this is not an object
|
||||||
*/
|
*/
|
||||||
inline simdjson_result<element> operator[](const char *key) const noexcept;
|
inline simdjson_result<element> operator[](const char *key) const noexcept;
|
||||||
simdjson_result<element> operator[](int) const noexcept = delete;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value associated with the given JSON pointer. We use the RFC 6901
|
* Get the value associated with the given JSON pointer. We use the RFC 6901
|
||||||
@@ -399,21 +397,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline simdjson_result<element> at_pointer(const std::string_view json_pointer) const noexcept;
|
inline simdjson_result<element> at_pointer(const std::string_view json_pointer) const noexcept;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value associated with the given JSONPath expression. We only support
|
|
||||||
* JSONPath queries that trivially convertible to JSON Pointer queries: key
|
|
||||||
* names and array indices.
|
|
||||||
*
|
|
||||||
* https://datatracker.ietf.org/doc/html/draft-normington-jsonpath-00
|
|
||||||
*
|
|
||||||
* @return The value associated with the given JSONPath expression, or:
|
|
||||||
* - INVALID_JSON_POINTER if the JSONPath to JSON Pointer conversion fails
|
|
||||||
* - 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
|
|
||||||
*/
|
|
||||||
inline simdjson_result<element> at_path(std::string_view json_path) const noexcept;
|
|
||||||
|
|
||||||
#ifndef SIMDJSON_DISABLE_DEPRECATED_API
|
#ifndef SIMDJSON_DISABLE_DEPRECATED_API
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -542,9 +525,7 @@ public:
|
|||||||
|
|
||||||
simdjson_inline simdjson_result<dom::element> operator[](std::string_view key) const noexcept;
|
simdjson_inline simdjson_result<dom::element> operator[](std::string_view key) const noexcept;
|
||||||
simdjson_inline simdjson_result<dom::element> operator[](const char *key) const noexcept;
|
simdjson_inline simdjson_result<dom::element> operator[](const char *key) const noexcept;
|
||||||
simdjson_result<dom::element> operator[](int) const noexcept = delete;
|
|
||||||
simdjson_inline simdjson_result<dom::element> at_pointer(const std::string_view json_pointer) const noexcept;
|
simdjson_inline simdjson_result<dom::element> at_pointer(const std::string_view json_pointer) const noexcept;
|
||||||
simdjson_inline simdjson_result<dom::element> at_path(const std::string_view json_path) const noexcept;
|
|
||||||
[[deprecated("For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]]
|
[[deprecated("For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]]
|
||||||
simdjson_inline simdjson_result<dom::element> at(const std::string_view json_pointer) const noexcept;
|
simdjson_inline simdjson_result<dom::element> at(const std::string_view json_pointer) const noexcept;
|
||||||
simdjson_inline simdjson_result<dom::element> at(size_t index) const noexcept;
|
simdjson_inline simdjson_result<dom::element> at(size_t index) const noexcept;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#include "simdjson/dom/element-inl.h"
|
#include "simdjson/dom/element-inl.h"
|
||||||
#include "simdjson/error-inl.h"
|
#include "simdjson/error-inl.h"
|
||||||
#include "simdjson/jsonpathutil.h"
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@@ -35,11 +34,6 @@ inline simdjson_result<dom::element> simdjson_result<dom::object>::at_pointer(st
|
|||||||
if (error()) { return error(); }
|
if (error()) { return error(); }
|
||||||
return first.at_pointer(json_pointer);
|
return first.at_pointer(json_pointer);
|
||||||
}
|
}
|
||||||
inline simdjson_result<dom::element> simdjson_result<dom::object>::at_path(std::string_view json_path) const noexcept {
|
|
||||||
auto json_pointer = json_path_to_pointer_conversion(json_path);
|
|
||||||
if (json_pointer == "-1") { return INVALID_JSON_POINTER; }
|
|
||||||
return at_pointer(json_pointer);
|
|
||||||
}
|
|
||||||
inline simdjson_result<dom::element> simdjson_result<dom::object>::at_key(std::string_view key) const noexcept {
|
inline simdjson_result<dom::element> simdjson_result<dom::object>::at_key(std::string_view key) const noexcept {
|
||||||
if (error()) { return error(); }
|
if (error()) { return error(); }
|
||||||
return first.at_key(key);
|
return first.at_key(key);
|
||||||
@@ -137,12 +131,6 @@ inline simdjson_result<element> object::at_pointer(std::string_view json_pointer
|
|||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline simdjson_result<element> object::at_path(std::string_view json_path) const noexcept {
|
|
||||||
auto json_pointer = json_path_to_pointer_conversion(json_path);
|
|
||||||
if (json_pointer == "-1") { return INVALID_JSON_POINTER; }
|
|
||||||
return at_pointer(json_pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline simdjson_result<element> object::at_key(std::string_view key) const noexcept {
|
inline simdjson_result<element> object::at_key(std::string_view key) const noexcept {
|
||||||
iterator end_field = end();
|
iterator end_field = end();
|
||||||
for (iterator field = begin(); field != end_field; ++field) {
|
for (iterator field = begin(); field != end_field; ++field) {
|
||||||
|
|||||||
@@ -145,7 +145,6 @@ public:
|
|||||||
* - INCORRECT_TYPE if this is not an object
|
* - INCORRECT_TYPE if this is not an object
|
||||||
*/
|
*/
|
||||||
inline simdjson_result<element> operator[](const char *key) const noexcept;
|
inline simdjson_result<element> operator[](const char *key) const noexcept;
|
||||||
simdjson_result<element> operator[](int) const noexcept = delete;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value associated with the given JSON pointer. We use the RFC 6901
|
* Get the value associated with the given JSON pointer. We use the RFC 6901
|
||||||
@@ -172,21 +171,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline simdjson_result<element> at_pointer(std::string_view json_pointer) const noexcept;
|
inline simdjson_result<element> at_pointer(std::string_view json_pointer) const noexcept;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value associated with the given JSONPath expression. We only support
|
|
||||||
* JSONPath queries that trivially convertible to JSON Pointer queries: key
|
|
||||||
* names and array indices.
|
|
||||||
*
|
|
||||||
* https://datatracker.ietf.org/doc/html/draft-normington-jsonpath-00
|
|
||||||
*
|
|
||||||
* @return The value associated with the given JSONPath expression, or:
|
|
||||||
* - INVALID_JSON_POINTER if the JSONPath to JSON Pointer conversion fails
|
|
||||||
* - 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
|
|
||||||
*/
|
|
||||||
inline simdjson_result<element> at_path(std::string_view json_path) const noexcept;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value associated with the given key.
|
* Get the value associated with the given key.
|
||||||
*
|
*
|
||||||
@@ -259,9 +243,7 @@ public:
|
|||||||
|
|
||||||
inline simdjson_result<dom::element> operator[](std::string_view key) const noexcept;
|
inline simdjson_result<dom::element> operator[](std::string_view key) const noexcept;
|
||||||
inline simdjson_result<dom::element> operator[](const char *key) const noexcept;
|
inline simdjson_result<dom::element> operator[](const char *key) const noexcept;
|
||||||
simdjson_result<dom::element> operator[](int) const noexcept = delete;
|
|
||||||
inline simdjson_result<dom::element> at_pointer(std::string_view json_pointer) const noexcept;
|
inline simdjson_result<dom::element> at_pointer(std::string_view json_pointer) const noexcept;
|
||||||
inline simdjson_result<dom::element> at_path(std::string_view json_path) const noexcept;
|
|
||||||
inline simdjson_result<dom::element> at_key(std::string_view key) const noexcept;
|
inline simdjson_result<dom::element> at_key(std::string_view key) const noexcept;
|
||||||
inline simdjson_result<dom::element> at_key_case_insensitive(std::string_view key) const noexcept;
|
inline simdjson_result<dom::element> at_key_case_insensitive(std::string_view key) const noexcept;
|
||||||
|
|
||||||
|
|||||||
@@ -202,22 +202,6 @@ public:
|
|||||||
* simdjson::dom::parser parser;
|
* simdjson::dom::parser parser;
|
||||||
* simdjson::dom::element element = parser.parse(padded_json_copy.get(), json_len, false);
|
* simdjson::dom::element element = parser.parse(padded_json_copy.get(), json_len, false);
|
||||||
*
|
*
|
||||||
* ### std::string references
|
|
||||||
*
|
|
||||||
* If you pass a mutable std::string reference (std::string&), the parser will seek to extend
|
|
||||||
* its capacity to SIMDJSON_PADDING bytes beyond the end of the string.
|
|
||||||
*
|
|
||||||
* Whenever you pass an std::string reference, the parser will access the bytes beyond the end of
|
|
||||||
* the string but before the end of the allocated memory (std::string::capacity()).
|
|
||||||
* If you are using a sanitizer that checks for reading uninitialized bytes or std::string's
|
|
||||||
* container-overflow checks, you may encounter sanitizer warnings.
|
|
||||||
* You can safely ignore these warnings. Or you can call simdjson::pad(std::string&) to pad the
|
|
||||||
* string with SIMDJSON_PADDING spaces: this function returns a simdjson::padding_string_view
|
|
||||||
* which can be be passed to the parser's parse function:
|
|
||||||
*
|
|
||||||
* std::string json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )";
|
|
||||||
* element doc = parser.parse(simdjson::pad(json));
|
|
||||||
*
|
|
||||||
* ### Parser Capacity
|
* ### Parser Capacity
|
||||||
*
|
*
|
||||||
* If the parser's current capacity is less than len, it will allocate enough capacity
|
* If the parser's current capacity is less than len, it will allocate enough capacity
|
||||||
@@ -565,14 +549,9 @@ public:
|
|||||||
/**
|
/**
|
||||||
* The parser instance can use threads when they are available to speed up some
|
* 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
|
* operations. It is enabled by default. Changing this attribute will change the
|
||||||
* behavior of the parser for future operations. Set to true by default.
|
* behavior of the parser for future operations.
|
||||||
*/
|
*/
|
||||||
bool threaded{true};
|
bool threaded{true};
|
||||||
#else
|
|
||||||
/**
|
|
||||||
* When SIMDJSON_THREADS_ENABLED is not defined, the parser instance cannot use threads.
|
|
||||||
*/
|
|
||||||
bool threaded{false};
|
|
||||||
#endif
|
#endif
|
||||||
/** @private Use the new DOM API instead */
|
/** @private Use the new DOM API instead */
|
||||||
class Iterator;
|
class Iterator;
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ struct simdjson_error : public std::exception {
|
|||||||
*/
|
*/
|
||||||
simdjson_error(error_code error) noexcept : _error{error} { }
|
simdjson_error(error_code error) noexcept : _error{error} { }
|
||||||
/** The error message */
|
/** The error message */
|
||||||
const char *what() const noexcept override { return error_message(error()); }
|
const char *what() const noexcept { return error_message(error()); }
|
||||||
/** The error code */
|
/** The error code */
|
||||||
error_code error() const noexcept { return _error; }
|
error_code error() const noexcept { return _error; }
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -75,12 +75,6 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace fallback
|
} // namespace fallback
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H
|
||||||
|
|||||||
@@ -574,6 +574,7 @@ simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(con
|
|||||||
// Our objective is accurate parsing (ULP of 0) at high speed.
|
// Our objective is accurate parsing (ULP of 0) at high speed.
|
||||||
template<typename W>
|
template<typename W>
|
||||||
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check for minus sign
|
// Check for minus sign
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
#define SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H
|
#define SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H
|
||||||
#include "simdjson/jsonpathutil.h"
|
|
||||||
#include "simdjson/generic/ondemand/base.h"
|
#include "simdjson/generic/ondemand/base.h"
|
||||||
#include "simdjson/generic/ondemand/array.h"
|
#include "simdjson/generic/ondemand/array.h"
|
||||||
#include "simdjson/generic/ondemand/array_iterator-inl.h"
|
#include "simdjson/generic/ondemand/array_iterator-inl.h"
|
||||||
@@ -164,6 +163,53 @@ inline simdjson_result<value> array::at_pointer(std::string_view json_pointer) n
|
|||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::string json_path_to_pointer_conversion(std::string_view json_path) {
|
||||||
|
if (json_path.empty() || (json_path.front() != '.' &&
|
||||||
|
json_path.front() != '[')) {
|
||||||
|
return "-1"; // This is just a sentinel value, the caller should check for this and return an error.
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
// Reserve space to reduce allocations, adjusting for potential increases due
|
||||||
|
// to escaping.
|
||||||
|
result.reserve(json_path.size() * 2);
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while (i < json_path.length()) {
|
||||||
|
if (json_path[i] == '.') {
|
||||||
|
result += '/';
|
||||||
|
} else if (json_path[i] == '[') {
|
||||||
|
result += '/';
|
||||||
|
++i; // Move past the '['
|
||||||
|
while (i < json_path.length() && json_path[i] != ']') {
|
||||||
|
if (json_path[i] == '~') {
|
||||||
|
result += "~0";
|
||||||
|
} else if (json_path[i] == '/') {
|
||||||
|
result += "~1";
|
||||||
|
} else {
|
||||||
|
result += json_path[i];
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
if (i == json_path.length() || json_path[i] != ']') {
|
||||||
|
return "-1"; // Using sentinel value that will be handled as an error by the caller.
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (json_path[i] == '~') {
|
||||||
|
result += "~0";
|
||||||
|
} else if (json_path[i] == '/') {
|
||||||
|
result += "~1";
|
||||||
|
} else {
|
||||||
|
result += json_path[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
inline simdjson_result<value> array::at_path(std::string_view json_path) noexcept {
|
inline simdjson_result<value> array::at_path(std::string_view json_path) noexcept {
|
||||||
auto json_pointer = json_path_to_pointer_conversion(json_path);
|
auto json_pointer = json_path_to_pointer_conversion(json_path);
|
||||||
if (json_pointer == "-1") { return INVALID_JSON_POINTER; }
|
if (json_pointer == "-1") { return INVALID_JSON_POINTER; }
|
||||||
|
|||||||
@@ -44,8 +44,7 @@ public:
|
|||||||
* calling this function, if successful, the array is 'rewinded' at its
|
* 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.,
|
* 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
|
* there is a missing comma), then an error is returned and it is no longer
|
||||||
* safe to continue. Note that count_elements() does not validate the JSON values,
|
* safe to continue.
|
||||||
* only the structure of the array.
|
|
||||||
*
|
*
|
||||||
* To check that an array is empty, it is more performant to use
|
* To check that an array is empty, it is more performant to use
|
||||||
* the is_empty() method.
|
* the is_empty() method.
|
||||||
|
|||||||
@@ -13,6 +13,5 @@
|
|||||||
#include "simdjson/padded_string.h"
|
#include "simdjson/padded_string.h"
|
||||||
#include "simdjson/padded_string_view.h"
|
#include "simdjson/padded_string_view.h"
|
||||||
#include "simdjson/internal/dom_parser_implementation.h"
|
#include "simdjson/internal/dom_parser_implementation.h"
|
||||||
#include "simdjson/jsonpathutil.h"
|
|
||||||
|
|
||||||
#endif // SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H
|
#endif // SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H
|
||||||
@@ -3,15 +3,17 @@
|
|||||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
#define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H
|
#define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H
|
||||||
#include "simdjson/generic/ondemand/base.h"
|
#include "simdjson/generic/ondemand/base.h"
|
||||||
|
#include "simdjson/generic/ondemand/array-inl.h"
|
||||||
#include "simdjson/generic/ondemand/array_iterator.h"
|
#include "simdjson/generic/ondemand/array_iterator.h"
|
||||||
#include "simdjson/generic/ondemand/document.h"
|
#include "simdjson/generic/ondemand/document.h"
|
||||||
|
#include "simdjson/generic/ondemand/json_iterator-inl.h"
|
||||||
|
#include "simdjson/generic/ondemand/json_path_to_pointer_conversion.h"
|
||||||
|
#include "simdjson/generic/ondemand/json_path_to_pointer_conversion-inl.h"
|
||||||
#include "simdjson/generic/ondemand/json_type.h"
|
#include "simdjson/generic/ondemand/json_type.h"
|
||||||
|
#include "simdjson/generic/ondemand/object-inl.h"
|
||||||
#include "simdjson/generic/ondemand/raw_json_string.h"
|
#include "simdjson/generic/ondemand/raw_json_string.h"
|
||||||
#include "simdjson/generic/ondemand/value.h"
|
#include "simdjson/generic/ondemand/value.h"
|
||||||
#include "simdjson/generic/ondemand/value-inl.h"
|
#include "simdjson/generic/ondemand/value-inl.h"
|
||||||
#include "simdjson/generic/ondemand/array-inl.h"
|
|
||||||
#include "simdjson/generic/ondemand/json_iterator-inl.h"
|
|
||||||
#include "simdjson/generic/ondemand/object-inl.h"
|
|
||||||
#include "simdjson/generic/ondemand/value_iterator-inl.h"
|
#include "simdjson/generic/ondemand/value_iterator-inl.h"
|
||||||
#include "simdjson/generic/ondemand/deserialize.h"
|
#include "simdjson/generic/ondemand/deserialize.h"
|
||||||
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
@@ -177,19 +179,10 @@ template<> simdjson_inline error_code document::get(int64_t& out) & noexcept { r
|
|||||||
template<> simdjson_inline error_code document::get(bool& out) & noexcept { return get_bool().get(out); }
|
template<> simdjson_inline error_code document::get(bool& out) & noexcept { return get_bool().get(out); }
|
||||||
template<> simdjson_inline error_code document::get(value& out) & noexcept { return get_value().get(out); }
|
template<> simdjson_inline error_code document::get(value& out) & noexcept { return get_value().get(out); }
|
||||||
|
|
||||||
template<> simdjson_deprecated simdjson_inline simdjson_result<raw_json_string> document::get() && noexcept { return get_raw_json_string(); }
|
|
||||||
template<> simdjson_deprecated simdjson_inline simdjson_result<std::string_view> document::get() && noexcept { return get_string(false); }
|
|
||||||
template<> simdjson_deprecated simdjson_inline simdjson_result<double> document::get() && noexcept { return std::forward<document>(*this).get_double(); }
|
|
||||||
template<> simdjson_deprecated simdjson_inline simdjson_result<uint64_t> document::get() && noexcept { return std::forward<document>(*this).get_uint64(); }
|
|
||||||
template<> simdjson_deprecated simdjson_inline simdjson_result<int64_t> document::get() && noexcept { return std::forward<document>(*this).get_int64(); }
|
|
||||||
template<> simdjson_deprecated simdjson_inline simdjson_result<bool> document::get() && noexcept { return std::forward<document>(*this).get_bool(); }
|
|
||||||
template<> simdjson_deprecated simdjson_inline simdjson_result<value> document::get() && noexcept { return get_value(); }
|
|
||||||
|
|
||||||
#if SIMDJSON_EXCEPTIONS
|
#if SIMDJSON_EXCEPTIONS
|
||||||
template <class T>
|
template <class T>
|
||||||
simdjson_deprecated simdjson_inline document::operator T() && noexcept(false) { return get<T>(); }
|
simdjson_inline document::operator T() noexcept(false) { return get<T>(); }
|
||||||
template <class T>
|
|
||||||
simdjson_inline document::operator T() & noexcept(false) { return get<T>(); }
|
|
||||||
simdjson_inline document::operator array() & noexcept(false) { return get_array(); }
|
simdjson_inline document::operator array() & noexcept(false) { return get_array(); }
|
||||||
simdjson_inline document::operator object() & noexcept(false) { return get_object(); }
|
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 uint64_t() noexcept(false) { return get_uint64(); }
|
||||||
@@ -246,14 +239,7 @@ simdjson_inline simdjson_result<value> document::operator[](const char *key) & n
|
|||||||
}
|
}
|
||||||
|
|
||||||
simdjson_inline error_code document::consume() noexcept {
|
simdjson_inline error_code document::consume() noexcept {
|
||||||
bool scalar = false;
|
auto error = iter.skip_child(0);
|
||||||
auto error = is_scalar().get(scalar);
|
|
||||||
if(error) { return error; }
|
|
||||||
if(scalar) {
|
|
||||||
iter.return_current_and_advance();
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
error = iter.skip_child(0);
|
|
||||||
if(error) { iter.abandon(); }
|
if(error) { iter.abandon(); }
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -275,8 +261,6 @@ simdjson_inline simdjson_result<json_type> document::type() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
simdjson_inline simdjson_result<bool> document::is_scalar() noexcept {
|
simdjson_inline simdjson_result<bool> document::is_scalar() noexcept {
|
||||||
// For more speed, we could do:
|
|
||||||
// return iter.is_single_token();
|
|
||||||
json_type this_type;
|
json_type this_type;
|
||||||
auto error = type().get(this_type);
|
auto error = type().get(this_type);
|
||||||
if(error) { return error; }
|
if(error) { return error; }
|
||||||
@@ -485,7 +469,7 @@ simdjson_inline simdjson_result<T> simdjson_result<SIMDJSON_IMPLEMENTATION::onde
|
|||||||
return first.get<T>();
|
return first.get<T>();
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
simdjson_deprecated simdjson_inline simdjson_result<T> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get() && noexcept {
|
simdjson_inline simdjson_result<T> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get() && noexcept {
|
||||||
if (error()) { return error(); }
|
if (error()) { return error(); }
|
||||||
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::document>(first).get<T>();
|
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::document>(first).get<T>();
|
||||||
}
|
}
|
||||||
@@ -501,7 +485,7 @@ simdjson_inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::do
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<> simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get<SIMDJSON_IMPLEMENTATION::ondemand::document>() & noexcept = delete;
|
template<> simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get<SIMDJSON_IMPLEMENTATION::ondemand::document>() & noexcept = delete;
|
||||||
template<> simdjson_deprecated simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get<SIMDJSON_IMPLEMENTATION::ondemand::document>() && noexcept {
|
template<> simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get<SIMDJSON_IMPLEMENTATION::ondemand::document>() && noexcept {
|
||||||
if (error()) { return error(); }
|
if (error()) { return error(); }
|
||||||
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::document>(first);
|
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::document>(first);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/** @overload template<typename T> error_code get(T &out) & noexcept */
|
/** @overload template<typename T> error_code get(T &out) & noexcept */
|
||||||
template<typename T> simdjson_deprecated simdjson_inline error_code get(T &out) && noexcept;
|
template<typename T> simdjson_inline error_code get(T &out) && noexcept;
|
||||||
|
|
||||||
#if SIMDJSON_EXCEPTIONS
|
#if SIMDJSON_EXCEPTIONS
|
||||||
/**
|
/**
|
||||||
@@ -267,10 +267,7 @@ public:
|
|||||||
* @returns An instance of type T
|
* @returns An instance of type T
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
explicit simdjson_inline operator T() & noexcept(false);
|
explicit simdjson_inline operator T() noexcept(false);
|
||||||
template <class T>
|
|
||||||
explicit simdjson_deprecated simdjson_inline operator T() && noexcept(false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast this JSON value to an array.
|
* Cast this JSON value to an array.
|
||||||
*
|
*
|
||||||
@@ -354,8 +351,7 @@ public:
|
|||||||
* calling this function, if successful, the array is 'rewinded' at its
|
* 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.,
|
* 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
|
* there is a missing comma), then an error is returned and it is no longer
|
||||||
* safe to continue. Note that count_elements() does not validate the JSON values,
|
* safe to continue.
|
||||||
* only the structure of the array.
|
|
||||||
*/
|
*/
|
||||||
simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
|
simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
|
||||||
/**
|
/**
|
||||||
@@ -467,7 +463,6 @@ public:
|
|||||||
simdjson_inline simdjson_result<value> operator[](std::string_view key) & noexcept;
|
simdjson_inline simdjson_result<value> operator[](std::string_view key) & noexcept;
|
||||||
/** @overload simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) & noexcept; */
|
/** @overload simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) & noexcept; */
|
||||||
simdjson_inline simdjson_result<value> operator[](const char *key) & noexcept;
|
simdjson_inline simdjson_result<value> operator[](const char *key) & noexcept;
|
||||||
simdjson_result<value> operator[](int) & noexcept = delete;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the type of this JSON value. It does not validate or consume the value.
|
* Get the type of this JSON value. It does not validate or consume the value.
|
||||||
@@ -736,11 +731,6 @@ protected:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A document_reference is a thin wrapper around a document reference instance.
|
* A document_reference is a thin wrapper around a document reference instance.
|
||||||
* The document_reference instances are used primarily/solely for streams of JSON
|
|
||||||
* documents. They differ from document instances when parsing a scalar value
|
|
||||||
* (a document that is not an array or an object). In the case of a document,
|
|
||||||
* we expect the document to be fully consumed. In the case of a document_reference,
|
|
||||||
* we allow trailing content.
|
|
||||||
*/
|
*/
|
||||||
class document_reference {
|
class document_reference {
|
||||||
public:
|
public:
|
||||||
@@ -854,7 +844,6 @@ public:
|
|||||||
simdjson_inline simdjson_result<value> find_field(const char *key) & noexcept;
|
simdjson_inline simdjson_result<value> find_field(const char *key) & noexcept;
|
||||||
simdjson_inline simdjson_result<value> operator[](std::string_view key) & noexcept;
|
simdjson_inline simdjson_result<value> operator[](std::string_view key) & noexcept;
|
||||||
simdjson_inline simdjson_result<value> operator[](const char *key) & noexcept;
|
simdjson_inline simdjson_result<value> operator[](const char *key) & noexcept;
|
||||||
simdjson_result<value> operator[](int) & noexcept = delete;
|
|
||||||
simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) & noexcept;
|
simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) & noexcept;
|
||||||
simdjson_inline simdjson_result<value> find_field_unordered(const char *key) & noexcept;
|
simdjson_inline simdjson_result<value> find_field_unordered(const char *key) & noexcept;
|
||||||
|
|
||||||
@@ -907,7 +896,7 @@ public:
|
|||||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||||
|
|
||||||
template<typename T> simdjson_inline simdjson_result<T> get() & noexcept;
|
template<typename T> simdjson_inline simdjson_result<T> get() & noexcept;
|
||||||
template<typename T> simdjson_deprecated simdjson_inline simdjson_result<T> get() && noexcept;
|
template<typename T> simdjson_inline simdjson_result<T> get() && noexcept;
|
||||||
|
|
||||||
template<typename T> simdjson_inline error_code get(T &out) & noexcept;
|
template<typename T> simdjson_inline error_code get(T &out) & noexcept;
|
||||||
template<typename T> simdjson_inline error_code get(T &out) && noexcept;
|
template<typename T> simdjson_inline error_code get(T &out) && noexcept;
|
||||||
@@ -933,7 +922,6 @@ public:
|
|||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field(const char *key) & noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field(const char *key) & noexcept;
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) & noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) & noexcept;
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](const char *key) & noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](const char *key) & noexcept;
|
||||||
simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](int) & noexcept = delete;
|
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) & noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) & noexcept;
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(const char *key) & noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(const char *key) & noexcept;
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::json_type> type() noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::json_type> type() noexcept;
|
||||||
@@ -1011,7 +999,6 @@ public:
|
|||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field(const char *key) & noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field(const char *key) & noexcept;
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) & noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) & noexcept;
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](const char *key) & noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](const char *key) & noexcept;
|
||||||
simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](int) & noexcept = delete;
|
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) & noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) & noexcept;
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(const char *key) & noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(const char *key) & noexcept;
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::json_type> type() noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::json_type> type() noexcept;
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ private:
|
|||||||
friend class document;
|
friend class document;
|
||||||
friend class json_iterator;
|
friend class json_iterator;
|
||||||
friend struct simdjson_result<ondemand::document_stream>;
|
friend struct simdjson_result<ondemand::document_stream>;
|
||||||
friend struct simdjson::internal::simdjson_result_base<ondemand::document_stream>;
|
friend struct internal::simdjson_result_base<ondemand::document_stream>;
|
||||||
}; // document_stream
|
}; // document_stream
|
||||||
|
|
||||||
} // namespace ondemand
|
} // namespace ondemand
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_ONDEMAND_GENERIC_JSON_PATH_TO_POINTER_CONVERSION_INL_H
|
||||||
|
#define SIMDJSON_ONDEMAND_GENERIC_JSON_PATH_TO_POINTER_CONVERSION_INL_H
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#define SIMDJSON_GENERIC_ONDEMAND_JSON_PATH_TO_POINTER_CONVERSION_INL_H
|
||||||
|
#include "simdjson/generic/ondemand/json_path_to_pointer_conversion.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
namespace simdjson {
|
||||||
|
namespace SIMDJSON_IMPLEMENTATION {}
|
||||||
|
namespace ondemand {
|
||||||
|
|
||||||
|
simdjson_inline std::string json_path_to_pointer_conversion(std::string_view json_path) {
|
||||||
|
if (json_path.empty() || (json_path.front() != '.' && json_path.front() != '[') {
|
||||||
|
return "-1"; // Sentinel value to be handled as an error by the caller.
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
// Reserve space to reduce allocations, adjusting for potential increases due
|
||||||
|
// to escaping.
|
||||||
|
result.reserve(json_path.size() * 2);
|
||||||
|
|
||||||
|
// Skip the initial '.' as it's assumed every path starts with it.
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while (i < json_path.length()) {
|
||||||
|
if (json_path[i] == '.') {
|
||||||
|
result += '/';
|
||||||
|
} else if (json_path[i] == '[') {
|
||||||
|
result += '/';
|
||||||
|
++i; // Move past the '['
|
||||||
|
while (i < json_path.length() && json_path[i] != ']') {
|
||||||
|
if (json_path[i] == '~') {
|
||||||
|
result += "~0";
|
||||||
|
} else if (json_path[i] == '/') {
|
||||||
|
result += "~1";
|
||||||
|
} else {
|
||||||
|
result += json_path[i];
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
if (i == json_path.length() || json_path[i] != ']') {
|
||||||
|
return "-1"; // Returning sentinel value that will be handled as an error by the caller
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (json_path[i] == '~') {
|
||||||
|
result += "~0";
|
||||||
|
} else if (json_path[i] == '/') {
|
||||||
|
result += "~1";
|
||||||
|
} else {
|
||||||
|
result += json_path[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return simdjson_result<std::string>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace ondemand
|
||||||
|
} // namespace SIMDJSON_IMPLEMENTATION
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
|
#endif // SIMDJSON_ONDEMAND_GENERIC_JSON_PATH_TO_POINTER_CONVERSION_INL_H
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_ONDEMAND_GENERIC_JSON_PATH_TO_POINTER_CONVERSION_H
|
||||||
|
#define SIMDJSON_ONDEMAND_GENERIC_JSON_PATH_TO_POINTER_CONVERSION_H
|
||||||
|
|
||||||
|
namespace simdjson {
|
||||||
|
namespace SIMDJSON_IMPLEMENTATION {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts JSONPath to JSON Pointer.
|
||||||
|
* @param json_path The JSONPath string to be converted.
|
||||||
|
* @return A string containing the equivalent JSON Pointer.
|
||||||
|
* @throws simdjson_error If the conversion fails.
|
||||||
|
*/
|
||||||
|
simdjson_inline std::string json_path_to_pointer_conversion(std::string_view json_path);
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace SIMDJSON_IMPLEMENTATION
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
|
#endif // SIMDJSON_JSON_PATH_TO_POINTER_CONVERSION_H
|
||||||
@@ -84,22 +84,6 @@ public:
|
|||||||
* using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the
|
* using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the
|
||||||
* SIMDJSON_PADDING bytes to avoid runtime warnings.
|
* SIMDJSON_PADDING bytes to avoid runtime warnings.
|
||||||
*
|
*
|
||||||
* ### std::string references
|
|
||||||
*
|
|
||||||
* If you pass a mutable std::string reference (std::string&), the parser will seek to extend
|
|
||||||
* its capacity to SIMDJSON_PADDING bytes beyond the end of the string.
|
|
||||||
*
|
|
||||||
* Whenever you pass an std::string reference, the parser will access the bytes beyond the end of
|
|
||||||
* the string but before the end of the allocated memory (std::string::capacity()).
|
|
||||||
* If you are using a sanitizer that checks for reading uninitialized bytes or std::string's
|
|
||||||
* container-overflow checks, you may encounter sanitizer warnings.
|
|
||||||
* You can safely ignore these warnings. Or you can call simdjson::pad(std::string&) to pad the
|
|
||||||
* string with SIMDJSON_PADDING spaces: this function returns a simdjson::padding_string_view
|
|
||||||
* which can be be passed to the parser's iterate function:
|
|
||||||
*
|
|
||||||
* std::string json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )";
|
|
||||||
* document doc = parser.iterate(simdjson::pad(json));
|
|
||||||
*
|
|
||||||
* @param json The JSON to parse.
|
* @param json The JSON to parse.
|
||||||
* @param len The length of the JSON.
|
* @param len The length of the JSON.
|
||||||
* @param capacity The number of bytes allocated in the JSON (must be at least len+SIMDJSON_PADDING).
|
* @param capacity The number of bytes allocated in the JSON (must be at least len+SIMDJSON_PADDING).
|
||||||
@@ -294,12 +278,8 @@ public:
|
|||||||
* behavior of the parser for future operations.
|
* behavior of the parser for future operations.
|
||||||
*/
|
*/
|
||||||
bool threaded{true};
|
bool threaded{true};
|
||||||
#else
|
|
||||||
/**
|
|
||||||
* When SIMDJSON_THREADS_ENABLED is not defined, the parser instance cannot use threads.
|
|
||||||
*/
|
|
||||||
bool threaded{false};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer.
|
* Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer.
|
||||||
* The result must be valid UTF-8.
|
* The result must be valid UTF-8.
|
||||||
@@ -360,7 +340,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
/** @private [for benchmarking access] The implementation to use */
|
/** @private [for benchmarking access] The implementation to use */
|
||||||
std::unique_ptr<simdjson::internal::dom_parser_implementation> implementation{};
|
std::unique_ptr<internal::dom_parser_implementation> implementation{};
|
||||||
size_t _capacity{0};
|
size_t _capacity{0};
|
||||||
size_t _max_capacity;
|
size_t _max_capacity;
|
||||||
size_t _max_depth{DEFAULT_MAX_DEPTH};
|
size_t _max_depth{DEFAULT_MAX_DEPTH};
|
||||||
|
|||||||
@@ -20,39 +20,36 @@ simdjson_inline const char * raw_json_string::raw() const noexcept { return rein
|
|||||||
|
|
||||||
simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(std::string_view target) noexcept {
|
simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(std::string_view target) noexcept {
|
||||||
size_t pos{0};
|
size_t pos{0};
|
||||||
while(pos < target.size()) {
|
// if the content has no escape character, just scan through it quickly!
|
||||||
pos = target.find('"', pos);
|
for(;pos < target.size() && target[pos] != '\\';pos++) {}
|
||||||
if(pos == std::string_view::npos) { return true; }
|
// slow path may begin.
|
||||||
if(pos != 0 && target[pos-1] != '\\') { return false; }
|
bool escaping{false};
|
||||||
if(pos > 1 && target[pos-2] == '\\') {
|
for(;pos < target.size();pos++) {
|
||||||
size_t backslash_count{2};
|
if((target[pos] == '"') && !escaping) {
|
||||||
for(size_t i = 3; i <= pos; i++) {
|
return false;
|
||||||
if(target[pos-i] == '\\') { backslash_count++; }
|
} else if(target[pos] == '\\') {
|
||||||
else { break; }
|
escaping = !escaping;
|
||||||
}
|
} else {
|
||||||
if(backslash_count % 2 == 0) { return false; }
|
escaping = false;
|
||||||
}
|
}
|
||||||
pos++;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(const char* target) noexcept {
|
simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(const char* target) noexcept {
|
||||||
size_t pos{0};
|
size_t pos{0};
|
||||||
while(target[pos]) {
|
// if the content has no escape character, just scan through it quickly!
|
||||||
const char * result = strchr(target+pos, '"');
|
for(;target[pos] && target[pos] != '\\';pos++) {}
|
||||||
if(result == nullptr) { return true; }
|
// slow path may begin.
|
||||||
pos = result - target;
|
bool escaping{false};
|
||||||
if(pos != 0 && target[pos-1] != '\\') { return false; }
|
for(;target[pos];pos++) {
|
||||||
if(pos > 1 && target[pos-2] == '\\') {
|
if((target[pos] == '"') && !escaping) {
|
||||||
size_t backslash_count{2};
|
return false;
|
||||||
for(size_t i = 3; i <= pos; i++) {
|
} else if(target[pos] == '\\') {
|
||||||
if(target[pos-i] == '\\') { backslash_count++; }
|
escaping = !escaping;
|
||||||
else { break; }
|
} else {
|
||||||
}
|
escaping = false;
|
||||||
if(backslash_count % 2 == 0) { return false; }
|
|
||||||
}
|
}
|
||||||
pos++;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -64,7 +61,7 @@ simdjson_inline bool raw_json_string::unsafe_is_equal(size_t length, std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
simdjson_inline bool raw_json_string::unsafe_is_equal(std::string_view target) const noexcept {
|
simdjson_inline bool raw_json_string::unsafe_is_equal(std::string_view target) const noexcept {
|
||||||
// Assumptions: does not contain unescaped quote characters("), and
|
// Assumptions: does not contain unescaped quote characters, and
|
||||||
// the raw content is quote terminated within a valid JSON string.
|
// the raw content is quote terminated within a valid JSON string.
|
||||||
if(target.size() <= SIMDJSON_PADDING) {
|
if(target.size() <= SIMDJSON_PADDING) {
|
||||||
return (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size());
|
return (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size());
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include "simdjson/generic/ondemand/array.h"
|
#include "simdjson/generic/ondemand/array.h"
|
||||||
#include "simdjson/generic/ondemand/array_iterator.h"
|
#include "simdjson/generic/ondemand/array_iterator.h"
|
||||||
#include "simdjson/generic/ondemand/json_iterator.h"
|
#include "simdjson/generic/ondemand/json_iterator.h"
|
||||||
|
#include "simdjson/generic/ondemand/json_path_to_pointer_conversion.h"
|
||||||
|
#include "simdjson/generic/ondemand/json_path_to_pointer_conversion-inl.h"
|
||||||
#include "simdjson/generic/ondemand/json_type.h"
|
#include "simdjson/generic/ondemand/json_type.h"
|
||||||
#include "simdjson/generic/ondemand/object.h"
|
#include "simdjson/generic/ondemand/object.h"
|
||||||
#include "simdjson/generic/ondemand/raw_json_string.h"
|
#include "simdjson/generic/ondemand/raw_json_string.h"
|
||||||
|
|||||||
@@ -163,17 +163,6 @@ public:
|
|||||||
* Important: a value should be consumed once. Calling get_string() twice on the same value
|
* Important: a value should be consumed once. Calling get_string() twice on the same value
|
||||||
* is an error.
|
* is an error.
|
||||||
*
|
*
|
||||||
* In some instances, you may want to allow replacement of invalid Unicode sequences.
|
|
||||||
* You may do so by passing the allow_replacement parameter as true. In the following
|
|
||||||
* example, the string "431924697b\udff0L\u0001Y" is not valid Unicode. By passing true
|
|
||||||
* to get_string, we allow the replacement of the invalid Unicode sequences with the Unicode
|
|
||||||
* replacement character (U+FFFD).
|
|
||||||
*
|
|
||||||
* simdjson::ondemand::parser parser;
|
|
||||||
* auto json = R"({"deviceId":"431924697b\udff0L\u0001Y"})"_padded;
|
|
||||||
* simdjson::ondemand::document doc = parser.iterate(json);
|
|
||||||
* auto view = doc["deviceId"].get_string(true);
|
|
||||||
*
|
|
||||||
* @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next
|
* @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.
|
* time it parses a document or when it is destroyed.
|
||||||
* @returns INCORRECT_TYPE if the JSON value is not a string.
|
* @returns INCORRECT_TYPE if the JSON value is not a string.
|
||||||
@@ -425,7 +414,6 @@ public:
|
|||||||
simdjson_inline simdjson_result<value> operator[](std::string_view key) noexcept;
|
simdjson_inline simdjson_result<value> operator[](std::string_view key) noexcept;
|
||||||
/** @overload simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) noexcept; */
|
/** @overload simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) noexcept; */
|
||||||
simdjson_inline simdjson_result<value> operator[](const char *key) noexcept;
|
simdjson_inline simdjson_result<value> operator[](const char *key) noexcept;
|
||||||
simdjson_result<value> operator[](int) noexcept = delete;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the type of this JSON value. It does not validate or consume the value.
|
* Get the type of this JSON value. It does not validate or consume the value.
|
||||||
@@ -793,7 +781,6 @@ public:
|
|||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) noexcept;
|
||||||
/** @overload simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) noexcept; */
|
/** @overload simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) noexcept; */
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](const char *key) noexcept;
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](const char *key) noexcept;
|
||||||
simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](int) noexcept = delete;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the type of this JSON value.
|
* Get the type of this JSON value.
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
#include "simdjson/generic/atomparsing.h"
|
#include "simdjson/generic/atomparsing.h"
|
||||||
#include "simdjson/generic/numberparsing.h"
|
#include "simdjson/generic/numberparsing.h"
|
||||||
#include "simdjson/generic/ondemand/json_iterator.h"
|
#include "simdjson/generic/ondemand/json_iterator.h"
|
||||||
#include "simdjson/generic/ondemand/value_iterator.h"
|
|
||||||
#include "simdjson/generic/ondemand/json_type-inl.h"
|
#include "simdjson/generic/ondemand/json_type-inl.h"
|
||||||
#include "simdjson/generic/ondemand/raw_json_string-inl.h"
|
#include "simdjson/generic/ondemand/raw_json_string-inl.h"
|
||||||
|
#include "simdjson/generic/ondemand/value_iterator.h"
|
||||||
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
@@ -799,8 +799,6 @@ simdjson_inline simdjson_result<bool> value_iterator::is_root_null(bool check_tr
|
|||||||
if(result) { // we have something that looks like a null.
|
if(result) { // we have something that looks like a null.
|
||||||
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
|
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
|
||||||
advance_root_scalar("null");
|
advance_root_scalar("null");
|
||||||
} else if (json[0] == 'n') {
|
|
||||||
return incorrect_type_error("Not a null but starts with n");
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,8 @@
|
|||||||
#include "simdjson/haswell/intrinsics.h"
|
#include "simdjson/haswell/intrinsics.h"
|
||||||
|
|
||||||
#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL
|
#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL
|
||||||
// We enable bmi2 only if LLVM/clang is used, because GCC may not
|
|
||||||
// make good use of it. See https://github.com/simdjson/simdjson/pull/2243
|
|
||||||
#if defined(__clang__)
|
|
||||||
SIMDJSON_TARGET_REGION("avx2,bmi,bmi2,pclmul,lzcnt,popcnt")
|
|
||||||
#else
|
|
||||||
SIMDJSON_TARGET_REGION("avx2,bmi,pclmul,lzcnt,popcnt")
|
SIMDJSON_TARGET_REGION("avx2,bmi,pclmul,lzcnt,popcnt")
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "simdjson/haswell/bitmanipulation.h"
|
#include "simdjson/haswell/bitmanipulation.h"
|
||||||
#include "simdjson/haswell/bitmask.h"
|
#include "simdjson/haswell/bitmask.h"
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
#ifndef SIMDJSON_JSONPATHUTIL_H
|
|
||||||
#define SIMDJSON_JSONPATHUTIL_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
namespace simdjson {
|
|
||||||
/**
|
|
||||||
* Converts JSONPath to JSON Pointer.
|
|
||||||
* @param json_path The JSONPath string to be converted.
|
|
||||||
* @return A string containing the equivalent JSON Pointer.
|
|
||||||
*/
|
|
||||||
inline std::string json_path_to_pointer_conversion(std::string_view json_path) {
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
// if JSONPath starts with $, skip it
|
|
||||||
if (!json_path.empty() && json_path.front() == '$') {
|
|
||||||
i = 1;
|
|
||||||
}
|
|
||||||
if (json_path.empty() || (json_path[i] != '.' &&
|
|
||||||
json_path[i] != '[')) {
|
|
||||||
return "-1"; // This is just a sentinel value, the caller should check for this and return an error.
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string result;
|
|
||||||
// Reserve space to reduce allocations, adjusting for potential increases due
|
|
||||||
// to escaping.
|
|
||||||
result.reserve(json_path.size() * 2);
|
|
||||||
|
|
||||||
while (i < json_path.length()) {
|
|
||||||
if (json_path[i] == '.') {
|
|
||||||
result += '/';
|
|
||||||
} else if (json_path[i] == '[') {
|
|
||||||
result += '/';
|
|
||||||
++i; // Move past the '['
|
|
||||||
while (i < json_path.length() && json_path[i] != ']') {
|
|
||||||
if (json_path[i] == '~') {
|
|
||||||
result += "~0";
|
|
||||||
} else if (json_path[i] == '/') {
|
|
||||||
result += "~1";
|
|
||||||
} else {
|
|
||||||
result += json_path[i];
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
if (i == json_path.length() || json_path[i] != ']') {
|
|
||||||
return "-1"; // Using sentinel value that will be handled as an error by the caller.
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (json_path[i] == '~') {
|
|
||||||
result += "~0";
|
|
||||||
} else if (json_path[i] == '/') {
|
|
||||||
result += "~1";
|
|
||||||
} else {
|
|
||||||
result += json_path[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
} // namespace simdjson
|
|
||||||
#endif // SIMDJSON_JSONPATHUTIL_H
|
|
||||||
@@ -36,12 +36,6 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace lasx
|
} // namespace lasx
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_LASX_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_LASX_NUMBERPARSING_DEFS_H
|
||||||
|
|||||||
@@ -36,12 +36,6 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace lsx
|
} // namespace lsx
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_LSX_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_LSX_NUMBERPARSING_DEFS_H
|
||||||
|
|||||||
@@ -53,9 +53,6 @@ inline padded_string::padded_string(const char *data, size_t length) noexcept
|
|||||||
if ((data != nullptr) && (data_ptr != nullptr)) {
|
if ((data != nullptr) && (data_ptr != nullptr)) {
|
||||||
std::memcpy(data_ptr, data, length);
|
std::memcpy(data_ptr, data, length);
|
||||||
}
|
}
|
||||||
if (data_ptr == nullptr) {
|
|
||||||
viable_size = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef __cpp_char8_t
|
#ifdef __cpp_char8_t
|
||||||
inline padded_string::padded_string(const char8_t *data, size_t length) noexcept
|
inline padded_string::padded_string(const char8_t *data, size_t length) noexcept
|
||||||
@@ -63,17 +60,12 @@ inline padded_string::padded_string(const char8_t *data, size_t length) noexcept
|
|||||||
if ((data != nullptr) && (data_ptr != nullptr)) {
|
if ((data != nullptr) && (data_ptr != nullptr)) {
|
||||||
std::memcpy(data_ptr, reinterpret_cast<const char *>(data), length);
|
std::memcpy(data_ptr, reinterpret_cast<const char *>(data), length);
|
||||||
}
|
}
|
||||||
if (data_ptr == nullptr) {
|
|
||||||
viable_size = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// note: do not pass std::string arguments by value
|
// note: do not pass std::string arguments by value
|
||||||
inline padded_string::padded_string(const std::string & str_ ) noexcept
|
inline padded_string::padded_string(const std::string & str_ ) noexcept
|
||||||
: viable_size(str_.size()), data_ptr(internal::allocate_padded_buffer(str_.size())) {
|
: viable_size(str_.size()), data_ptr(internal::allocate_padded_buffer(str_.size())) {
|
||||||
if (data_ptr == nullptr) {
|
if (data_ptr != nullptr) {
|
||||||
viable_size = 0;
|
|
||||||
} else {
|
|
||||||
std::memcpy(data_ptr, str_.data(), str_.size());
|
std::memcpy(data_ptr, str_.data(), str_.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,11 +179,11 @@ inline simdjson_result<padded_string> padded_string::load(std::string_view filen
|
|||||||
|
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
inline simdjson::padded_string operator ""_padded(const char *str, size_t len) {
|
inline simdjson::padded_string operator "" _padded(const char *str, size_t len) {
|
||||||
return simdjson::padded_string(str, len);
|
return simdjson::padded_string(str, len);
|
||||||
}
|
}
|
||||||
#ifdef __cpp_char8_t
|
#ifdef __cpp_char8_t
|
||||||
inline simdjson::padded_string operator ""_padded(const char8_t *str, size_t len) {
|
inline simdjson::padded_string operator "" _padded(const char8_t *str, size_t len) {
|
||||||
return simdjson::padded_string(reinterpret_cast<const char8_t *>(str), len);
|
return simdjson::padded_string(reinterpret_cast<const char8_t *>(str), len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -161,9 +161,9 @@ inline std::ostream& operator<<(std::ostream& out, simdjson_result<padded_string
|
|||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
// This is deliberately outside of simdjson so that people get it without having to use the namespace
|
// 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);
|
inline simdjson::padded_string operator "" _padded(const char *str, size_t len);
|
||||||
#ifdef __cpp_char8_t
|
#ifdef __cpp_char8_t
|
||||||
inline simdjson::padded_string operator ""_padded(const char8_t *str, size_t len);
|
inline simdjson::padded_string operator "" _padded(const char8_t *str, size_t len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
|
|||||||
@@ -53,11 +53,6 @@ inline bool padded_string_view::remove_utf8_bom() noexcept {
|
|||||||
inline std::ostream& operator<<(std::ostream& out, simdjson_result<padded_string_view> &s) noexcept(false) { return out << s.value(); }
|
inline std::ostream& operator<<(std::ostream& out, simdjson_result<padded_string_view> &s) noexcept(false) { return out << s.value(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline padded_string_view pad(std::string& s) noexcept {
|
|
||||||
const auto len = s.size();
|
|
||||||
s.append(SIMDJSON_PADDING, ' ');
|
|
||||||
return padded_string_view(s.data(), len, s.size());
|
|
||||||
}
|
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -83,15 +83,6 @@ public:
|
|||||||
inline std::ostream& operator<<(std::ostream& out, simdjson_result<padded_string_view> &s) noexcept(false);
|
inline std::ostream& operator<<(std::ostream& out, simdjson_result<padded_string_view> &s) noexcept(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a padded_string_view from a string. The string will be padded with SIMDJSON_PADDING
|
|
||||||
* space characters. The resulting padded_string_view will have a length equal to the original
|
|
||||||
* string.
|
|
||||||
*
|
|
||||||
* @param s The string.
|
|
||||||
* @return The padded string.
|
|
||||||
*/
|
|
||||||
inline padded_string_view pad(std::string& s) noexcept;
|
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_PADDED_STRING_VIEW_H
|
#endif // SIMDJSON_PADDED_STRING_VIEW_H
|
||||||
|
|||||||
@@ -6,15 +6,11 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <climits>
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
// strcasecmp, strncasecmp
|
// strcasecmp, strncasecmp
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static_assert(CHAR_BIT == 8, "simdjson requires 8-bit bytes");
|
|
||||||
|
|
||||||
|
|
||||||
// We are using size_t without namespace std:: throughout the project
|
// We are using size_t without namespace std:: throughout the project
|
||||||
using std::size_t;
|
using std::size_t;
|
||||||
|
|
||||||
@@ -48,7 +44,6 @@ using std::size_t;
|
|||||||
#elif defined(__loongarch_lp64)
|
#elif defined(__loongarch_lp64)
|
||||||
#define SIMDJSON_IS_LOONGARCH64 1
|
#define SIMDJSON_IS_LOONGARCH64 1
|
||||||
#elif defined(__PPC64__) || defined(_M_PPC64)
|
#elif defined(__PPC64__) || defined(_M_PPC64)
|
||||||
#define SIMDJSON_IS_PPC64 1
|
|
||||||
#if defined(__ALTIVEC__)
|
#if defined(__ALTIVEC__)
|
||||||
#define SIMDJSON_IS_PPC64_VMX 1
|
#define SIMDJSON_IS_PPC64_VMX 1
|
||||||
#endif // defined(__ALTIVEC__)
|
#endif // defined(__ALTIVEC__)
|
||||||
@@ -206,43 +201,4 @@ using std::size_t;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__
|
|
||||||
#define SIMDJSON_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
|
||||||
#elif defined _WIN32
|
|
||||||
#define SIMDJSON_IS_BIG_ENDIAN 0
|
|
||||||
#else
|
|
||||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
|
||||||
#include <machine/endian.h>
|
|
||||||
#elif defined(sun) || defined(__sun)
|
|
||||||
#include <sys/byteorder.h>
|
|
||||||
#elif defined(__MVS__)
|
|
||||||
#include <sys/endian.h>
|
|
||||||
#else
|
|
||||||
#ifdef __has_include
|
|
||||||
#if __has_include(<endian.h>)
|
|
||||||
#include <endian.h>
|
|
||||||
#endif //__has_include(<endian.h>)
|
|
||||||
#endif //__has_include
|
|
||||||
#endif
|
|
||||||
#
|
|
||||||
#ifndef __BYTE_ORDER__
|
|
||||||
// safe choice
|
|
||||||
#define SIMDJSON_IS_BIG_ENDIAN 0
|
|
||||||
#endif
|
|
||||||
#
|
|
||||||
#ifndef __ORDER_LITTLE_ENDIAN__
|
|
||||||
// safe choice
|
|
||||||
#define SIMDJSON_IS_BIG_ENDIAN 0
|
|
||||||
#endif
|
|
||||||
#
|
|
||||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
||||||
#define SIMDJSON_IS_BIG_ENDIAN 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_IS_BIG_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif // SIMDJSON_PORTABILITY_H
|
#endif // SIMDJSON_PORTABILITY_H
|
||||||
|
|||||||
@@ -60,12 +60,6 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace ppc64
|
} // namespace ppc64
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_PPC64_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_PPC64_NUMBERPARSING_DEFS_H
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||||
|
|
||||||
/** The version of simdjson being used (major.minor.revision) */
|
/** The version of simdjson being used (major.minor.revision) */
|
||||||
#define SIMDJSON_VERSION "3.11.6"
|
#define SIMDJSON_VERSION "3.10.0"
|
||||||
|
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
enum {
|
enum {
|
||||||
@@ -15,11 +15,11 @@ enum {
|
|||||||
/**
|
/**
|
||||||
* The minor version (major.MINOR.revision) of simdjson being used.
|
* The minor version (major.MINOR.revision) of simdjson being used.
|
||||||
*/
|
*/
|
||||||
SIMDJSON_VERSION_MINOR = 11,
|
SIMDJSON_VERSION_MINOR = 10,
|
||||||
/**
|
/**
|
||||||
* The revision (major.minor.REVISION) of simdjson being used.
|
* The revision (major.minor.REVISION) of simdjson being used.
|
||||||
*/
|
*/
|
||||||
SIMDJSON_VERSION_REVISION = 6
|
SIMDJSON_VERSION_REVISION = 0
|
||||||
};
|
};
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
|
|||||||
@@ -323,10 +323,6 @@ class Amalgamator:
|
|||||||
for line in fid2:
|
for line in fid2:
|
||||||
line = line.rstrip('\n')
|
line = line.rstrip('\n')
|
||||||
|
|
||||||
# Ignore #pragma once, it causes warnings if it ends up in a .cpp file
|
|
||||||
if re.search(r'^#pragma once$', line):
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Ignore lines inside #ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
# Ignore lines inside #ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
if re.search(r'^#ifndef\s+SIMDJSON_CONDITIONAL_INCLUDE\s*$', line):
|
if re.search(r'^#ifndef\s+SIMDJSON_CONDITIONAL_INCLUDE\s*$', line):
|
||||||
assert file.is_conditional_include, f"{file} uses #ifndef SIMDJSON_CONDITIONAL_INCLUDE but is not an amalgamated file!"
|
assert file.is_conditional_include, f"{file} uses #ifndef SIMDJSON_CONDITIONAL_INCLUDE but is not an amalgamated file!"
|
||||||
|
|||||||
+41
-184
@@ -1,4 +1,4 @@
|
|||||||
/* auto-generated on 2025-01-09 11:01:48 -0500. Do not edit! */
|
/* auto-generated on 2024-09-30 10:57:33 -0400. Do not edit! */
|
||||||
/* including simdjson.cpp: */
|
/* including simdjson.cpp: */
|
||||||
/* begin file simdjson.cpp */
|
/* begin file simdjson.cpp */
|
||||||
#define SIMDJSON_SRC_SIMDJSON_CPP
|
#define SIMDJSON_SRC_SIMDJSON_CPP
|
||||||
@@ -83,24 +83,12 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__apple_build_version__)
|
#ifdef __cpp_concepts
|
||||||
#if __apple_build_version__ < 14000000
|
|
||||||
#define SIMDJSON_CONCEPT_DISABLED 1 // apple-clang/13 doesn't support std::convertible_to
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cpp_concepts) && !defined(SIMDJSON_CONCEPT_DISABLED)
|
|
||||||
#if __cpp_concepts >= 201907L
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#define SIMDJSON_SUPPORTS_DESERIALIZATION 1
|
#define SIMDJSON_SUPPORTS_DESERIALIZATION 1
|
||||||
#else
|
#else // __cpp_concepts
|
||||||
#define SIMDJSON_SUPPORTS_DESERIALIZATION 0
|
#define SIMDJSON_SUPPORTS_DESERIALIZATION 0
|
||||||
#endif
|
#endif
|
||||||
#else // defined(__cpp_concepts) && !defined(SIMDJSON_CONCEPT_DISABLED)
|
|
||||||
#define SIMDJSON_SUPPORTS_DESERIALIZATION 0
|
|
||||||
#endif // defined(__cpp_concepts) && !defined(SIMDJSON_CONCEPT_DISABLED)
|
|
||||||
|
|
||||||
#endif // SIMDJSON_COMPILER_CHECK_H
|
#endif // SIMDJSON_COMPILER_CHECK_H
|
||||||
/* end file simdjson/compiler_check.h */
|
/* end file simdjson/compiler_check.h */
|
||||||
/* including simdjson/portability.h: #include "simdjson/portability.h" */
|
/* including simdjson/portability.h: #include "simdjson/portability.h" */
|
||||||
@@ -113,15 +101,11 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <climits>
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
// strcasecmp, strncasecmp
|
// strcasecmp, strncasecmp
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static_assert(CHAR_BIT == 8, "simdjson requires 8-bit bytes");
|
|
||||||
|
|
||||||
|
|
||||||
// We are using size_t without namespace std:: throughout the project
|
// We are using size_t without namespace std:: throughout the project
|
||||||
using std::size_t;
|
using std::size_t;
|
||||||
|
|
||||||
@@ -155,7 +139,6 @@ using std::size_t;
|
|||||||
#elif defined(__loongarch_lp64)
|
#elif defined(__loongarch_lp64)
|
||||||
#define SIMDJSON_IS_LOONGARCH64 1
|
#define SIMDJSON_IS_LOONGARCH64 1
|
||||||
#elif defined(__PPC64__) || defined(_M_PPC64)
|
#elif defined(__PPC64__) || defined(_M_PPC64)
|
||||||
#define SIMDJSON_IS_PPC64 1
|
|
||||||
#if defined(__ALTIVEC__)
|
#if defined(__ALTIVEC__)
|
||||||
#define SIMDJSON_IS_PPC64_VMX 1
|
#define SIMDJSON_IS_PPC64_VMX 1
|
||||||
#endif // defined(__ALTIVEC__)
|
#endif // defined(__ALTIVEC__)
|
||||||
@@ -313,45 +296,6 @@ using std::size_t;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__
|
|
||||||
#define SIMDJSON_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
|
||||||
#elif defined _WIN32
|
|
||||||
#define SIMDJSON_IS_BIG_ENDIAN 0
|
|
||||||
#else
|
|
||||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
|
||||||
#include <machine/endian.h>
|
|
||||||
#elif defined(sun) || defined(__sun)
|
|
||||||
#include <sys/byteorder.h>
|
|
||||||
#elif defined(__MVS__)
|
|
||||||
#include <sys/endian.h>
|
|
||||||
#else
|
|
||||||
#ifdef __has_include
|
|
||||||
#if __has_include(<endian.h>)
|
|
||||||
#include <endian.h>
|
|
||||||
#endif //__has_include(<endian.h>)
|
|
||||||
#endif //__has_include
|
|
||||||
#endif
|
|
||||||
#
|
|
||||||
#ifndef __BYTE_ORDER__
|
|
||||||
// safe choice
|
|
||||||
#define SIMDJSON_IS_BIG_ENDIAN 0
|
|
||||||
#endif
|
|
||||||
#
|
|
||||||
#ifndef __ORDER_LITTLE_ENDIAN__
|
|
||||||
// safe choice
|
|
||||||
#define SIMDJSON_IS_BIG_ENDIAN 0
|
|
||||||
#endif
|
|
||||||
#
|
|
||||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
||||||
#define SIMDJSON_IS_BIG_ENDIAN 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_IS_BIG_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif // SIMDJSON_PORTABILITY_H
|
#endif // SIMDJSON_PORTABILITY_H
|
||||||
/* end file simdjson/portability.h */
|
/* end file simdjson/portability.h */
|
||||||
|
|
||||||
@@ -400,8 +344,6 @@ double from_chars(const char *first, const char* end) noexcept;
|
|||||||
#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
|
#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
|
||||||
|
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
// We could use [[deprecated]] but it requires C++14
|
|
||||||
#define simdjson_deprecated __declspec(deprecated)
|
|
||||||
|
|
||||||
#define simdjson_really_inline __forceinline
|
#define simdjson_really_inline __forceinline
|
||||||
#define simdjson_never_inline __declspec(noinline)
|
#define simdjson_never_inline __declspec(noinline)
|
||||||
@@ -440,8 +382,6 @@ double from_chars(const char *first, const char* end) noexcept;
|
|||||||
#define SIMDJSON_POP_DISABLE_UNUSED_WARNINGS
|
#define SIMDJSON_POP_DISABLE_UNUSED_WARNINGS
|
||||||
|
|
||||||
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
|
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
// We could use [[deprecated]] but it requires C++14
|
|
||||||
#define simdjson_deprecated __attribute__((deprecated))
|
|
||||||
|
|
||||||
#define simdjson_really_inline inline __attribute__((always_inline))
|
#define simdjson_really_inline inline __attribute__((always_inline))
|
||||||
#define simdjson_never_inline inline __attribute__((noinline))
|
#define simdjson_never_inline inline __attribute__((noinline))
|
||||||
@@ -617,6 +557,7 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
|
|||||||
// Distributed under the Boost Software License, Version 1.0.
|
// 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)
|
// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#ifndef NONSTD_SV_LITE_H_INCLUDED
|
#ifndef NONSTD_SV_LITE_H_INCLUDED
|
||||||
#define NONSTD_SV_LITE_H_INCLUDED
|
#define NONSTD_SV_LITE_H_INCLUDED
|
||||||
@@ -2497,7 +2438,7 @@ struct simdjson_error : public std::exception {
|
|||||||
*/
|
*/
|
||||||
simdjson_error(error_code error) noexcept : _error{error} { }
|
simdjson_error(error_code error) noexcept : _error{error} { }
|
||||||
/** The error message */
|
/** The error message */
|
||||||
const char *what() const noexcept override { return error_message(error()); }
|
const char *what() const noexcept { return error_message(error()); }
|
||||||
/** The error code */
|
/** The error code */
|
||||||
error_code error() const noexcept { return _error; }
|
error_code error() const noexcept { return _error; }
|
||||||
private:
|
private:
|
||||||
@@ -2753,14 +2694,14 @@ namespace details {
|
|||||||
}; \
|
}; \
|
||||||
};
|
};
|
||||||
|
|
||||||
SIMDJSON_IMPL_CONCEPT(emplace_back, emplace_back)
|
SIMDJSON_IMPL_CONCEPT(emplace_back, emplace_back);
|
||||||
SIMDJSON_IMPL_CONCEPT(emplace, emplace)
|
SIMDJSON_IMPL_CONCEPT(emplace, emplace);
|
||||||
SIMDJSON_IMPL_CONCEPT(push_back, push_back)
|
SIMDJSON_IMPL_CONCEPT(push_back, push_back);
|
||||||
SIMDJSON_IMPL_CONCEPT(add, add)
|
SIMDJSON_IMPL_CONCEPT(add, add);
|
||||||
SIMDJSON_IMPL_CONCEPT(push, push)
|
SIMDJSON_IMPL_CONCEPT(push, push);
|
||||||
SIMDJSON_IMPL_CONCEPT(append, append)
|
SIMDJSON_IMPL_CONCEPT(append, append);
|
||||||
SIMDJSON_IMPL_CONCEPT(insert, insert)
|
SIMDJSON_IMPL_CONCEPT(insert, insert);
|
||||||
SIMDJSON_IMPL_CONCEPT(op_append, operator+=)
|
SIMDJSON_IMPL_CONCEPT(op_append, operator+=);
|
||||||
|
|
||||||
#undef SIMDJSON_IMPL_CONCEPT
|
#undef SIMDJSON_IMPL_CONCEPT
|
||||||
} // namespace details
|
} // namespace details
|
||||||
@@ -7805,7 +7746,7 @@ SIMDJSON_NO_SANITIZE_UNDEFINED
|
|||||||
// See issue https://github.com/simdjson/simdjson/issues/1965
|
// See issue https://github.com/simdjson/simdjson/issues/1965
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
SIMDJSON_NO_SANITIZE_MEMORY
|
||||||
simdjson_inline int trailing_zeroes(uint64_t input_num) {
|
simdjson_inline int trailing_zeroes(uint64_t input_num) {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
// Search the mask data from least significant bit (LSB)
|
// Search the mask data from least significant bit (LSB)
|
||||||
// to the most significant bit (MSB) for a set bit (1).
|
// to the most significant bit (MSB) for a set bit (1).
|
||||||
@@ -7821,15 +7762,9 @@ simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
|||||||
return input_num & (input_num-1);
|
return input_num & (input_num-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We sometimes call leading_zeroes 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.
|
|
||||||
// Applies only when SIMDJSON_PREFER_REVERSE_BITS is defined and true.
|
|
||||||
// (See below.)
|
|
||||||
SIMDJSON_NO_SANITIZE_UNDEFINED
|
|
||||||
/* result might be undefined when input_num is zero */
|
/* result might be undefined when input_num is zero */
|
||||||
simdjson_inline int leading_zeroes(uint64_t input_num) {
|
simdjson_inline int leading_zeroes(uint64_t input_num) {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
unsigned long leading_zero = 0;
|
unsigned long leading_zero = 0;
|
||||||
// Search the mask data from most significant bit (MSB)
|
// Search the mask data from most significant bit (MSB)
|
||||||
// to least significant bit (LSB) for a set bit (1).
|
// to least significant bit (LSB) for a set bit (1).
|
||||||
@@ -7882,7 +7817,7 @@ simdjson_inline uint64_t zero_leading_bit(uint64_t rev_bits, int leading_zeroes)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) {
|
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
*result = value1 + value2;
|
*result = value1 + value2;
|
||||||
return *result < value1;
|
return *result < value1;
|
||||||
#else
|
#else
|
||||||
@@ -7999,13 +7934,7 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace arm64
|
} // namespace arm64
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_ARM64_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_ARM64_NUMBERPARSING_DEFS_H
|
||||||
/* end file simdjson/arm64/numberparsing_defs.h */
|
/* end file simdjson/arm64/numberparsing_defs.h */
|
||||||
@@ -8025,7 +7954,7 @@ namespace arm64 {
|
|||||||
namespace {
|
namespace {
|
||||||
namespace simd {
|
namespace simd {
|
||||||
|
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
namespace {
|
namespace {
|
||||||
// Start of private section with Visual Studio workaround
|
// Start of private section with Visual Studio workaround
|
||||||
|
|
||||||
@@ -8134,7 +8063,7 @@ namespace {
|
|||||||
// We return uint32_t instead of uint16_t because that seems to be more efficient for most
|
// 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).
|
// purposes (cutting it down to uint16_t costs performance in some compilers).
|
||||||
simdjson_inline uint32_t to_bitmask() const {
|
simdjson_inline uint32_t to_bitmask() const {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
const uint8x16_t bit_mask = simdjson_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
|
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);
|
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80);
|
||||||
#else
|
#else
|
||||||
@@ -8165,7 +8094,7 @@ namespace {
|
|||||||
// Splat constructor
|
// Splat constructor
|
||||||
simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
|
simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
|
||||||
// Member-by-member initialization
|
// Member-by-member initialization
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
simdjson_inline simd8(
|
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 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 v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15
|
||||||
@@ -8259,7 +8188,7 @@ namespace {
|
|||||||
uint64x2_t shufmask64 = {thintable_epi8[mask1], thintable_epi8[mask2]};
|
uint64x2_t shufmask64 = {thintable_epi8[mask1], thintable_epi8[mask2]};
|
||||||
uint8x16_t shufmask = vreinterpretq_u8_u64(shufmask64);
|
uint8x16_t shufmask = vreinterpretq_u8_u64(shufmask64);
|
||||||
// we increment by 0x08 the second half of the mask
|
// we increment by 0x08 the second half of the mask
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#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);
|
uint8x16_t inc = simdjson_make_uint8x16_t(0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08);
|
||||||
#else
|
#else
|
||||||
uint8x16_t inc = {0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
|
uint8x16_t inc = {0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
|
||||||
@@ -8289,7 +8218,7 @@ namespace {
|
|||||||
uint8x8_t compactmask1 = vcreate_u8(thintable_epi8[mask1]);
|
uint8x8_t compactmask1 = vcreate_u8(thintable_epi8[mask1]);
|
||||||
uint8x8_t compactmask2 = vcreate_u8(thintable_epi8[mask2]);
|
uint8x8_t compactmask2 = vcreate_u8(thintable_epi8[mask2]);
|
||||||
// we increment by 0x08 the second half of the mask
|
// we increment by 0x08 the second half of the mask
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
uint8x8_t inc = simdjson_make_uint8x8_t(0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08);
|
uint8x8_t inc = simdjson_make_uint8x8_t(0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08);
|
||||||
#else
|
#else
|
||||||
uint8x8_t inc = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
|
uint8x8_t inc = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
|
||||||
@@ -8341,7 +8270,7 @@ namespace {
|
|||||||
// Array constructor
|
// Array constructor
|
||||||
simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {}
|
simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {}
|
||||||
// Member-by-member initialization
|
// Member-by-member initialization
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
simdjson_inline simd8(
|
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 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 v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15
|
||||||
@@ -8462,7 +8391,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
simdjson_inline uint64_t to_bitmask() const {
|
simdjson_inline uint64_t to_bitmask() const {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
const uint8x16_t bit_mask = simdjson_make_uint8x16_t(
|
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,
|
||||||
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80
|
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80
|
||||||
@@ -9622,6 +9551,7 @@ simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(con
|
|||||||
// Our objective is accurate parsing (ULP of 0) at high speed.
|
// Our objective is accurate parsing (ULP of 0) at high speed.
|
||||||
template<typename W>
|
template<typename W>
|
||||||
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check for minus sign
|
// Check for minus sign
|
||||||
//
|
//
|
||||||
@@ -10572,7 +10502,7 @@ SIMDJSON_NO_SANITIZE_UNDEFINED
|
|||||||
// See issue https://github.com/simdjson/simdjson/issues/1965
|
// See issue https://github.com/simdjson/simdjson/issues/1965
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
SIMDJSON_NO_SANITIZE_MEMORY
|
||||||
simdjson_inline int trailing_zeroes(uint64_t input_num) {
|
simdjson_inline int trailing_zeroes(uint64_t input_num) {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
// Search the mask data from least significant bit (LSB)
|
// Search the mask data from least significant bit (LSB)
|
||||||
// to the most significant bit (MSB) for a set bit (1).
|
// to the most significant bit (MSB) for a set bit (1).
|
||||||
@@ -10588,15 +10518,9 @@ simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
|||||||
return input_num & (input_num-1);
|
return input_num & (input_num-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We sometimes call leading_zeroes 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.
|
|
||||||
// Applies only when SIMDJSON_PREFER_REVERSE_BITS is defined and true.
|
|
||||||
// (See below.)
|
|
||||||
SIMDJSON_NO_SANITIZE_UNDEFINED
|
|
||||||
/* result might be undefined when input_num is zero */
|
/* result might be undefined when input_num is zero */
|
||||||
simdjson_inline int leading_zeroes(uint64_t input_num) {
|
simdjson_inline int leading_zeroes(uint64_t input_num) {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
unsigned long leading_zero = 0;
|
unsigned long leading_zero = 0;
|
||||||
// Search the mask data from most significant bit (MSB)
|
// Search the mask data from most significant bit (MSB)
|
||||||
// to least significant bit (LSB) for a set bit (1).
|
// to least significant bit (LSB) for a set bit (1).
|
||||||
@@ -10649,7 +10573,7 @@ simdjson_inline uint64_t zero_leading_bit(uint64_t rev_bits, int leading_zeroes)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) {
|
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
*result = value1 + value2;
|
*result = value1 + value2;
|
||||||
return *result < value1;
|
return *result < value1;
|
||||||
#else
|
#else
|
||||||
@@ -10766,13 +10690,7 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace arm64
|
} // namespace arm64
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_ARM64_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_ARM64_NUMBERPARSING_DEFS_H
|
||||||
/* end file simdjson/arm64/numberparsing_defs.h */
|
/* end file simdjson/arm64/numberparsing_defs.h */
|
||||||
@@ -10792,7 +10710,7 @@ namespace arm64 {
|
|||||||
namespace {
|
namespace {
|
||||||
namespace simd {
|
namespace simd {
|
||||||
|
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
namespace {
|
namespace {
|
||||||
// Start of private section with Visual Studio workaround
|
// Start of private section with Visual Studio workaround
|
||||||
|
|
||||||
@@ -10901,7 +10819,7 @@ namespace {
|
|||||||
// We return uint32_t instead of uint16_t because that seems to be more efficient for most
|
// 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).
|
// purposes (cutting it down to uint16_t costs performance in some compilers).
|
||||||
simdjson_inline uint32_t to_bitmask() const {
|
simdjson_inline uint32_t to_bitmask() const {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
const uint8x16_t bit_mask = simdjson_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
|
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);
|
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80);
|
||||||
#else
|
#else
|
||||||
@@ -10932,7 +10850,7 @@ namespace {
|
|||||||
// Splat constructor
|
// Splat constructor
|
||||||
simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
|
simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
|
||||||
// Member-by-member initialization
|
// Member-by-member initialization
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
simdjson_inline simd8(
|
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 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 v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15
|
||||||
@@ -11026,7 +10944,7 @@ namespace {
|
|||||||
uint64x2_t shufmask64 = {thintable_epi8[mask1], thintable_epi8[mask2]};
|
uint64x2_t shufmask64 = {thintable_epi8[mask1], thintable_epi8[mask2]};
|
||||||
uint8x16_t shufmask = vreinterpretq_u8_u64(shufmask64);
|
uint8x16_t shufmask = vreinterpretq_u8_u64(shufmask64);
|
||||||
// we increment by 0x08 the second half of the mask
|
// we increment by 0x08 the second half of the mask
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#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);
|
uint8x16_t inc = simdjson_make_uint8x16_t(0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08);
|
||||||
#else
|
#else
|
||||||
uint8x16_t inc = {0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
|
uint8x16_t inc = {0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
|
||||||
@@ -11056,7 +10974,7 @@ namespace {
|
|||||||
uint8x8_t compactmask1 = vcreate_u8(thintable_epi8[mask1]);
|
uint8x8_t compactmask1 = vcreate_u8(thintable_epi8[mask1]);
|
||||||
uint8x8_t compactmask2 = vcreate_u8(thintable_epi8[mask2]);
|
uint8x8_t compactmask2 = vcreate_u8(thintable_epi8[mask2]);
|
||||||
// we increment by 0x08 the second half of the mask
|
// we increment by 0x08 the second half of the mask
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
uint8x8_t inc = simdjson_make_uint8x8_t(0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08);
|
uint8x8_t inc = simdjson_make_uint8x8_t(0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08);
|
||||||
#else
|
#else
|
||||||
uint8x8_t inc = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
|
uint8x8_t inc = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
|
||||||
@@ -11108,7 +11026,7 @@ namespace {
|
|||||||
// Array constructor
|
// Array constructor
|
||||||
simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {}
|
simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {}
|
||||||
// Member-by-member initialization
|
// Member-by-member initialization
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
simdjson_inline simd8(
|
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 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 v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15
|
||||||
@@ -11229,7 +11147,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
simdjson_inline uint64_t to_bitmask() const {
|
simdjson_inline uint64_t to_bitmask() const {
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
const uint8x16_t bit_mask = simdjson_make_uint8x16_t(
|
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,
|
||||||
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80
|
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80
|
||||||
@@ -14182,7 +14100,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
|
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);
|
return arm64::stringparsing::parse_string(src, dst, allow_replacement);
|
||||||
}
|
}
|
||||||
@@ -14321,14 +14238,8 @@ static_assert(sizeof(__m256i) <= simdjson::SIMDJSON_PADDING, "insufficient paddi
|
|||||||
/* end file simdjson/haswell/intrinsics.h */
|
/* end file simdjson/haswell/intrinsics.h */
|
||||||
|
|
||||||
#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL
|
#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL
|
||||||
// We enable bmi2 only if LLVM/clang is used, because GCC may not
|
|
||||||
// make good use of it. See https://github.com/simdjson/simdjson/pull/2243
|
|
||||||
#if defined(__clang__)
|
|
||||||
SIMDJSON_TARGET_REGION("avx2,bmi,bmi2,pclmul,lzcnt,popcnt")
|
|
||||||
#else
|
|
||||||
SIMDJSON_TARGET_REGION("avx2,bmi,pclmul,lzcnt,popcnt")
|
SIMDJSON_TARGET_REGION("avx2,bmi,pclmul,lzcnt,popcnt")
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
/* including simdjson/haswell/bitmanipulation.h: #include "simdjson/haswell/bitmanipulation.h" */
|
/* including simdjson/haswell/bitmanipulation.h: #include "simdjson/haswell/bitmanipulation.h" */
|
||||||
/* begin file simdjson/haswell/bitmanipulation.h */
|
/* begin file simdjson/haswell/bitmanipulation.h */
|
||||||
@@ -15982,6 +15893,7 @@ simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(con
|
|||||||
// Our objective is accurate parsing (ULP of 0) at high speed.
|
// Our objective is accurate parsing (ULP of 0) at high speed.
|
||||||
template<typename W>
|
template<typename W>
|
||||||
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check for minus sign
|
// Check for minus sign
|
||||||
//
|
//
|
||||||
@@ -16959,14 +16871,8 @@ static_assert(sizeof(__m256i) <= simdjson::SIMDJSON_PADDING, "insufficient paddi
|
|||||||
/* end file simdjson/haswell/intrinsics.h */
|
/* end file simdjson/haswell/intrinsics.h */
|
||||||
|
|
||||||
#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL
|
#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL
|
||||||
// We enable bmi2 only if LLVM/clang is used, because GCC may not
|
|
||||||
// make good use of it. See https://github.com/simdjson/simdjson/pull/2243
|
|
||||||
#if defined(__clang__)
|
|
||||||
SIMDJSON_TARGET_REGION("avx2,bmi,bmi2,pclmul,lzcnt,popcnt")
|
|
||||||
#else
|
|
||||||
SIMDJSON_TARGET_REGION("avx2,bmi,pclmul,lzcnt,popcnt")
|
SIMDJSON_TARGET_REGION("avx2,bmi,pclmul,lzcnt,popcnt")
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
/* including simdjson/haswell/bitmanipulation.h: #include "simdjson/haswell/bitmanipulation.h" */
|
/* including simdjson/haswell/bitmanipulation.h: #include "simdjson/haswell/bitmanipulation.h" */
|
||||||
/* begin file simdjson/haswell/bitmanipulation.h */
|
/* begin file simdjson/haswell/bitmanipulation.h */
|
||||||
@@ -20410,7 +20316,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
|
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);
|
return haswell::stringparsing::parse_string(src, dst, replacement_char);
|
||||||
}
|
}
|
||||||
@@ -22202,6 +22107,7 @@ simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(con
|
|||||||
// Our objective is accurate parsing (ULP of 0) at high speed.
|
// Our objective is accurate parsing (ULP of 0) at high speed.
|
||||||
template<typename W>
|
template<typename W>
|
||||||
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check for minus sign
|
// Check for minus sign
|
||||||
//
|
//
|
||||||
@@ -26665,7 +26571,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
|
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);
|
return icelake::stringparsing::parse_string(src, dst, replacement_char);
|
||||||
}
|
}
|
||||||
@@ -26968,13 +26873,7 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace ppc64
|
} // namespace ppc64
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_PPC64_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_PPC64_NUMBERPARSING_DEFS_H
|
||||||
/* end file simdjson/ppc64/numberparsing_defs.h */
|
/* end file simdjson/ppc64/numberparsing_defs.h */
|
||||||
@@ -28578,6 +28477,7 @@ simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(con
|
|||||||
// Our objective is accurate parsing (ULP of 0) at high speed.
|
// Our objective is accurate parsing (ULP of 0) at high speed.
|
||||||
template<typename W>
|
template<typename W>
|
||||||
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check for minus sign
|
// Check for minus sign
|
||||||
//
|
//
|
||||||
@@ -29717,13 +29617,7 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace ppc64
|
} // namespace ppc64
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_PPC64_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_PPC64_NUMBERPARSING_DEFS_H
|
||||||
/* end file simdjson/ppc64/numberparsing_defs.h */
|
/* end file simdjson/ppc64/numberparsing_defs.h */
|
||||||
@@ -33090,7 +32984,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
|
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);
|
return ppc64::stringparsing::parse_string(src, dst, replacement_char);
|
||||||
}
|
}
|
||||||
@@ -35320,6 +35213,7 @@ simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(con
|
|||||||
// Our objective is accurate parsing (ULP of 0) at high speed.
|
// Our objective is accurate parsing (ULP of 0) at high speed.
|
||||||
template<typename W>
|
template<typename W>
|
||||||
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check for minus sign
|
// Check for minus sign
|
||||||
//
|
//
|
||||||
@@ -40179,7 +40073,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
|
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);
|
return westmere::stringparsing::parse_string(src, dst, replacement_char);
|
||||||
}
|
}
|
||||||
@@ -40406,13 +40299,7 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace lsx
|
} // namespace lsx
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_LSX_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_LSX_NUMBERPARSING_DEFS_H
|
||||||
/* end file simdjson/lsx/numberparsing_defs.h */
|
/* end file simdjson/lsx/numberparsing_defs.h */
|
||||||
@@ -41886,6 +41773,7 @@ simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(con
|
|||||||
// Our objective is accurate parsing (ULP of 0) at high speed.
|
// Our objective is accurate parsing (ULP of 0) at high speed.
|
||||||
template<typename W>
|
template<typename W>
|
||||||
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check for minus sign
|
// Check for minus sign
|
||||||
//
|
//
|
||||||
@@ -42940,13 +42828,7 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace lsx
|
} // namespace lsx
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_LSX_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_LSX_NUMBERPARSING_DEFS_H
|
||||||
/* end file simdjson/lsx/numberparsing_defs.h */
|
/* end file simdjson/lsx/numberparsing_defs.h */
|
||||||
@@ -46177,7 +46059,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
|
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
|
||||||
return lsx::stringparsing::parse_string(src, dst, allow_replacement);
|
return lsx::stringparsing::parse_string(src, dst, allow_replacement);
|
||||||
}
|
}
|
||||||
@@ -46401,13 +46282,7 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace lasx
|
} // namespace lasx
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_LASX_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_LASX_NUMBERPARSING_DEFS_H
|
||||||
/* end file simdjson/lasx/numberparsing_defs.h */
|
/* end file simdjson/lasx/numberparsing_defs.h */
|
||||||
@@ -47897,6 +47772,7 @@ simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(con
|
|||||||
// Our objective is accurate parsing (ULP of 0) at high speed.
|
// Our objective is accurate parsing (ULP of 0) at high speed.
|
||||||
template<typename W>
|
template<typename W>
|
||||||
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check for minus sign
|
// Check for minus sign
|
||||||
//
|
//
|
||||||
@@ -48951,13 +48827,7 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace lasx
|
} // namespace lasx
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_LASX_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_LASX_NUMBERPARSING_DEFS_H
|
||||||
/* end file simdjson/lasx/numberparsing_defs.h */
|
/* end file simdjson/lasx/numberparsing_defs.h */
|
||||||
@@ -52200,7 +52070,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
|
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
|
||||||
return lasx::stringparsing::parse_string(src, dst, allow_replacement);
|
return lasx::stringparsing::parse_string(src, dst, allow_replacement);
|
||||||
}
|
}
|
||||||
@@ -52442,13 +52311,7 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace fallback
|
} // namespace fallback
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H
|
||||||
/* end file simdjson/fallback/numberparsing_defs.h */
|
/* end file simdjson/fallback/numberparsing_defs.h */
|
||||||
@@ -53507,6 +53370,7 @@ simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(con
|
|||||||
// Our objective is accurate parsing (ULP of 0) at high speed.
|
// Our objective is accurate parsing (ULP of 0) at high speed.
|
||||||
template<typename W>
|
template<typename W>
|
||||||
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check for minus sign
|
// Check for minus sign
|
||||||
//
|
//
|
||||||
@@ -54581,13 +54445,7 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
|
|||||||
} // namespace fallback
|
} // namespace fallback
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#ifndef SIMDJSON_SWAR_NUMBER_PARSING
|
|
||||||
#if SIMDJSON_IS_BIG_ENDIAN
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 0
|
|
||||||
#else
|
|
||||||
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H
|
#endif // SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H
|
||||||
/* end file simdjson/fallback/numberparsing_defs.h */
|
/* end file simdjson/fallback/numberparsing_defs.h */
|
||||||
@@ -56174,7 +56032,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
|
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);
|
return fallback::stringparsing::parse_string(src, dst, replacement_char);
|
||||||
}
|
}
|
||||||
|
|||||||
+818
-1417
File diff suppressed because it is too large
Load Diff
@@ -150,7 +150,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
|
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);
|
return arm64::stringparsing::parse_string(src, dst, allow_replacement);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -388,7 +388,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
|
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);
|
return fallback::stringparsing::parse_string(src, dst, replacement_char);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,7 +147,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
|
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);
|
return haswell::stringparsing::parse_string(src, dst, replacement_char);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,7 +193,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
|
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);
|
return icelake::stringparsing::parse_string(src, dst, replacement_char);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
|
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
|
||||||
return lasx::stringparsing::parse_string(src, dst, allow_replacement);
|
return lasx::stringparsing::parse_string(src, dst, allow_replacement);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
|
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
|
||||||
return lsx::stringparsing::parse_string(src, dst, allow_replacement);
|
return lsx::stringparsing::parse_string(src, dst, allow_replacement);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
|
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);
|
return ppc64::stringparsing::parse_string(src, dst, replacement_char);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,7 +152,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::docu
|
|||||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMDJSON_NO_SANITIZE_MEMORY
|
|
||||||
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
|
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);
|
return westmere::stringparsing::parse_string(src, dst, replacement_char);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ add_cpp_test(errortests LABELS dom acceptance per_implementation
|
|||||||
add_cpp_test(extracting_values_example LABELS dom acceptance per_implementation)
|
add_cpp_test(extracting_values_example LABELS dom acceptance per_implementation)
|
||||||
add_cpp_test(integer_tests LABELS dom acceptance per_implementation)
|
add_cpp_test(integer_tests LABELS dom acceptance per_implementation)
|
||||||
add_cpp_test(jsoncheck LABELS dom acceptance per_implementation)
|
add_cpp_test(jsoncheck LABELS dom acceptance per_implementation)
|
||||||
add_cpp_test(json_path_tests LABELS dom acceptance per_implementation)
|
|
||||||
add_cpp_test(minefieldcheck LABELS dom acceptance per_implementation)
|
add_cpp_test(minefieldcheck LABELS dom acceptance per_implementation)
|
||||||
add_cpp_test(numberparsingcheck LABELS dom acceptance per_implementation) # https://tools.ietf.org/html/rfc6901
|
add_cpp_test(numberparsingcheck LABELS dom acceptance per_implementation) # https://tools.ietf.org/html/rfc6901
|
||||||
add_cpp_test(parse_many_test LABELS dom acceptance per_implementation)
|
add_cpp_test(parse_many_test LABELS dom acceptance per_implementation)
|
||||||
|
|||||||
@@ -1,350 +0,0 @@
|
|||||||
/**
|
|
||||||
* refer to pathcheck.cpp
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
using namespace std::string_literals;
|
|
||||||
|
|
||||||
#include "simdjson.h"
|
|
||||||
#include "test_macros.h"
|
|
||||||
|
|
||||||
// we define our own asserts to get around NDEBUG
|
|
||||||
#ifndef ASSERT
|
|
||||||
#define ASSERT(x) \
|
|
||||||
{ \
|
|
||||||
if (!(x)) { \
|
|
||||||
std::cerr << "Failed assertion " << #x << std::endl; \
|
|
||||||
return false; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace simdjson;
|
|
||||||
|
|
||||||
bool demo() {
|
|
||||||
#if SIMDJSON_EXCEPTIONS
|
|
||||||
std::cout << "demo test" << std::endl;
|
|
||||||
auto cars_json = R"( [
|
|
||||||
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
|
|
||||||
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
|
|
||||||
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
|
|
||||||
] )"_padded;
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element cars = parser.parse(cars_json);
|
|
||||||
double x = cars.at_path("$[0].tire_pressure[1]");
|
|
||||||
if (x != 39.9)
|
|
||||||
return false;
|
|
||||||
// Iterating through an array of objects
|
|
||||||
std::vector<double> measured;
|
|
||||||
for (dom::element car_element : cars) {
|
|
||||||
dom::object car;
|
|
||||||
simdjson::error_code error;
|
|
||||||
if ((error = car_element.get(car))) {
|
|
||||||
std::cerr << error << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
double x3 = car.at_path("$.tire_pressure[1]");
|
|
||||||
measured.push_back(x3);
|
|
||||||
}
|
|
||||||
std::vector<double> expected = {39.9, 31, 30};
|
|
||||||
if (measured != expected) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const padded_string TEST_JSON = R"(
|
|
||||||
{
|
|
||||||
"/~01abc": [
|
|
||||||
0,
|
|
||||||
{
|
|
||||||
"\\\" 0": [
|
|
||||||
"value0",
|
|
||||||
"value1"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"0": "0 ok",
|
|
||||||
"01": "01 ok",
|
|
||||||
"": "empty ok",
|
|
||||||
"arr": []
|
|
||||||
}
|
|
||||||
)"_padded;
|
|
||||||
|
|
||||||
const padded_string TEST_RFC_JSON = R"(
|
|
||||||
{
|
|
||||||
"foo": ["bar", "baz"],
|
|
||||||
"": 0,
|
|
||||||
"a/b": 1,
|
|
||||||
"c%d": 2,
|
|
||||||
"e^f": 3,
|
|
||||||
"g|h": 4,
|
|
||||||
"i\\j": 5,
|
|
||||||
"k\"l": 6,
|
|
||||||
" ": 7,
|
|
||||||
"m~n": 8
|
|
||||||
}
|
|
||||||
)"_padded;
|
|
||||||
|
|
||||||
bool run_success_test(const padded_string &source, const char *json_path,
|
|
||||||
std::string_view expected_value) {
|
|
||||||
std::cout << "Running successful JSONPath test '" << json_path << "' ..."
|
|
||||||
<< std::endl;
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element doc;
|
|
||||||
auto error = parser.parse(source).get(doc);
|
|
||||||
if (error) {
|
|
||||||
std::cerr << "cannot parse: " << error << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dom::element answer;
|
|
||||||
error = doc.at_path(json_path).get(answer);
|
|
||||||
if (error) {
|
|
||||||
std::cerr << "cannot access pointer: " << error << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::string str_answer = simdjson::minify(answer);
|
|
||||||
if (str_answer != expected_value) {
|
|
||||||
std::cerr << "They differ!!!" << std::endl;
|
|
||||||
std::cerr << " found '" << str_answer << "'" << std::endl;
|
|
||||||
std::cerr << " expected '" << expected_value << "'" << std::endl;
|
|
||||||
}
|
|
||||||
ASSERT_EQUAL(str_answer, expected_value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool run_failure_test(const padded_string &source, const char *json_path,
|
|
||||||
error_code expected_error) {
|
|
||||||
std::cout << "Running invalid JSONPath test '" << json_path << "' ..."
|
|
||||||
<< std::endl;
|
|
||||||
dom::parser parser;
|
|
||||||
ASSERT_ERROR(parser.parse(source).at_path(json_path).error(), expected_error);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool demo_relative_path() {
|
|
||||||
TEST_START();
|
|
||||||
auto cars_json = R"( [
|
|
||||||
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
|
|
||||||
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
|
|
||||||
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
|
|
||||||
] )"_padded;
|
|
||||||
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element cars;
|
|
||||||
std::vector<double> measured;
|
|
||||||
auto error = parser.parse(cars_json).get(cars);
|
|
||||||
if (error) {
|
|
||||||
std::cerr << "cannot parse: " << error << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dom::array cars_array;
|
|
||||||
error = cars.get(cars_array);
|
|
||||||
if (error) {
|
|
||||||
std::cerr << "cannot get array: " << error << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (auto car_element : cars_array) {
|
|
||||||
double x;
|
|
||||||
ASSERT_SUCCESS(car_element.at_path(".tire_pressure[1]").get(x));
|
|
||||||
measured.push_back(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<double> expected = {39.9, 31, 30};
|
|
||||||
if (measured != expected) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool many_json_paths() {
|
|
||||||
TEST_START();
|
|
||||||
auto cars_json = R"( [
|
|
||||||
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
|
|
||||||
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
|
|
||||||
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
|
|
||||||
] )"_padded;
|
|
||||||
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element cars;
|
|
||||||
std::vector<double> measured;
|
|
||||||
ASSERT_SUCCESS(parser.parse(cars_json).get(cars));
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
double x;
|
|
||||||
std::string json_path = std::string("$[") + std::to_string(i) +
|
|
||||||
std::string("].tire_pressure[1]");
|
|
||||||
ASSERT_SUCCESS(cars.at_path(json_path).get(x));
|
|
||||||
measured.push_back(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<double> expected = {39.9, 31, 30};
|
|
||||||
if (measured != expected) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool many_json_paths_object_array() {
|
|
||||||
TEST_START();
|
|
||||||
auto dogcatpotato =
|
|
||||||
R"( { "dog" : [1,2,3], "cat" : [5, 6, 7], "potato" : [1234]})"_padded;
|
|
||||||
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element doc;
|
|
||||||
ASSERT_SUCCESS(parser.parse(dogcatpotato).get(doc));
|
|
||||||
dom::object obj;
|
|
||||||
ASSERT_SUCCESS(doc.get_object().get(obj));
|
|
||||||
int64_t x;
|
|
||||||
ASSERT_SUCCESS(obj.at_path("$.dog[1]").get(x));
|
|
||||||
ASSERT_EQUAL(x, 2);
|
|
||||||
ASSERT_SUCCESS(obj.at_path("$.potato[0]").get(x));
|
|
||||||
ASSERT_EQUAL(x, 1234);
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
bool many_json_paths_object() {
|
|
||||||
TEST_START();
|
|
||||||
auto cfoofoo2 =
|
|
||||||
R"( { "c" :{ "foo": { "a": [ 10, 20, 30 ] }}, "d": { "foo2": { "a": [ 10, 20, 30 ] }} , "e": 120 })"_padded;
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element doc;
|
|
||||||
ASSERT_SUCCESS(parser.parse(cfoofoo2).get(doc));
|
|
||||||
dom::object obj;
|
|
||||||
ASSERT_SUCCESS(doc.get_object().get(obj));
|
|
||||||
int64_t x;
|
|
||||||
ASSERT_SUCCESS(obj.at_path("$.c.foo.a[1]").get(x));
|
|
||||||
ASSERT_EQUAL(x, 20);
|
|
||||||
ASSERT_SUCCESS(obj.at_path("$.d.foo2.a.2").get(x));
|
|
||||||
ASSERT_EQUAL(x, 30);
|
|
||||||
ASSERT_SUCCESS(obj.at_path("$.e").get(x));
|
|
||||||
ASSERT_EQUAL(x, 120);
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
bool many_json_paths_array() {
|
|
||||||
TEST_START();
|
|
||||||
auto cfoofoo2 =
|
|
||||||
R"( [ 111, 2, 3, { "foo": { "a": [ 10, 20, 33 ] }}, { "foo2": { "a": [ 10, 20, 30 ] }}, 1001 ])"_padded;
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element doc;
|
|
||||||
ASSERT_SUCCESS(parser.parse(cfoofoo2).get(doc));
|
|
||||||
dom::array arr;
|
|
||||||
ASSERT_SUCCESS(doc.get_array().get(arr));
|
|
||||||
int64_t x;
|
|
||||||
ASSERT_SUCCESS(arr.at_path("$[3].foo.a[1]").get(x));
|
|
||||||
ASSERT_EQUAL(x, 20);
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
struct car_type {
|
|
||||||
std::string make;
|
|
||||||
std::string model;
|
|
||||||
uint64_t year;
|
|
||||||
std::vector<double> tire_pressure;
|
|
||||||
car_type(std::string_view _make, std::string_view _model, uint64_t _year,
|
|
||||||
std::vector<double> &&_tire_pressure)
|
|
||||||
: make{_make}, model{_model}, year(_year), tire_pressure(_tire_pressure) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool json_path_invalidation() {
|
|
||||||
TEST_START();
|
|
||||||
auto cars_json = R"( [
|
|
||||||
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
|
|
||||||
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
|
|
||||||
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
|
|
||||||
] )"_padded;
|
|
||||||
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element cars;
|
|
||||||
std::vector<double> measured;
|
|
||||||
ASSERT_SUCCESS(parser.parse(cars_json).get(cars));
|
|
||||||
std::vector<car_type> content;
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
dom::object obj;
|
|
||||||
std::string json_path =
|
|
||||||
std::string("$[") + std::to_string(i) + std::string("]");
|
|
||||||
// Each successive at_path call invalidates
|
|
||||||
// previously parsed values, strings, objects and array.
|
|
||||||
ASSERT_SUCCESS(cars.at_path(json_path).get(obj));
|
|
||||||
// We materialize the object.
|
|
||||||
std::string_view make;
|
|
||||||
ASSERT_SUCCESS(obj["make"].get(make));
|
|
||||||
std::string_view model;
|
|
||||||
ASSERT_SUCCESS(obj["model"].get(model));
|
|
||||||
uint64_t year;
|
|
||||||
ASSERT_SUCCESS(obj["year"].get(year));
|
|
||||||
// We materialize the array.
|
|
||||||
dom::array arr;
|
|
||||||
ASSERT_SUCCESS(obj["tire_pressure"].get(arr));
|
|
||||||
std::vector<double> values;
|
|
||||||
for (auto x : arr) {
|
|
||||||
double value_double;
|
|
||||||
ASSERT_SUCCESS(x.get(value_double));
|
|
||||||
values.push_back(value_double);
|
|
||||||
}
|
|
||||||
content.emplace_back(make, model, year, std::move(values));
|
|
||||||
}
|
|
||||||
std::string expected[] = {"Toyota", "Kia", "Toyota"};
|
|
||||||
int i = 0;
|
|
||||||
for (car_type c : content) {
|
|
||||||
std::cout << c.make << " " << c.model << " " << c.year << "\n";
|
|
||||||
ASSERT_EQUAL(expected[i++], c.make);
|
|
||||||
}
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
// for 0.5 version and following (standard compliant)
|
|
||||||
bool modern_support() {
|
|
||||||
#if SIMDJSON_EXCEPTIONS
|
|
||||||
std::cout << "modern test" << std::endl;
|
|
||||||
auto example_json = R"({"key": "value", "array": [0, 1, 2]})"_padded;
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element example = parser.parse(example_json);
|
|
||||||
std::string_view value_str = example.at_path("$.key");
|
|
||||||
ASSERT_EQUAL(value_str, "value");
|
|
||||||
int64_t array0 = example.at_path("$.array[0]");
|
|
||||||
ASSERT_EQUAL(array0, 0);
|
|
||||||
array0 = example.at_path("$.array").at_path("$[0]");
|
|
||||||
ASSERT_EQUAL(array0, 0);
|
|
||||||
ASSERT_ERROR(example.at_path("$.no_such_key").error(), NO_SUCH_FIELD);
|
|
||||||
ASSERT_ERROR(example.at_path("$.array[9]").error(), INDEX_OUT_OF_BOUNDS);
|
|
||||||
ASSERT_ERROR(example.at_path("$.array.not_a_num").error(), INCORRECT_TYPE);
|
|
||||||
ASSERT_ERROR(example.at_path("$.array.").error(), INVALID_JSON_POINTER);
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
if (true && demo() && modern_support() &&
|
|
||||||
run_success_test(TEST_RFC_JSON, "$.foo", "[\"bar\",\"baz\"]") &&
|
|
||||||
run_success_test(TEST_RFC_JSON, "$.foo[0]", "\"bar\"") &&
|
|
||||||
run_success_test(TEST_RFC_JSON, "$.", "0") &&
|
|
||||||
run_success_test(TEST_RFC_JSON, "$.a/b", "1") &&
|
|
||||||
run_success_test(TEST_RFC_JSON, "$.c%d", "2") &&
|
|
||||||
run_success_test(TEST_RFC_JSON, "$.e^f", "3") &&
|
|
||||||
run_success_test(TEST_RFC_JSON, "$.g|h", "4") &&
|
|
||||||
run_success_test(TEST_RFC_JSON, "$.i\\j", "5") &&
|
|
||||||
run_success_test(TEST_RFC_JSON, "$.k\"l", "6") &&
|
|
||||||
run_success_test(TEST_RFC_JSON, "$. ", "7") &&
|
|
||||||
run_success_test(TEST_RFC_JSON, "$.m~n", "8") &&
|
|
||||||
run_success_test(TEST_JSON, "$./~01abc",
|
|
||||||
R"([0,{"\\\" 0":["value0","value1"]}])") &&
|
|
||||||
run_success_test(TEST_JSON, "$./~01abc[1]",
|
|
||||||
R"({"\\\" 0":["value0","value1"]})") &&
|
|
||||||
run_success_test(TEST_JSON, "$./~01abc[1].\\\" 0",
|
|
||||||
R"(["value0","value1"])") &&
|
|
||||||
run_success_test(TEST_JSON, "$.arr", R"([])") // get array
|
|
||||||
&&
|
|
||||||
run_failure_test(TEST_JSON, R"($./~01abc[1].\\\" 0[2])", NO_SUCH_FIELD) &&
|
|
||||||
run_failure_test(TEST_JSON, "$.arr[0]", INDEX_OUT_OF_BOUNDS) &&
|
|
||||||
run_failure_test(TEST_JSON, "/~01abc", INVALID_JSON_POINTER) &&
|
|
||||||
run_failure_test(TEST_JSON, ".~1abc", NO_SUCH_FIELD) &&
|
|
||||||
run_failure_test(TEST_JSON, "./~01abc.01", INVALID_JSON_POINTER) &&
|
|
||||||
run_failure_test(TEST_JSON, "./~01abc.", INVALID_JSON_POINTER) &&
|
|
||||||
run_failure_test(TEST_JSON, "./~01abc.-", INDEX_OUT_OF_BOUNDS)) {
|
|
||||||
std::cout << "Success!" << std::endl;
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
std::cerr << "Failed!" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -461,52 +461,7 @@ void parse_documentation_lowlevel() {
|
|||||||
(void)element;
|
(void)element;
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplepad() {
|
|
||||||
std::string json = "[1]";
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element doc;
|
|
||||||
auto error = parser.parse(simdjson::pad(json)).get(doc);
|
|
||||||
if(error) { exit(-1); }
|
|
||||||
}
|
|
||||||
|
|
||||||
void jsondollar() {
|
|
||||||
dom::parser parser;
|
|
||||||
auto json = R"( { "c" :{ "foo": { "a": [ 10, 20, 30 ] }}, "d": { "foo2": { "a": [ 10, 20, 30 ] }} , "e": 120 })"_padded;
|
|
||||||
dom::element doc;
|
|
||||||
auto error = parser.parse(json).get(doc);
|
|
||||||
if(error) { exit(-1); }
|
|
||||||
dom::object obj;
|
|
||||||
error = doc.get_object().get(obj);
|
|
||||||
if(error) { exit(-1); }
|
|
||||||
int64_t x = 0; // initialization to silence unwarranted compiler warning
|
|
||||||
error = obj.at_path("$[3].foo.a[1]").get(x);
|
|
||||||
if(error) { exit(-1); }
|
|
||||||
if(x != 20) { exit(-1); }
|
|
||||||
x = obj.at_path("$.d.foo2.a.2");
|
|
||||||
if(x != 30) { exit(-1); }
|
|
||||||
if(error) { exit(-1); }
|
|
||||||
}
|
|
||||||
|
|
||||||
void jsonpath() {
|
|
||||||
auto cars_json = R"( [
|
|
||||||
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
|
|
||||||
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
|
|
||||||
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
|
|
||||||
] )"_padded;
|
|
||||||
dom::parser parser;
|
|
||||||
dom::element doc;
|
|
||||||
auto error = parser.parse(cars_json).get(doc);
|
|
||||||
if(error) { exit(-1); }
|
|
||||||
double p = 0.0; // initialization to silence unwarranted compiler warning
|
|
||||||
error = doc.at_path("[0].tire_pressure[1]").get(p);
|
|
||||||
if(error) { exit(-1); }
|
|
||||||
if(p != 39.9) { exit(-1); }
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
simplepad();
|
|
||||||
jsonpath();
|
|
||||||
jsondollar();
|
|
||||||
basics_dom_1();
|
basics_dom_1();
|
||||||
basics_dom_2();
|
basics_dom_2();
|
||||||
basics_dom_3();
|
basics_dom_3();
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ function(add_dual_compile_test TEST_NAME)
|
|||||||
target_compile_definitions(${TEST_NAME}_should_not_compile PRIVATE COMPILATION_TEST_USE_FAILING_CODE=1)
|
target_compile_definitions(${TEST_NAME}_should_not_compile PRIVATE COMPILATION_TEST_USE_FAILING_CODE=1)
|
||||||
endfunction(add_dual_compile_test)
|
endfunction(add_dual_compile_test)
|
||||||
|
|
||||||
add_dual_compile_test(iterate_object)
|
|
||||||
add_dual_compile_test(iterate_array)
|
|
||||||
add_dual_compile_test(iterate_char_star)
|
add_dual_compile_test(iterate_char_star)
|
||||||
add_dual_compile_test(iterate_string_view)
|
add_dual_compile_test(iterate_string_view)
|
||||||
add_dual_compile_test(iterate_temporary_buffer)
|
add_dual_compile_test(iterate_temporary_buffer)
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include "simdjson.h"
|
|
||||||
|
|
||||||
using namespace simdjson;
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
auto json = "[1]"_padded;
|
|
||||||
ondemand::parser parser;
|
|
||||||
auto f = [](ondemand::parser& p, simdjson::padded_string& jsons) -> ondemand::document {
|
|
||||||
ondemand::document doc;
|
|
||||||
auto error = p.iterate(jsons).get(doc);
|
|
||||||
if(error) { std::abort(); }
|
|
||||||
return doc;
|
|
||||||
};
|
|
||||||
ondemand::array arrayv;
|
|
||||||
#if COMPILATION_TEST_USE_FAILING_CODE
|
|
||||||
// Not allowed as this would be unsafe, the document must remain alive.
|
|
||||||
auto error = f(parser).get_array().get(arrayv);
|
|
||||||
#else
|
|
||||||
ondemand::document doc = f(parser, json);
|
|
||||||
auto error = doc.get_array().get(arrayv);
|
|
||||||
#endif
|
|
||||||
if(error) {
|
|
||||||
std::cout << "Failure" << std::endl;
|
|
||||||
}
|
|
||||||
int64_t a = 0;
|
|
||||||
error = arrayv.at(0).get_int64().get(a);
|
|
||||||
if(error) {
|
|
||||||
std::cout << "failure" << std::endl;
|
|
||||||
}
|
|
||||||
printf("a = %d\n", (int)a);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include "simdjson.h"
|
|
||||||
|
|
||||||
using namespace simdjson;
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
auto json = "{\"a\":1}"_padded;
|
|
||||||
ondemand::parser parser;
|
|
||||||
auto f = [](ondemand::parser& p, simdjson::padded_string& jsons) -> ondemand::document {
|
|
||||||
ondemand::document doc;
|
|
||||||
auto error = p.iterate(jsons).get(doc);
|
|
||||||
if(error) { std::abort(); }
|
|
||||||
return doc;
|
|
||||||
};
|
|
||||||
ondemand::object objv;
|
|
||||||
#if COMPILATION_TEST_USE_FAILING_CODE
|
|
||||||
// Not allowed as this would be unsafe, the document must remain alive.
|
|
||||||
auto error = f(parser).get_object().get(objv);
|
|
||||||
#else
|
|
||||||
ondemand::document doc = f(parser, json);
|
|
||||||
auto error = doc.get_object().get(objv);
|
|
||||||
#endif
|
|
||||||
if(error) {
|
|
||||||
std::cout << "Failure" << std::endl;
|
|
||||||
}
|
|
||||||
int64_t a = 0;
|
|
||||||
error = objv["a"].get_int64().get(a);
|
|
||||||
if(error) {
|
|
||||||
std::cout << "failure" << std::endl;
|
|
||||||
}
|
|
||||||
printf("a = %d\n", (int)a);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -21,24 +21,8 @@ long page_size() {
|
|||||||
// Returns true if the buffer + len + simdjson::SIMDJSON_PADDING crosses the
|
// Returns true if the buffer + len + simdjson::SIMDJSON_PADDING crosses the
|
||||||
// page boundary.
|
// page boundary.
|
||||||
bool need_allocation(const char *buf, size_t len) {
|
bool need_allocation(const char *buf, size_t len) {
|
||||||
return ((reinterpret_cast<uintptr_t>(buf + len - 1) % page_size())
|
return ((reinterpret_cast<uintptr_t>(buf + len - 1) % page_size()) <
|
||||||
+ simdjson::SIMDJSON_PADDING > static_cast<uintptr_t>(page_size()));
|
simdjson::SIMDJSON_PADDING);
|
||||||
}
|
|
||||||
|
|
||||||
bool check_need_allocation() {
|
|
||||||
long ps = page_size();
|
|
||||||
std::vector<std::tuple<uintptr_t,size_t,bool>> test_cases = {
|
|
||||||
{2*ps, 5, false}, {2*ps, ps, true}, {2*ps, 100, false},
|
|
||||||
};
|
|
||||||
for(auto t : test_cases) {
|
|
||||||
uintptr_t buf = std::get<0>(t);
|
|
||||||
size_t len = std::get<1>(t);
|
|
||||||
bool expected = std::get<2>(t);
|
|
||||||
if(need_allocation(reinterpret_cast<const char *>(buf), len) != expected) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson::padded_string_view
|
simdjson::padded_string_view
|
||||||
@@ -55,10 +39,6 @@ get_padded_string_view(const char *buf, size_t len,
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
printf("page_size: %ld\n", page_size());
|
printf("page_size: %ld\n", page_size());
|
||||||
if(!check_need_allocation()) {
|
|
||||||
printf("Bug in the need_allocation function.\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
const char *jsonpoiner = R"(
|
const char *jsonpoiner = R"(
|
||||||
{
|
{
|
||||||
"key": "value"
|
"key": "value"
|
||||||
|
|||||||
@@ -59,22 +59,6 @@ void compilation_test_3() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not run this, it is only meant to compile
|
|
||||||
void compilation_test_4() {
|
|
||||||
const padded_string bogus = ""_padded;
|
|
||||||
ondemand::parser parser;
|
|
||||||
int64_t x1 = (int64_t)parser.iterate(bogus);
|
|
||||||
double x2 = (double)parser.iterate(bogus);
|
|
||||||
std::string_view x = (std::string_view)parser.iterate(bogus);
|
|
||||||
uint64_t x3 = (uint64_t)parser.iterate(bogus);
|
|
||||||
bool x4 = (bool)parser.iterate(bogus);
|
|
||||||
(void) x1;
|
|
||||||
(void) x2;
|
|
||||||
(void) x3;
|
|
||||||
(void) x4;
|
|
||||||
(void) x;
|
|
||||||
}
|
|
||||||
#endif // SIMDJSON_EXCEPTIONS
|
#endif // SIMDJSON_EXCEPTIONS
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|||||||
@@ -346,54 +346,6 @@ namespace json_path_tests {
|
|||||||
TEST_SUCCEED();
|
TEST_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool many_json_paths_with_prefix() {
|
|
||||||
TEST_START();
|
|
||||||
// object
|
|
||||||
{
|
|
||||||
auto cfoofoo2 = R"( { "c" :{ "foo": { "a": [ 10, 20, 30 ] }}, "d": { "foo2": { "a": [ 10, 20, 30 ] }} , "e": 120 })"_padded;
|
|
||||||
ondemand::parser parser;
|
|
||||||
ondemand::document doc;
|
|
||||||
ASSERT_SUCCESS(parser.iterate(cfoofoo2).get(doc));
|
|
||||||
ondemand::object obj;
|
|
||||||
ASSERT_SUCCESS(doc.get_object().get(obj));
|
|
||||||
int64_t x;
|
|
||||||
ASSERT_SUCCESS(obj.at_path("$.c.foo.a[1]").get(x));
|
|
||||||
ASSERT_EQUAL(x, 20);
|
|
||||||
ASSERT_SUCCESS(obj.at_path("$.d.foo2.a.2").get(x));
|
|
||||||
ASSERT_EQUAL(x, 30);
|
|
||||||
ASSERT_SUCCESS(obj.at_path("$.e").get(x));
|
|
||||||
ASSERT_EQUAL(x, 120);
|
|
||||||
}
|
|
||||||
// array
|
|
||||||
{
|
|
||||||
auto cfoofoo2 = R"( [ 111, 2, 3, { "foo": { "a": [ 10, 20, 33 ] }}, { "foo2": { "a": [ 10, 20, 30 ] }}, 1001 ])"_padded;
|
|
||||||
ondemand::parser parser;
|
|
||||||
ondemand::document doc;
|
|
||||||
ASSERT_SUCCESS(parser.iterate(cfoofoo2).get(doc));
|
|
||||||
ondemand::array arr;
|
|
||||||
ASSERT_SUCCESS(doc.get_array().get(arr));
|
|
||||||
int64_t x;
|
|
||||||
ASSERT_SUCCESS(arr.at_path("$[3].foo.a[1]").get(x));
|
|
||||||
ASSERT_EQUAL(x, 20);
|
|
||||||
}
|
|
||||||
// onject array
|
|
||||||
{
|
|
||||||
auto dogcatpotato = R"( { "dog" : [1,2,3], "cat" : [5, 6, 7], "potato" : [1234]})"_padded;
|
|
||||||
|
|
||||||
ondemand::parser parser;
|
|
||||||
ondemand::document doc;
|
|
||||||
ASSERT_SUCCESS(parser.iterate(dogcatpotato).get(doc));
|
|
||||||
ondemand::object obj;
|
|
||||||
ASSERT_SUCCESS(doc.get_object().get(obj));
|
|
||||||
int64_t x;
|
|
||||||
ASSERT_SUCCESS(obj.at_path("$.dog[1]").get(x));
|
|
||||||
ASSERT_EQUAL(x, 2);
|
|
||||||
ASSERT_SUCCESS(obj.at_path("$.potato[0]").get(x));
|
|
||||||
ASSERT_EQUAL(x, 1234);
|
|
||||||
}
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SIMDJSON_EXCEPTIONS
|
#if SIMDJSON_EXCEPTIONS
|
||||||
bool json_path_invalidation_exceptions() {
|
bool json_path_invalidation_exceptions() {
|
||||||
TEST_START();
|
TEST_START();
|
||||||
@@ -440,7 +392,6 @@ namespace json_path_tests {
|
|||||||
many_json_paths_array() &&
|
many_json_paths_array() &&
|
||||||
many_json_paths_object() &&
|
many_json_paths_object() &&
|
||||||
many_json_paths_object_array() &&
|
many_json_paths_object_array() &&
|
||||||
many_json_paths_with_prefix() &&
|
|
||||||
run_broken_tests() &&
|
run_broken_tests() &&
|
||||||
json_path_invalidation() &&
|
json_path_invalidation() &&
|
||||||
demo_test() &&
|
demo_test() &&
|
||||||
|
|||||||
@@ -164,7 +164,8 @@ namespace json_pointer_tests {
|
|||||||
ASSERT_TRUE(is_scalar);
|
ASSERT_TRUE(is_scalar);
|
||||||
ASSERT_ERROR(doc.at_pointer("").get(val), simdjson::SCALAR_DOCUMENT_AS_VALUE);
|
ASSERT_ERROR(doc.at_pointer("").get(val), simdjson::SCALAR_DOCUMENT_AS_VALUE);
|
||||||
std::cout << " checking true"<< std::endl;
|
std::cout << " checking true"<< std::endl;
|
||||||
ASSERT_SUCCESS(parser.iterate(true_json).is_scalar().get(is_scalar));
|
ASSERT_SUCCESS(parser.iterate(true_json).get(doc));
|
||||||
|
ASSERT_SUCCESS(doc.is_scalar().get(is_scalar));
|
||||||
ASSERT_TRUE(is_scalar);
|
ASSERT_TRUE(is_scalar);
|
||||||
ASSERT_ERROR(doc.at_pointer("").get(val), simdjson::SCALAR_DOCUMENT_AS_VALUE);
|
ASSERT_ERROR(doc.at_pointer("").get(val), simdjson::SCALAR_DOCUMENT_AS_VALUE);
|
||||||
std::cout << " checking object"<< std::endl;
|
std::cout << " checking object"<< std::endl;
|
||||||
|
|||||||
@@ -5,23 +5,6 @@ using namespace simdjson;
|
|||||||
|
|
||||||
namespace misc_tests {
|
namespace misc_tests {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
bool issue2322() {
|
|
||||||
TEST_START();
|
|
||||||
std::vector<std::pair<std::string, bool>> examples = {{R"("hello")", false},
|
|
||||||
{R"(\"hello)", true},
|
|
||||||
{R"("hello\")", true},
|
|
||||||
{R"("hel\"lo")", false},
|
|
||||||
{R"("hel\\lo")", false},
|
|
||||||
{R"(\"hel\\\"lo\")", true},
|
|
||||||
{R"(\\"hel\\\"lo\")", false}};
|
|
||||||
for (std::pair<std::string, bool> v : examples) {
|
|
||||||
ASSERT_EQUAL(ondemand::raw_json_string::is_free_from_unescaped_quote(v.first),
|
|
||||||
v.second);
|
|
||||||
ASSERT_EQUAL(ondemand::raw_json_string::is_free_from_unescaped_quote(v.first.c_str()),
|
|
||||||
v.second);
|
|
||||||
}
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
#if SIMDJSON_EXCEPTIONS
|
#if SIMDJSON_EXCEPTIONS
|
||||||
// user reported an asan error:
|
// user reported an asan error:
|
||||||
bool issue2199() {
|
bool issue2199() {
|
||||||
@@ -554,24 +537,6 @@ bool issue2322() {
|
|||||||
TEST_SUCCEED();
|
TEST_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_warn_unused bool issue2312() {
|
|
||||||
TEST_START();
|
|
||||||
std::string init_string = R"("abc":)";
|
|
||||||
init_string.resize(init_string.size() + simdjson::SIMDJSON_PADDING);
|
|
||||||
simdjson::padded_string_view padded_view{init_string.data(), 5, init_string.size()};
|
|
||||||
simdjson::ondemand::parser parser;
|
|
||||||
simdjson::ondemand::document doc;
|
|
||||||
ASSERT_SUCCESS(parser.iterate(padded_view).get(doc));
|
|
||||||
std::string_view abc;
|
|
||||||
ASSERT_SUCCESS(doc.get_string().get(abc));
|
|
||||||
ASSERT_EQUAL(abc, "abc");
|
|
||||||
ASSERT_SUCCESS(parser.iterate(padded_view).get(doc));
|
|
||||||
std::string_view raw;
|
|
||||||
ASSERT_SUCCESS(doc.raw_json().get(raw));
|
|
||||||
ASSERT_EQUAL(raw, "\"abc\"");
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
simdjson_warn_unused bool big_integer() {
|
simdjson_warn_unused bool big_integer() {
|
||||||
TEST_START();
|
TEST_START();
|
||||||
simdjson::ondemand::parser parser;
|
simdjson::ondemand::parser parser;
|
||||||
@@ -655,8 +620,6 @@ bool issue2322() {
|
|||||||
|
|
||||||
bool run() {
|
bool run() {
|
||||||
return
|
return
|
||||||
issue2322() &&
|
|
||||||
issue2312() &&
|
|
||||||
#if SIMDJSON_EXCEPTIONS
|
#if SIMDJSON_EXCEPTIONS
|
||||||
issue2199() &&
|
issue2199() &&
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,15 +8,7 @@
|
|||||||
#endif
|
#endif
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace simdjson;
|
using namespace simdjson;
|
||||||
using error_code = simdjson::error_code;
|
using error_code=simdjson::error_code;
|
||||||
|
|
||||||
bool simplepad() {
|
|
||||||
std::string json = "[1]";
|
|
||||||
ondemand::parser parser;
|
|
||||||
ondemand::document doc;
|
|
||||||
auto error = parser.iterate(simdjson::pad(json)).get(doc);
|
|
||||||
return error == SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool string1() {
|
bool string1() {
|
||||||
const char * data = "my data"; // 7 bytes
|
const char * data = "my data"; // 7 bytes
|
||||||
@@ -229,19 +221,6 @@ bool gen_raw2() {
|
|||||||
TEST_SUCCEED();
|
TEST_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool jsondollar() {
|
|
||||||
TEST_START();
|
|
||||||
auto json = R"( { "c" :{ "foo": { "a": [ 10, 20, 30 ] }}, "d": { "foo2": { "a": [ 10, 20, 30 ] }} , "e": 120 })"_padded;
|
|
||||||
ondemand::parser parser;
|
|
||||||
ondemand::document doc = parser.iterate(json);
|
|
||||||
ondemand::object obj = doc.get_object();
|
|
||||||
int64_t x = obj.at_path("$.c.foo.a[1]"); // 20
|
|
||||||
ASSERT_EQUAL(x, 20);
|
|
||||||
x = obj.at_path("$.d.foo2.a.2"); // 30
|
|
||||||
ASSERT_EQUAL(x, 30);
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gen_raw3() {
|
bool gen_raw3() {
|
||||||
TEST_START();
|
TEST_START();
|
||||||
simdjson::ondemand::parser parser;
|
simdjson::ondemand::parser parser;
|
||||||
@@ -1897,7 +1876,6 @@ bool run() {
|
|||||||
#if SIMDJSON_CPLUSPLUS17
|
#if SIMDJSON_CPLUSPLUS17
|
||||||
&& big_int_array()
|
&& big_int_array()
|
||||||
#endif // SIMDJSON_CPLUSPLUS17
|
#endif // SIMDJSON_CPLUSPLUS17
|
||||||
&& jsondollar()
|
|
||||||
&& big_int_array_as_double()
|
&& big_int_array_as_double()
|
||||||
&& key_raw_json_token()
|
&& key_raw_json_token()
|
||||||
&& to_optional()
|
&& to_optional()
|
||||||
@@ -1926,7 +1904,6 @@ bool run() {
|
|||||||
&& using_the_parsed_json_4()
|
&& using_the_parsed_json_4()
|
||||||
&& using_the_parsed_json_5()
|
&& using_the_parsed_json_5()
|
||||||
#endif
|
#endif
|
||||||
&& simplepad()
|
|
||||||
&& using_the_parsed_json_6()
|
&& using_the_parsed_json_6()
|
||||||
&& json_pointer_simple()
|
&& json_pointer_simple()
|
||||||
&& json_pointer_unicode()
|
&& json_pointer_unicode()
|
||||||
|
|||||||
@@ -369,24 +369,15 @@ namespace scalar_tests {
|
|||||||
ondemand::parser parser;
|
ondemand::parser parser;
|
||||||
ondemand::document doc;
|
ondemand::document doc;
|
||||||
ASSERT_SUCCESS(parser.iterate(json).get(doc));
|
ASSERT_SUCCESS(parser.iterate(json).get(doc));
|
||||||
ASSERT_ERROR(doc.is_null(), INCORRECT_TYPE);
|
bool x;
|
||||||
TEST_SUCCEED();
|
ASSERT_SUCCESS(doc.is_null().get(x));
|
||||||
}
|
ASSERT_TRUE(!x);
|
||||||
|
|
||||||
bool nul() {
|
|
||||||
TEST_START();
|
|
||||||
auto json = R"( nul )"_padded;
|
|
||||||
ondemand::parser parser;
|
|
||||||
ondemand::document doc;
|
|
||||||
ASSERT_SUCCESS(parser.iterate(json).get(doc));
|
|
||||||
ASSERT_ERROR(doc.is_null(), INCORRECT_TYPE);
|
|
||||||
TEST_SUCCEED();
|
TEST_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool run() {
|
bool run() {
|
||||||
return
|
return
|
||||||
nully() &&
|
nully() &&
|
||||||
nul() &&
|
|
||||||
string_with_trailing() &&
|
string_with_trailing() &&
|
||||||
uint64_with_trailing() &&
|
uint64_with_trailing() &&
|
||||||
int64_with_trailing() &&
|
int64_with_trailing() &&
|
||||||
|
|||||||
Reference in New Issue
Block a user