Compare commits

..

1 Commits

Author SHA1 Message Date
Daniel Lemire 44c69f64f6 bumping up cmake 2026-03-25 10:21:18 -04:00
65 changed files with 1353 additions and 4595 deletions
+1 -1
View File
@@ -24,6 +24,6 @@ jobs:
apt-get update -q -y
apt-get install -y cmake make g++
run: |
cmake -DSIMDJSON_SANITIZE_UNDEFINED=ON -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -B build
cmake -DSIMDJSON_SANITIZE_UNDEFINED=ON -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build -j=2
ctest --output-on-failure --test-dir build
+3 -3
View File
@@ -18,13 +18,13 @@ jobs:
run: |
mkdir builddebug &&
cd builddebug &&
cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF .. &&
cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . &&
ctest --output-on-failure -LE explicitonly -j &&
cd .. &&
mkdir build &&
cd build &&
cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . &&
ctest --output-on-failure -LE explicitonly -j &&
cmake --install . &&
@@ -35,7 +35,7 @@ jobs:
run: |
mkdir buildshared &&
cd buildshared &&
cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX:PATH=destination -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . &&
ctest --output-on-failure -LE explicitonly -j &&
cmake --install . &&
+1 -1
View File
@@ -43,6 +43,6 @@ jobs:
run: |
mkdir build
cd build
cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DBUILD_SHARED_LIBS=OFF -DSIMDJSON_DO_NOT_USE_THREADS_NO_MATTER_WHAT=ON ..
cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DBUILD_SHARED_LIBS=OFF -DSIMDJSON_DO_NOT_USE_THREADS_NO_MATTER_WHAT=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON ..
cmake --build . --verbose
ctest -j4 --output-on-failure -LE explicitonly
+1 -1
View File
@@ -24,6 +24,6 @@ jobs:
apt-get update -q -y
apt-get install -y cmake make g++
run: |
cmake -DCMAKE_BUILD_TYPE=Release -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -B build
cmake -DCMAKE_BUILD_TYPE=Release -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build -j=2
ctest --output-on-failure --test-dir build
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
- name: Build
run: |
CC=clang-18 CXX=clang++-18 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv_zvbb" CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build/ -j$(nproc) --config Release
- name: Test VLEN=1024
run: |
+2 -2
View File
@@ -20,7 +20,7 @@ jobs:
- name: Build
run: |
CC=clang-20 CXX=clang++-20 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv" CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build/ -j$(nproc) --config Release
- name: Test VLEN=128
run: |
@@ -30,7 +30,7 @@ jobs:
- name: Build VLS
run: |
CC=clang-20 CXX=clang++-20 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv_zvl128b_zba_zbb_zbc -mrvv-vector-bits=zvl" CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build-vls
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build-vls
cmake --build build-vls/ -j$(nproc) --config Release
- name: Test VLEN=128 VLS
run: |
+2 -2
View File
@@ -20,7 +20,7 @@ jobs:
- name: Build
run: |
CC=riscv64-linux-gnu-gcc-14 CXX=riscv64-linux-gnu-g++-14 CFLAGS=-march=rv64gcv CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build/ -j$(nproc) --config Release
- name: Test VLEN=256
run: |
@@ -30,7 +30,7 @@ jobs:
- name: Build VLS
run: |
CC=riscv64-linux-gnu-gcc-14 CXX=riscv64-linux-gnu-g++-14 CFLAGS="-march=rv64gcv_zvl256b -mrvv-vector-bits=zvl" CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build-vls
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build-vls
cmake --build build-vls/ -j$(nproc) --config Release
- name: Test VLEN=256 VLS
run: |
+2 -2
View File
@@ -20,7 +20,7 @@ jobs:
- name: Build
run: |
CC=clang-19 CXX=clang++-19 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv" CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build/ -j$(nproc) --config Release
- name: Test VLEN=512
run: |
@@ -30,7 +30,7 @@ jobs:
- name: Build VLS
run: |
CC=clang-19 CXX=clang++-19 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv_zvl512b_zba_zbb_zbc -mrvv-vector-bits=zvl" CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build-vls
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build-vls
cmake --build build-vls/ -j$(nproc) --config Release
- name: Test VLEN=512 VLS
run: |
+1 -1
View File
@@ -24,6 +24,6 @@ jobs:
apt-get update -q -y
apt-get install -y cmake make g++
run: |
cmake -DCMAKE_BUILD_TYPE=Release -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -B build
cmake -DCMAKE_BUILD_TYPE=Release -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build -j=2
ctest --output-on-failure --test-dir build
+1 -1
View File
@@ -18,6 +18,6 @@ jobs:
run: |
mkdir build &&
cd build &&
CXX=clang++-13 cmake -DSIMDJSON_DEVELOPER_MODE=ON .. &&
CXX=clang++-13 cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . &&
ctest --output-on-failure -LE explicitonly -j
@@ -19,6 +19,6 @@ jobs:
run: |
mkdir build &&
cd build &&
CXX=g++-12 cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GLIBCXX_ASSERTIONS=ON -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON .. &&
CXX=g++-12 cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GLIBCXX_ASSERTIONS=ON -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . &&
ctest . -E avoid_
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
run: |
mkdir build &&
cd build &&
CXX=g++-12 cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_SANITIZE_THREADS=ON .. &&
CXX=g++-12 cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_SANITIZE_THREADS=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . --target document_stream_tests --target ondemand_document_stream_tests --target parse_many_test &&
ctest --output-on-failure -R parse_many_test &&
ctest --output-on-failure -R document_stream_tests
+1 -1
View File
@@ -24,6 +24,6 @@ jobs:
run: |
mkdir build &&
cd build &&
cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_ENABLE_DOM_CHECKPERF=ON -DCMAKE_CXX_FLAGS="-Werror=old-style-cast -pedantic -Wpedantic" -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_ENABLE_DOM_CHECKPERF=ON -DCMAKE_CXX_FLAGS="-Werror=old-style-cast -pedantic -Wpedantic" -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . --target checkperf &&
ctest --output-on-failure -R checkperf
@@ -13,7 +13,7 @@ jobs:
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Prepare
run: cmake -DSIMDJSON_CXX_STANDARD=20 -DSIMDJSON_EXCEPTIONS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -B build
run: cmake -DSIMDJSON_CXX_STANDARD=20 -DSIMDJSON_EXCEPTIONS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
env:
CXX: ${{matrix.cxx}}
- name: Build
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Prepare
run: cmake -DSIMDJSON_CXX_STANDARD=20 -DSIMDJSON_DEVELOPER_MODE=ON -B build
run: cmake -DSIMDJSON_CXX_STANDARD=20 -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
env:
CXX: ${{matrix.cxx}}
- name: Build
+2 -2
View File
@@ -18,13 +18,13 @@ jobs:
run: |
mkdir builddebug &&
cd builddebug &&
cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_EXCEPTIONS=OFF -DBUILD_SHARED_LIBS=OFF .. &&
cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_EXCEPTIONS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . &&
ctest --output-on-failure -LE explicitonly -j &&
cd .. &&
mkdir build &&
cd build &&
cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_EXCEPTIONS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_EXCEPTIONS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . &&
ctest --output-on-failure -LE explicitonly -j &&
make install &&
+2 -2
View File
@@ -18,13 +18,13 @@ jobs:
run: |
mkdir builddebug &&
cd builddebug &&
cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_ENABLE_THREADS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF .. &&
cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_ENABLE_THREADS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . &&
ctest --output-on-failure -LE explicitonly -j &&
cd .. &&
mkdir build &&
cd build &&
cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_ENABLE_THREADS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_ENABLE_THREADS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . &&
ctest --output-on-failure -LE explicitonly -j &&
make install &&
+2 -2
View File
@@ -18,7 +18,7 @@ jobs:
run: |
mkdir builddebug &&
cd builddebug &&
cmake -DSIMDJSON_SANITIZE=ON -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF .. &&
cmake -DSIMDJSON_SANITIZE=ON -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . &&
ctest --output-on-failure -LE explicitonly -j
ubuntu-build-undefined-sanitizer:
@@ -36,6 +36,6 @@ jobs:
run: |
mkdir builddebugundefsani &&
cd builddebugundefsani &&
cmake -DSIMDJSON_SANITIZE_UNDEFINED=ON -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF .. &&
cmake -DSIMDJSON_SANITIZE_UNDEFINED=ON -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . &&
ctest --output-on-failure -LE explicitonly -j
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Prepare
run: cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_SANITIZE=${{matrix.sanitizer}} -DBUILD_SHARED_LIBS=${{matrix.shared}} -B build
run: cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_SANITIZE=${{matrix.sanitizer}} -DBUILD_SHARED_LIBS=${{matrix.shared}} -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
env:
CXX: ${{matrix.cxx}}
- name: Build
+1 -1
View File
@@ -17,5 +17,5 @@ jobs:
uses: actions/checkout@v4
- name: Use cmake
run: |
cmake -A ${{ matrix.arch }} -DCMAKE_SYSTEM_VERSION="10.0.22621.0" -DCMAKE_CROSSCOMPILING=1 -DSIMDJSON_DEVELOPER_MODE=ON -D SIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_EXCEPTIONS=OFF -B build &&
cmake -A ${{ matrix.arch }} -DCMAKE_SYSTEM_VERSION="10.0.22621.0" -DCMAKE_CROSSCOMPILING=1 -DSIMDJSON_DEVELOPER_MODE=ON -D SIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_EXCEPTIONS=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build &&
cmake --build build --verbose
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
uses: actions/checkout@v4
- name: Configure
run: |
cmake -DSIMDJSON_CXX_STANDARD=20 -G "${{matrix.gen}}" -A ${{matrix.arch}} -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DBUILD_SHARED_LIBS=${{matrix.shared}} -B build
cmake -DSIMDJSON_CXX_STANDARD=20 -G "${{matrix.gen}}" -A ${{matrix.arch}} -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DBUILD_SHARED_LIBS=${{matrix.shared}} -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
- name: Build Debug
run: cmake --build build --config Debug --verbose
- name: Build Release
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
uses: actions/checkout@v4
- name: Configure
run: |
cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -T ClangCL -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -B build
cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -T ClangCL -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
- name: Build
run: cmake --build build --config ${{matrix.build_type}} --verbose
- name: Run tests
+84 -98
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.14)
cmake_minimum_required(VERSION 3.24)
# Build performance optimizations
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "Export compile commands for faster IDE integration")
@@ -12,7 +12,7 @@ endif()
project(
simdjson
# The version number is modified by tools/release.py
VERSION 4.6.4
VERSION 4.4.2
DESCRIPTION "Parsing gigabytes of JSON per second"
HOMEPAGE_URL "https://simdjson.org/"
LANGUAGES CXX C
@@ -29,8 +29,8 @@ string(
# ---- Options, variables ----
# These version numbers are modified by tools/release.py
set(SIMDJSON_LIB_VERSION "33.0.0" CACHE STRING "simdjson library version")
set(SIMDJSON_LIB_SOVERSION "33" CACHE STRING "simdjson library soversion")
set(SIMDJSON_LIB_VERSION "31.0.0" CACHE STRING "simdjson library version")
set(SIMDJSON_LIB_SOVERSION "31" 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)
if(SIMDJSON_BUILD_STATIC_LIB AND NOT BUILD_SHARED_LIBS)
@@ -76,12 +76,9 @@ if(SIMDJSON_DEVELOPMENT_CHECKS)
endif()
if(is_top_project)
option(SIMDJSON_INSTALL "Enable target install" ON)
option(SIMDJSON_DEVELOPER_MODE "Enable targets for developing simdjson" OFF)
option(BUILD_SHARED_LIBS "Build simdjson as a shared library" OFF)
option(SIMDJSON_SINGLEHEADER "Disable singleheader generation" ON)
else()
option(SIMDJSON_INSTALL "Enable target install" ${BUILD_SHARED_LIBS})
endif()
include(cmake/handle-deprecations.cmake)
@@ -95,16 +92,13 @@ add_library(simdjson ${SIMDJSON_SOURCES})
add_library(simdjson::simdjson ALIAS simdjson)
set(SIMDJSON_LIBRARIES simdjson)
# Check for <bit> header compatibility
include(CheckIncludeFileCXX)
check_include_file_cxx(bit SIMDJSON_HAS_BIT_HEADER)
# Enable precompiled headers for faster builds
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.16")
set(SIMDJSON_PRECOMPILE_HEADERS
target_precompile_headers(simdjson PRIVATE
<algorithm>
<array>
<atomic>
<bit>
<cassert>
<cctype>
<cerrno>
@@ -117,12 +111,6 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.16")
<utility>
<vector>
)
if(SIMDJSON_HAS_BIT_HEADER)
list(APPEND SIMDJSON_PRECOMPILE_HEADERS <bit>)
endif()
target_precompile_headers(simdjson PRIVATE ${SIMDJSON_PRECOMPILE_HEADERS})
endif()
if(SIMDJSON_BUILD_STATIC_LIB)
@@ -228,89 +216,87 @@ endif()
# ---- Install rules ----
if(SIMDJSON_INSTALL)
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
if(SIMDJSON_SINGLEHEADER)
install(
FILES singleheader/simdjson.h
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
COMPONENT simdjson_Development
)
endif()
install(
TARGETS simdjson
EXPORT simdjsonTargets
RUNTIME COMPONENT simdjson_Runtime
LIBRARY COMPONENT simdjson_Runtime
NAMELINK_COMPONENT simdjson_Development
ARCHIVE COMPONENT simdjson_Development
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
configure_file(cmake/simdjson-config.cmake.in simdjson-config.cmake @ONLY)
write_basic_package_version_file(
simdjson-config-version.cmake
COMPATIBILITY SameMinorVersion
)
set(
SIMDJSON_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/simdjson"
CACHE STRING "CMake package config location relative to the install prefix"
)
mark_as_advanced(SIMDJSON_INSTALL_CMAKEDIR)
install(
FILES
"${PROJECT_BINARY_DIR}/simdjson-config.cmake"
"${PROJECT_BINARY_DIR}/simdjson-config-version.cmake"
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
COMPONENT simdjson_Development
)
install(
EXPORT simdjsonTargets
NAMESPACE simdjson::
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
COMPONENT simdjson_Development
)
if(SIMDJSON_BUILD_STATIC_LIB)
install(
TARGETS simdjson_static
EXPORT simdjson_staticTargets
ARCHIVE COMPONENT simdjson_Development
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
install(
EXPORT simdjson_staticTargets
NAMESPACE simdjson::
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
COMPONENT simdjson_Development
)
endif()
# pkg-config
include(cmake/JoinPaths.cmake)
join_paths(PKGCONFIG_INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
join_paths(PKGCONFIG_LIBDIR "\${prefix}" "${CMAKE_INSTALL_LIBDIR}")
if(SIMDJSON_ENABLE_THREADS)
set(PKGCONFIG_CFLAGS "-DSIMDJSON_THREADS_ENABLED=1")
if(CMAKE_THREAD_LIBS_INIT)
set(PKGCONFIG_LIBS_PRIVATE "Libs.private: ${CMAKE_THREAD_LIBS_INIT}")
endif()
endif()
configure_file("simdjson.pc.in" "simdjson.pc" @ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/simdjson.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)
if(SIMDJSON_SINGLEHEADER)
install(
FILES singleheader/simdjson.h
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
COMPONENT simdjson_Development
)
endif()
install(
TARGETS simdjson
EXPORT simdjsonTargets
RUNTIME COMPONENT simdjson_Runtime
LIBRARY COMPONENT simdjson_Runtime
NAMELINK_COMPONENT simdjson_Development
ARCHIVE COMPONENT simdjson_Development
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
configure_file(cmake/simdjson-config.cmake.in simdjson-config.cmake @ONLY)
write_basic_package_version_file(
simdjson-config-version.cmake
COMPATIBILITY SameMinorVersion
)
set(
SIMDJSON_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/simdjson"
CACHE STRING "CMake package config location relative to the install prefix"
)
mark_as_advanced(SIMDJSON_INSTALL_CMAKEDIR)
install(
FILES
"${PROJECT_BINARY_DIR}/simdjson-config.cmake"
"${PROJECT_BINARY_DIR}/simdjson-config-version.cmake"
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
COMPONENT simdjson_Development
)
install(
EXPORT simdjsonTargets
NAMESPACE simdjson::
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
COMPONENT simdjson_Development
)
if(SIMDJSON_BUILD_STATIC_LIB)
install(
TARGETS simdjson_static
EXPORT simdjson_staticTargets
ARCHIVE COMPONENT simdjson_Development
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
install(
EXPORT simdjson_staticTargets
NAMESPACE simdjson::
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
COMPONENT simdjson_Development
)
endif()
# pkg-config
include(cmake/JoinPaths.cmake)
join_paths(PKGCONFIG_INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
join_paths(PKGCONFIG_LIBDIR "\${prefix}" "${CMAKE_INSTALL_LIBDIR}")
if(SIMDJSON_ENABLE_THREADS)
set(PKGCONFIG_CFLAGS "-DSIMDJSON_THREADS_ENABLED=1")
if(CMAKE_THREAD_LIBS_INIT)
set(PKGCONFIG_LIBS_PRIVATE "Libs.private: ${CMAKE_THREAD_LIBS_INIT}")
endif()
endif()
configure_file("simdjson.pc.in" "simdjson.pc" @ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/simdjson.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)
#
# CPack
#
+1 -1
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = "4.6.4"
PROJECT_NUMBER = "4.4.2"
# 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
+1 -1
View File
@@ -171,7 +171,7 @@ We recommend Visual Studio 2019 or better on a 64-bit system.")
else()
target_compile_options(
simdjson-internal-flags INTERFACE
-Werror -Wall -Wextra -Weffc++ -Wsign-compare -Wshadow -Wwrite-strings
-Wall -Wextra -Weffc++ -Wsign-compare -Wshadow -Wwrite-strings
-Wpointer-arith -Winit-self -Wconversion -Wno-sign-conversion
)
if(CMAKE_CXX_STANDARD VERSION_GREATER_EQUAL 20)
+26 -23
View File
@@ -28,8 +28,6 @@ separate document](https://github.com/simdjson/simdjson/blob/master/doc/builder.
- [UTF-8 validation (alone)](#utf-8-validation-alone)
- [JSON Pointer](#json-pointer)
- [JSONPath](#jsonpath)
* [Using `for_each_at_path_with_wildcard` for JSONPath Queries (On-Demand)](#using-for_each_at_path_with_wildcard-for-jsonpath-queries-on-demand)
+ [Example Usage](#example-usage)
- [Compile-Time JSONPath and JSON Pointer (C++26 Reflection)](#compile-time-jsonpath-and-json-pointer-c26-reflection)
- [Error handling](#error-handling)
* [Error handling examples without exceptions](#error-handling-examples-without-exceptions)
@@ -438,7 +436,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
* **Extracting Values:** You can cast a JSON element to a native type:
`double(element)`. This works for `std::string_view`, double, uint64_t, int64_t, bool,
ondemand::object and ondemand::array. We also have explicit methods such as `get_string()`, `get_double()`,
`get_uint64()`, `get_int64()`, `get_uint32()`, `get_int32()`, `get_bool()`, `get_object()` and `get_array()`. After a cast or an explicit method,
`get_uint64()`, `get_int64()`, `get_bool()`, `get_object()` and `get_array()`. After a cast or an explicit method,
the number, string or boolean will be parsed, or the initial `{` or `[` will be verified for `ondemand::object` and `ondemand::array`. An exception may be thrown if
the cast is not possible: the error code is `simdjson::INCORRECT_TYPE` (see [Error handling](#error-handling)). Importantly, when getting an ondemand::object or ondemand::array instance, its content is
not validated: you are only guaranteed that the corresponding initial character (`{` or `[`) is present. Thus,
@@ -448,8 +446,8 @@ support for users who avoid exceptions. See [the simdjson error handling documen
pass `true` (`get_string(true)`) as a parameter to get replacement characters where errors
occur. If you somehow need to access non-UTF-8 strings in a lossless manner
(e.g., if you strings contain unpaired surrogates), you may use the `get_wobbly_string()` function to get a string in the [WTF-8 format](https://simonsapin.github.io/wtf-8).
When calling `get_uint64()`, `get_int64()`, `get_uint32()` or `get_int32()`, if the number does not fit in the
corresponding integer type, it is also considered an error (`NUMBER_OUT_OF_RANGE`). When parsing numbers or other scalar values, the library checks
When calling `get_uint64()` and `get_int64()`, if the number does not fit in a corresponding
64-bit integer type, it is also considered an error. When parsing numbers or other scalar values, the library checks
that the value is followed by an expected character, thus you *may* get a number parsing error when accessing the digits
as an integer in the following strings: `{"number":12332a`, `{"number":12332\0`, `{"number":12332` (the digits appear at the end). We always abide by the [RFC 8259](https://www.tbray.org/ongoing/When/201x/2017/12/14/rfc8259.html) JSON specification so that, for example, numbers prefixed by the `+` sign are in error.
@@ -1792,15 +1790,15 @@ int64_t x = obj.at_path("$.c.foo.a[1]"); // 20
x = obj.at_path("$.d.foo2.a.2"); // 30
```
## Using `for_each_at_path_with_wildcard` for JSONPath Queries (On-Demand)
## Using `at_path_with_wildcard` for JSONPath Queries (On-Demand)
The `for_each_at_path_with_wildcard` function in simdjson extends the JSONPath querying capabilities by supporting wildcard expressions (`*`) in JSON paths. It calls a user-provided callback for each matching element, avoiding the need to materialize all results into a vector. For example, you can use `$.address.*` to fetch all fields within the `address` object or `$.phoneNumbers[*].numbers[*]` to retrieve all phone numbers across multiple objects in an array.
The `at_path_with_wildcard` function in simdjson extends the JSONPath querying capabilities by supporting wildcard expressions (`*`) in JSON paths. This allows users to retrieve multiple elements from a JSON document in a single query. For example, you can use `$.address.*` to fetch all fields within the `address` object or `$.phoneNumbers[*].numbers[*]` to retrieve all phone numbers across multiple objects in an array.
The `*` wildcard matches all elements at a specific level. For instance, `$.address.*` retrieves all key-value pairs in the `address` object, while `$.*.streetAddress` fetches all `streetAddress` fields across objects at the root level. You can combine wildcards with array indexing. For example, `$.phoneNumbers[*].numbers[1]` retrieves the second number from each `numbers` array in the `phoneNumbers` array. If no elements match the wildcard query, the callback is simply never called. For instance, querying `$.empty_object.*` or `$.empty_array.*` will yield no callbacks.
The `*` wildcard matches all elements at a specific level. For instance, `$.address.*` retrieves all key-value pairs in the `address` object, while `$.*.streetAddress` fetches all `streetAddress` fields across objects at the root level. You can combine wildcards with array indexing. For example, `$.phoneNumbers[*].numbers[1]` retrieves the second number from each `numbers` array in the `phoneNumbers` array. If no elements match the wildcard query, the function returns an empty result. For instance, querying `$.empty_object.*` or `$.empty_array.*` will yield an empty set.
### Example Usage
Here is an example demonstrating the use of `for_each_at_path_with_wildcard`:
Here is an example demonstrating the use of `at_path_with_wildcard`:
```cpp
simdjson::padded_string json_string = R"(
@@ -1829,22 +1827,27 @@ ondemand::parser parser;
ondemand::document doc = parser.iterate(json_string);
// Fetch all fields in the address object
auto error = doc.for_each_at_path_with_wildcard("$.address.*",
[](ondemand::value value) {
std::string_view field;
if (value.get(field) == SUCCESS) {
std::cout << field << std::endl;
}
});
std::vector<ondemand::value> values;
auto error = doc.at_path_with_wildcard("$.address.*").get(values);
if (!error) {
for (auto value : values) {
std::string_view field;
if (value.get(field) == SUCCESS) {
std::cout << field << std::endl;
}
}
}
// Fetch all phone numbers
doc.for_each_at_path_with_wildcard("$.phoneNumbers[*].numbers[*]",
[](ondemand::value value) {
std::string_view number;
if (value.get(number) == SUCCESS) {
std::cout << number << std::endl;
}
});
error = doc.at_path_with_wildcard("$.phoneNumbers[*].numbers[*]").get(values);
if (!error) {
for (auto value : values) {
std::string_view number;
if (value.get(number) == SUCCESS) {
std::cout << number << std::endl;
}
}
}
```
This function is particularly useful for extracting data from complex JSON structures with nested arrays and objects. By leveraging wildcards, you can simplify your queries and reduce the need for multiple iterations.
+1 -18
View File
@@ -168,23 +168,6 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper
`SIMDJSON_MINUS_ZERO_AS_FLOAT` to `1` when building simdjson, you can get that `-0` is mapped to `-0.0`
as in JavaScript. You can get the desired effect by building simdjson with cmake setting the
`SIMDJSON_MINUS_ZERO_AS_FLOAT` to on: `cmake -B build -D SIMDJSON_MINUS_ZERO_AS_FLOAT=ON`.
* **Big Integer Support (opt-in):** By default, integers that exceed the 64-bit range cause parsing to fail with `BIGINT_ERROR`. You can opt in to big integer support so that these numbers are stored as raw digit strings on the tape instead:
```cpp
simdjson::dom::parser parser;
parser.number_as_string(true); // opt-in, default false
simdjson::dom::element doc;
auto error = parser.parse("[1, 123456789012345678901]"_padded).get(doc);
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
for (simdjson::dom::element elem : doc) {
if (elem.is_bigint()) {
std::string_view digits;
error = elem.get_bigint().get(digits);
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
std::cout << "big integer: " << digits << std::endl;
}
}
```
When enabled, big integers have type `element_type::BIGINT`. Calling `get_int64()`, `get_uint64()`, or `get_double()` on a big integer returns `INCORRECT_TYPE`. Normal numbers (int64, uint64, double) are unaffected.
* **Field Access:** To get the value of the "foo" field in an object, use `object["foo"]`.
* **Array Iteration:** To iterate through an array, use `for (auto value : array) { ... }`. If you
know the type of the value, you can cast it right there, too! `for (double value : array) { ... }`
@@ -197,7 +180,7 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper
* **Array and Object size** Given an array or an object, you can get its size (number of elements or keys)
with the `size()` method.
* **Checking an Element Type:** You can check an element's type with `element.type()`. It
returns an `element_type` with values such as `simdjson::dom::element_type::ARRAY`, `simdjson::dom::element_type::OBJECT`, `simdjson::dom::element_type::INT64`, `simdjson::dom::element_type::UINT64`,`simdjson::dom::element_type::DOUBLE`, `simdjson::dom::element_type::STRING`, `simdjson::dom::element_type::BOOL`, `simdjson::dom::element_type::NULL_VALUE` or, `simdjson::dom::element_type::BIGINT` (when big integer support is enabled).
returns an `element_type` with values such as `simdjson::dom::element_type::ARRAY`, `simdjson::dom::element_type::OBJECT`, `simdjson::dom::element_type::INT64`, `simdjson::dom::element_type::UINT64`,`simdjson::dom::element_type::DOUBLE`, `simdjson::dom::element_type::STRING`, `simdjson::dom::element_type::BOOL` or, `simdjson::dom::element_type::NULL_VALUE`.
* **Output to streams and strings:** Given a document or an element (or node) out of a JSON document, you can output a minified string version using the C++ stream idiom (`out << element`). You can also request the construction of a minified string version (`simdjson::minify(element)`) or a prettified string version (`simdjson::prettify(element)`). Numbers are serialized as 64-bit floating-point numbers (`double`).
### Examples
-8
View File
@@ -93,14 +93,6 @@ Float values are represented as two 64-bit tape elements:
Performance consideration: We store numbers of the main tape because we believe that locality of reference is helpful for performance.
## Big Integers
When a JSON integer exceeds the 64-bit range (both signed and unsigned), it is classified as a big integer. By default, parsing returns `BIGINT_ERROR`. When `parser.number_as_string(true)` is set, the raw digits are stored on the string tape using the same format as strings (4-byte little-endian length prefix, followed by the UTF-8 digit bytes, followed by a null terminator).
A big integer is represented on the main tape as the 64-bit tape element `('Z' << 56) + x` where the payload `x` is the location on the string tape of the null-terminated digit string.
For example, the JSON value `99999999999999999999` would be stored as the string `"99999999999999999999"` on the string tape, with a `'Z'` tag on the main tape. Negative big integers include the leading minus sign.
## Root node
Each JSON document will have two special 64-bit tape elements representing a root node, one at the beginning and one at the end.
@@ -2,13 +2,6 @@
function(add_quickstart_test TEST_NAME SOURCE_FILE)
cmake_parse_arguments(PARSE_ARGV 2 ARGS "NO_EXCEPTIONS;NATIVE_ARCH" "" "CXX_STANDARD;LABELS")
# Standard compiler flags
if (MSVC)
list(APPEND QUICKSTART_FLAGS /WX)
else()
list(APPEND QUICKSTART_FLAGS -Werror)
endif()
# Native architecture compiler flag
if (ARGS_NATIVE_ARCH)
if (MSVC)
-3
View File
@@ -54,9 +54,6 @@ static void print_json(std::ostream& os, simdjson::dom::element element) noexcep
case simdjson::dom::element_type::NULL_VALUE:
os << "null" << endl;
break;
case simdjson::dom::element_type::BIGINT:
os << element.get_bigint().value_unsafe() << endl;
break;
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
-9
View File
@@ -141,15 +141,6 @@ inline bool document::dump_raw_tape(std::ostream &os) const noexcept {
case 'r': // we start and end with the root node
// should we be hitting the root node?
return false;
case 'Z': // we have a big integer
os << "bigint ";
std::memcpy(&string_length, string_buf.get() + payload, sizeof(uint32_t));
os << std::string_view(
reinterpret_cast<const char *>(string_buf.get() + payload + sizeof(uint32_t)),
string_length
);
os << '\n';
break;
default:
return false;
}
-22
View File
@@ -81,10 +81,6 @@ simdjson_inline simdjson_result<bool> simdjson_result<dom::element>::get_bool()
if (error()) { return error(); }
return first.get_bool();
}
simdjson_inline simdjson_result<std::string_view> simdjson_result<dom::element>::get_bigint() const noexcept {
if (error()) { return error(); }
return first.get_bigint();
}
simdjson_inline bool simdjson_result<dom::element>::is_array() const noexcept {
return !error() && first.is_array();
@@ -114,9 +110,6 @@ simdjson_inline bool simdjson_result<dom::element>::is_bool() const noexcept {
simdjson_inline bool simdjson_result<dom::element>::is_null() const noexcept {
return !error() && first.is_null();
}
simdjson_inline bool simdjson_result<dom::element>::is_bigint() const noexcept {
return !error() && first.is_bigint();
}
simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](std::string_view key) const noexcept {
if (error()) { return error(); }
@@ -225,15 +218,6 @@ inline simdjson_result<bool> element::get_bool() const noexcept {
}
return INCORRECT_TYPE;
}
inline simdjson_result<std::string_view> element::get_bigint() const noexcept {
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
switch (tape.tape_ref_type()) {
case internal::tape_type::BIGINT:
return tape.get_string_view();
default:
return INCORRECT_TYPE;
}
}
inline simdjson_result<const char *> element::get_c_str() const noexcept {
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
switch (tape.tape_ref_type()) {
@@ -376,10 +360,6 @@ inline bool element::is_null() const noexcept {
return tape.is_null_on_tape();
}
inline bool element::is_bigint() const noexcept {
return tape.tape_ref_type() == internal::tape_type::BIGINT;
}
#if SIMDJSON_EXCEPTIONS
inline element::operator bool() const noexcept(false) { return get<bool>(); }
@@ -512,8 +492,6 @@ inline std::ostream& operator<<(std::ostream& out, element_type type) {
return out << "bool";
case element_type::NULL_VALUE:
return out << "null";
case element_type::BIGINT:
return out << "bigint";
default:
return out << "unexpected content!!!"; // abort() usage is forbidden in the library
}
+1 -17
View File
@@ -21,8 +21,7 @@ enum class element_type {
DOUBLE = 'd', ///< double: Any number with a "." or "e" that fits in double.
STRING = '"', ///< std::string_view
BOOL = 't', ///< bool
NULL_VALUE = 'n', ///< null
BIGINT = 'Z' ///< std::string_view: big integer stored as raw digit string
NULL_VALUE = 'n' ///< null
};
/**
@@ -121,14 +120,6 @@ public:
*/
inline simdjson_result<bool> get_bool() const noexcept;
/**
* Read this element as a big integer (raw digit string).
*
* @returns A string_view of the raw digits, or:
* INCORRECT_TYPE if the JSON element is not a big integer.
*/
inline simdjson_result<std::string_view> get_bigint() const noexcept;
/**
* Whether this element is a json array.
*
@@ -184,11 +175,6 @@ public:
*/
inline bool is_null() const noexcept;
/**
* Whether this element is a big integer (number exceeding 64-bit range).
*/
inline bool is_bigint() const noexcept;
/**
* Tell whether the value can be cast to provided type (T).
*
@@ -547,7 +533,6 @@ public:
simdjson_inline simdjson_result<uint64_t> get_uint64() const noexcept;
simdjson_inline simdjson_result<double> get_double() const noexcept;
simdjson_inline simdjson_result<bool> get_bool() const noexcept;
simdjson_inline simdjson_result<std::string_view> get_bigint() const noexcept;
simdjson_inline bool is_array() const noexcept;
simdjson_inline bool is_object() const noexcept;
@@ -558,7 +543,6 @@ public:
simdjson_inline bool is_number() const noexcept;
simdjson_inline bool is_bool() const noexcept;
simdjson_inline bool is_null() const noexcept;
simdjson_inline bool is_bigint() 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;
+1 -3
View File
@@ -36,11 +36,10 @@ inline bool parser::dump_raw_tape(std::ostream &os) const noexcept {
}
inline simdjson_result<size_t> parser::read_file(std::string_view path) noexcept {
const std::string path_copy(path);
// Open the file
SIMDJSON_PUSH_DISABLE_WARNINGS
SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe
std::FILE *fp = std::fopen(path_copy.c_str(), "rb");
std::FILE *fp = std::fopen(path.data(), "rb");
SIMDJSON_POP_DISABLE_WARNINGS
if (fp == nullptr) {
@@ -133,7 +132,6 @@ inline simdjson_result<element> parser::parse_into_document(document& provided_d
buf += 3;
len -= 3;
}
implementation->_number_as_string = _number_as_string;
_error = implementation->parse(buf, len, provided_doc);
if (_error) { return _error; }
-10
View File
@@ -610,13 +610,6 @@ public:
inline bool dump_raw_tape(std::ostream &os) const noexcept;
/**
* When enabled, big integers (exceeding uint64 range) are stored as strings
* in the tape instead of returning BIGINT_ERROR. Default: false.
*/
inline void number_as_string(bool enabled) noexcept { _number_as_string = enabled; }
inline bool number_as_string() const noexcept { return _number_as_string; }
private:
/**
* The maximum document length this parser will automatically support.
@@ -625,9 +618,6 @@ private:
*/
size_t _max_capacity;
/** Whether to store big integers as strings instead of returning BIGINT_ERROR */
bool _number_as_string{false};
/**
* The loaded buffer (reused each time load() is called)
*/
-6
View File
@@ -460,12 +460,6 @@ inline void string_builder<serializer>::append(simdjson::dom::element value) {
case tape_type::STRING:
format.string(iter.get_string_view());
break;
case tape_type::BIGINT: {
// Big integer stored as string — output raw digits (no quotes)
auto sv = iter.get_string_view();
format.chars(sv.data(), sv.data() + sv.size());
break;
}
case tape_type::INT64:
format.number(iter.next_tape_value<int64_t>());
iter.json_index++; // numbers take up 2 spots, so we need to increment
@@ -1,6 +1,5 @@
#include <array>
#include <cstring>
#include <limits>
#include <type_traits>
#ifndef SIMDJSON_GENERIC_STRING_BUILDER_INL_H
@@ -756,11 +755,6 @@ simdjson_inline void string_builder::append(number_type v) noexcept {
simdjson_inline void
string_builder::escape_and_append(std::string_view input) noexcept {
// escaping might turn a control character into \x00xx so 6 characters.
// Guard against size_t overflow in the multiplication below.
if (input.size() > (std::numeric_limits<size_t>::max)() / 6) {
set_valid(false);
return;
}
if (capacity_check(6 * input.size())) {
position += write_string_escaped(input, buffer.get() + position);
}
@@ -769,11 +763,6 @@ string_builder::escape_and_append(std::string_view input) noexcept {
simdjson_inline void
string_builder::escape_and_append_with_quotes(std::string_view input) noexcept {
// escaping might turn a control character into \x00xx so 6 characters.
// Guard against size_t overflow in the arithmetic below.
if (input.size() > ((std::numeric_limits<size_t>::max)() - 2) / 6) {
set_valid(false);
return;
}
if (capacity_check(2 + 6 * input.size())) {
buffer.get()[position++] = '"';
position += write_string_escaped(input, buffer.get() + position);
+44 -35
View File
@@ -170,34 +170,46 @@ inline simdjson_result<value> array::at_path(std::string_view json_path) noexcep
return at_pointer(json_pointer);
}
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, value>
#else
template <typename Func>
#endif
inline error_code array::for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept {
inline simdjson_result<std::vector<value>> array::at_path_with_wildcard(std::string_view json_path) noexcept {
std::vector<value> result;
auto result_pair = get_next_key_and_json_path(json_path);
std::string_view key = result_pair.first;
std::string_view remaining_path = result_pair.second;
// Wildcard case
if (key=="*"){
for(auto element: *this) {
value val;
SIMDJSON_TRY(element.get(val));
if (remaining_path.empty()) {
callback(val);
} else {
error_code err = element.for_each_at_path_with_wildcard(remaining_path, callback);
if(err) { return err; }
if(key=="*"){
for(auto element: *this){
if(element.error()){
return element.error();
}
if(remaining_path.empty()){
// Use value_unsafe() because we've already checked for errors above.
// The 'element' is a simdjson_result<value> wrapper, and we need to extract
// the underlying value. value_unsafe() is safe here because error() returned false.
result.push_back(std::move(element).value_unsafe());
}else{
auto nested_result = element.at_path_with_wildcard(remaining_path);
if(nested_result.error()){
return nested_result.error();
}
// Same logic as above.
std::vector<value> nested_matches = std::move(nested_result).value_unsafe();
result.insert(result.end(),
std::make_move_iterator(nested_matches.begin()),
std::make_move_iterator(nested_matches.end()));
}
}
return SUCCESS;
} else {
return result;
}else{
// Specific index case in which we access the element at the given index
size_t idx = 0;
size_t idx=0;
for (char c : key) {
for(char c:key){
if(c < '0' || c > '9'){
return INVALID_JSON_POINTER;
}
@@ -205,13 +217,16 @@ inline error_code array::for_each_at_path_with_wildcard(std::string_view json_pa
}
auto element = at(idx);
value val;
SIMDJSON_TRY(element.get(val));
if (remaining_path.empty()){
callback(val);
return SUCCESS;
} else {
return element.for_each_at_path_with_wildcard(remaining_path, callback);
if(element.error()){
return element.error();
}
if(remaining_path.empty()){
result.push_back(std::move(element).value_unsafe());
return result;
}else{
return element.at_path_with_wildcard(remaining_path);
}
}
}
@@ -274,15 +289,9 @@ simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdj
if (error()) { return error(); }
return first.at_path(json_path);
}
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, SIMDJSON_IMPLEMENTATION::ondemand::value>
#else
template <typename Func>
#endif
simdjson_inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array>::for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept {
simdjson_inline simdjson_result<std::vector<SIMDJSON_IMPLEMENTATION::ondemand::value>> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array>::at_path_with_wildcard(std::string_view json_path) noexcept {
if (error()) { return error(); }
return first.for_each_at_path_with_wildcard(json_path, std::forward<Func>(callback));
return first.at_path_with_wildcard(json_path);
}
simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array>::raw_json() noexcept {
if (error()) { return error(); }
+4 -18
View File
@@ -119,21 +119,13 @@ public:
inline simdjson_result<value> at_path(std::string_view json_path) noexcept;
/**
* Call the provided callback for each value matching the given JSONPath
* expression with wildcard support.
* Get all values matching the given JSONPath expression with wildcard support.
* Supports wildcard patterns like "[*]" to match all array elements.
*
* @param json_path JSONPath expression with wildcards
* @param callback Function called for each matching value
* @return error_code indicating success or failure
* @return Vector of values matching the wildcard pattern
*/
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, value>
#else
template <typename Func>
#endif
inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
inline simdjson_result<std::vector<value>> at_path_with_wildcard(std::string_view json_path) noexcept;
/**
* Consumes the array and returns a string_view instance corresponding to the
@@ -257,13 +249,7 @@ public:
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at(size_t index) noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_pointer(std::string_view json_pointer) noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_path(std::string_view json_path) noexcept;
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, SIMDJSON_IMPLEMENTATION::ondemand::value>
#else
template <typename Func>
#endif
simdjson_inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
simdjson_inline simdjson_result<std::vector<SIMDJSON_IMPLEMENTATION::ondemand::value>> at_path_with_wildcard(std::string_view json_path) noexcept;
simdjson_inline simdjson_result<std::string_view> raw_json() noexcept;
#if SIMDJSON_SUPPORTS_CONCEPTS
// TODO: move this code into object-inl.h
@@ -16,8 +16,6 @@
#include "simdjson/generic/ondemand/deserialize.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#include <limits>
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
namespace ondemand {
@@ -133,18 +131,6 @@ simdjson_inline simdjson_result<int64_t> document::get_int64() noexcept {
simdjson_inline simdjson_result<int64_t> document::get_int64_in_string() noexcept {
return get_root_value_iterator().get_root_int64_in_string(true);
}
simdjson_inline simdjson_result<uint32_t> document::get_uint32() noexcept {
uint64_t result;
SIMDJSON_TRY(get_uint64().get(result));
if (result > (std::numeric_limits<uint32_t>::max)()) { return NUMBER_OUT_OF_RANGE; }
return static_cast<uint32_t>(result);
}
simdjson_inline simdjson_result<int32_t> document::get_int32() noexcept {
int64_t result;
SIMDJSON_TRY(get_int64().get(result));
if (result > (std::numeric_limits<int32_t>::max)() || result < (std::numeric_limits<int32_t>::min)()) { return NUMBER_OUT_OF_RANGE; }
return static_cast<int32_t>(result);
}
simdjson_inline simdjson_result<double> document::get_double() noexcept {
return get_root_value_iterator().get_root_double(true);
}
@@ -178,8 +164,6 @@ template<> simdjson_inline simdjson_result<std::string_view> document::get() & n
template<> simdjson_inline simdjson_result<double> document::get() & noexcept { return get_double(); }
template<> simdjson_inline simdjson_result<uint64_t> document::get() & noexcept { return get_uint64(); }
template<> simdjson_inline simdjson_result<int64_t> document::get() & noexcept { return get_int64(); }
template<> simdjson_inline simdjson_result<uint32_t> document::get() & noexcept { return get_uint32(); }
template<> simdjson_inline simdjson_result<int32_t> document::get() & noexcept { return get_int32(); }
template<> simdjson_inline simdjson_result<bool> document::get() & noexcept { return get_bool(); }
template<> simdjson_inline simdjson_result<value> document::get() & noexcept { return get_value(); }
@@ -190,8 +174,6 @@ template<> simdjson_warn_unused simdjson_inline error_code document::get(std::st
template<> simdjson_warn_unused simdjson_inline error_code document::get(double& out) & noexcept { return get_double().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code document::get(uint64_t& out) & noexcept { return get_uint64().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code document::get(int64_t& out) & noexcept { return get_int64().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code document::get(uint32_t& out) & noexcept { return get_uint32().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code document::get(int32_t& out) & noexcept { return get_int32().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code document::get(bool& out) & noexcept { return get_bool().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code document::get(value& out) & noexcept { return get_value().get(out); }
@@ -365,14 +347,8 @@ simdjson_inline simdjson_result<value> document::at_path(std::string_view json_p
}
}
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, value>
#else
template <typename Func>
#endif
simdjson_inline error_code document::for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept {
rewind(); // Rewind the document each time for_each_at_path_with_wildcard is called
simdjson_inline simdjson_result<std::vector<value>> document::at_path_with_wildcard(std::string_view json_path) noexcept {
rewind(); // Rewind the document each time at_path_with_wildcard is called
if (json_path.empty()) {
return INVALID_JSON_POINTER;
}
@@ -380,9 +356,9 @@ simdjson_inline error_code document::for_each_at_path_with_wildcard(std::string_
SIMDJSON_TRY(type().get(t));
switch (t) {
case json_type::array:
return (*this).get_array().for_each_at_path_with_wildcard(json_path, std::forward<Func>(callback));
return (*this).get_array().at_path_with_wildcard(json_path);
case json_type::object:
return (*this).get_object().for_each_at_path_with_wildcard(json_path, std::forward<Func>(callback));
return (*this).get_object().at_path_with_wildcard(json_path);
default:
return INVALID_JSON_POINTER;
}
@@ -528,14 +504,6 @@ simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_IMPLEMENTATION
if (error()) { return error(); }
return first.get_int64_in_string();
}
simdjson_inline simdjson_result<uint32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_uint32() noexcept {
if (error()) { return error(); }
return first.get_uint32();
}
simdjson_inline simdjson_result<int32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_int32() noexcept {
if (error()) { return error(); }
return first.get_int32();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_double() noexcept {
if (error()) { return error(); }
return first.get_double();
@@ -719,15 +687,9 @@ simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjs
return first.at_path(json_path);
}
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, SIMDJSON_IMPLEMENTATION::ondemand::value>
#else
template <typename Func>
#endif
simdjson_inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept {
simdjson_inline simdjson_result<std::vector<SIMDJSON_IMPLEMENTATION::ondemand::value>> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::at_path_with_wildcard(std::string_view json_path) noexcept {
if (error()) { return error(); }
return first.for_each_at_path_with_wildcard(json_path, std::forward<Func>(callback));
return first.at_path_with_wildcard(json_path);
}
#if SIMDJSON_STATIC_REFLECTION
@@ -769,18 +731,6 @@ simdjson_inline simdjson_result<uint64_t> document_reference::get_uint64() noexc
simdjson_inline simdjson_result<uint64_t> document_reference::get_uint64_in_string() noexcept { return doc->get_root_value_iterator().get_root_uint64_in_string(false); }
simdjson_inline simdjson_result<int64_t> document_reference::get_int64() noexcept { return doc->get_root_value_iterator().get_root_int64(false); }
simdjson_inline simdjson_result<int64_t> document_reference::get_int64_in_string() noexcept { return doc->get_root_value_iterator().get_root_int64_in_string(false); }
simdjson_inline simdjson_result<uint32_t> document_reference::get_uint32() noexcept {
uint64_t result;
SIMDJSON_TRY(doc->get_root_value_iterator().get_root_uint64(false).get(result));
if (result > (std::numeric_limits<uint32_t>::max)()) { return NUMBER_OUT_OF_RANGE; }
return static_cast<uint32_t>(result);
}
simdjson_inline simdjson_result<int32_t> document_reference::get_int32() noexcept {
int64_t result;
SIMDJSON_TRY(doc->get_root_value_iterator().get_root_int64(false).get(result));
if (result > (std::numeric_limits<int32_t>::max)() || result < (std::numeric_limits<int32_t>::min)()) { return NUMBER_OUT_OF_RANGE; }
return static_cast<int32_t>(result);
}
simdjson_inline simdjson_result<double> document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); }
simdjson_inline simdjson_result<double> document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); }
simdjson_inline simdjson_result<std::string_view> document_reference::get_string(bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(false, allow_replacement); }
@@ -798,8 +748,6 @@ template<> simdjson_inline simdjson_result<std::string_view> document_reference:
template<> simdjson_inline simdjson_result<double> document_reference::get() & noexcept { return get_double(); }
template<> simdjson_inline simdjson_result<uint64_t> document_reference::get() & noexcept { return get_uint64(); }
template<> simdjson_inline simdjson_result<int64_t> document_reference::get() & noexcept { return get_int64(); }
template<> simdjson_inline simdjson_result<uint32_t> document_reference::get() & noexcept { return get_uint32(); }
template<> simdjson_inline simdjson_result<int32_t> document_reference::get() & noexcept { return get_int32(); }
template<> simdjson_inline simdjson_result<bool> document_reference::get() & noexcept { return get_bool(); }
template<> simdjson_inline simdjson_result<value> document_reference::get() & noexcept { return get_value(); }
#if SIMDJSON_EXCEPTIONS
@@ -838,13 +786,7 @@ simdjson_inline simdjson_result<number> document_reference::get_number() noexcep
simdjson_inline simdjson_result<std::string_view> document_reference::raw_json_token() noexcept { return doc->raw_json_token(); }
simdjson_inline simdjson_result<value> document_reference::at_pointer(std::string_view json_pointer) noexcept { return doc->at_pointer(json_pointer); }
simdjson_inline simdjson_result<value> document_reference::at_path(std::string_view json_path) noexcept { return doc->at_path(json_path); }
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, value>
#else
template <typename Func>
#endif
simdjson_inline error_code document_reference::for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept { return doc->for_each_at_path_with_wildcard(json_path, std::forward<Func>(callback)); }
simdjson_inline simdjson_result<std::vector<value>> document_reference::at_path_with_wildcard(std::string_view json_path) noexcept { return doc->at_path_with_wildcard(json_path); }
simdjson_inline simdjson_result<std::string_view> document_reference::raw_json() noexcept { return doc->raw_json();}
simdjson_inline document_reference::operator document&() const noexcept { return *doc; }
#if SIMDJSON_SUPPORTS_CONCEPTS && SIMDJSON_STATIC_REFLECTION
@@ -937,14 +879,6 @@ simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_IMPLEMENTATION
if (error()) { return error(); }
return first.get_int64_in_string();
}
simdjson_inline simdjson_result<uint32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_uint32() noexcept {
if (error()) { return error(); }
return first.get_uint32();
}
simdjson_inline simdjson_result<int32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_int32() noexcept {
if (error()) { return error(); }
return first.get_int32();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_double() noexcept {
if (error()) { return error(); }
return first.get_double();
@@ -1109,17 +1043,11 @@ simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjs
}
return first.at_path(json_path);
}
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, SIMDJSON_IMPLEMENTATION::ondemand::value>
#else
template <typename Func>
#endif
simdjson_inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept {
simdjson_inline simdjson_result<std::vector<SIMDJSON_IMPLEMENTATION::ondemand::value>> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::at_path_with_wildcard(std::string_view json_path) noexcept {
if (error()) {
return error();
}
return first.for_each_at_path_with_wildcard(json_path, std::forward<Func>(callback));
return first.at_path_with_wildcard(json_path);
}
#if SIMDJSON_STATIC_REFLECTION
template<constevalutil::fixed_string... FieldNames, typename T>
+11 -58
View File
@@ -76,26 +76,6 @@ public:
* @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer.
*/
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
/**
* Cast this JSON value to a 32-bit unsigned integer.
*
* Calls get_uint64() and checks that the result fits in a uint32_t.
*
* @returns A 32-bit unsigned integer.
* @returns INCORRECT_TYPE If the JSON value is not an unsigned integer.
* @returns NUMBER_OUT_OF_RANGE If the value does not fit in a uint32_t.
*/
simdjson_inline simdjson_result<uint32_t> get_uint32() noexcept;
/**
* Cast this JSON value to a 32-bit signed integer.
*
* Calls get_int64() and checks that the result fits in an int32_t.
*
* @returns A 32-bit signed integer.
* @returns INCORRECT_TYPE If the JSON value is not an integer.
* @returns NUMBER_OUT_OF_RANGE If the value does not fit in an int32_t.
*/
simdjson_inline simdjson_result<int32_t> get_int32() noexcept;
/**
* Cast this JSON value to a double.
*
@@ -744,24 +724,21 @@ public:
simdjson_inline simdjson_result<value> at_path(std::string_view json_path) noexcept;
/**
* Call the provided callback for each value matching the given JSONPath
* expression with wildcard support.
* Get all values matching the given JSONPath expression with wildcard support.
*
* Supports wildcard patterns like "$.array[*]" or "$.object.*" to match multiple elements.
*
* This method materializes all matching values into a vector.
* The document will be consumed after this call.
*
* @param json_path JSONPath expression with wildcards
* @param callback Function called for each matching value
* @return error_code indicating success or failure
* @return Vector of values matching the wildcard pattern, or:
* - INVALID_JSON_POINTER if the JSONPath cannot be parsed
* - NO_SUCH_FIELD if a field does not exist
* - INDEX_OUT_OF_BOUNDS if an array index is out of bounds
* - INCORRECT_TYPE if path traversal encounters wrong type
*/
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, value>
#else
template <typename Func>
#endif
simdjson_inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
simdjson_inline simdjson_result<std::vector<value>> at_path_with_wildcard(std::string_view json_path) noexcept;
/**
* Consumes the document and returns a string_view instance corresponding to the
@@ -852,8 +829,6 @@ public:
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<uint32_t> get_uint32() noexcept;
simdjson_inline simdjson_result<int32_t> get_int32() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
@@ -982,13 +957,7 @@ public:
simdjson_inline simdjson_result<std::string_view> raw_json_token() noexcept;
simdjson_inline simdjson_result<value> at_pointer(std::string_view json_pointer) noexcept;
simdjson_inline simdjson_result<value> at_path(std::string_view json_path) noexcept;
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, value>
#else
template <typename Func>
#endif
simdjson_inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
simdjson_inline simdjson_result<std::vector<value>> at_path_with_wildcard(std::string_view json_path) noexcept;
private:
document *doc{nullptr};
@@ -1013,8 +982,6 @@ public:
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<uint32_t> get_uint32() noexcept;
simdjson_inline simdjson_result<int32_t> get_int32() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
@@ -1074,13 +1041,7 @@ public:
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_pointer(std::string_view json_pointer) noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_path(std::string_view json_path) noexcept;
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, SIMDJSON_IMPLEMENTATION::ondemand::value>
#else
template <typename Func>
#endif
simdjson_inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
simdjson_inline simdjson_result<std::vector<SIMDJSON_IMPLEMENTATION::ondemand::value>> at_path_with_wildcard(std::string_view json_path) noexcept;
#if SIMDJSON_STATIC_REFLECTION
template<constevalutil::fixed_string... FieldNames, typename T>
requires(std::is_class_v<T> && (sizeof...(FieldNames) > 0))
@@ -1108,8 +1069,6 @@ public:
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<uint32_t> get_uint32() noexcept;
simdjson_inline simdjson_result<int32_t> get_int32() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
@@ -1165,13 +1124,7 @@ public:
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_pointer(std::string_view json_pointer) noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_path(std::string_view json_path) noexcept;
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, SIMDJSON_IMPLEMENTATION::ondemand::value>
#else
template <typename Func>
#endif
simdjson_inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
simdjson_inline simdjson_result<std::vector<SIMDJSON_IMPLEMENTATION::ondemand::value>> at_path_with_wildcard(std::string_view json_path) noexcept;
#if SIMDJSON_STATIC_REFLECTION
template<constevalutil::fixed_string... FieldNames, typename T>
requires(std::is_class_v<T> && (sizeof...(FieldNames) > 0))
+23 -21
View File
@@ -177,13 +177,9 @@ inline simdjson_result<value> object::at_path(std::string_view json_path) noexce
return at_pointer(json_pointer);
}
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, value>
#else
template <typename Func>
#endif
inline error_code object::for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept {
inline simdjson_result<std::vector<value>> object::at_path_with_wildcard(std::string_view json_path) noexcept {
std::vector<value> result;
auto result_pair = get_next_key_and_json_path(json_path);
std::string_view key = result_pair.first;
std::string_view remaining_path = result_pair.second;
@@ -193,22 +189,34 @@ inline error_code object::for_each_at_path_with_wildcard(std::string_view json_p
for (auto field : *this) {
value val;
SIMDJSON_TRY(field.value().get(val));
if (remaining_path.empty()) {
callback(val);
result.push_back(std::move(val));
} else {
SIMDJSON_TRY(val.for_each_at_path_with_wildcard(remaining_path, callback));
auto nested_result = val.at_path_with_wildcard(remaining_path);
if (nested_result.error()) {
return nested_result.error();
}
// Extract and append all nested matches to our result
std::vector<value> nested_vec;
SIMDJSON_TRY(std::move(nested_result).get(nested_vec));
result.insert(result.end(),
std::make_move_iterator(nested_vec.begin()),
std::make_move_iterator(nested_vec.end()));
}
}
return SUCCESS;
return result;
} else {
value val;
SIMDJSON_TRY(find_field(key).get(val));
if (remaining_path.empty()) {
callback(val);
return SUCCESS;
result.push_back(std::move(val));
return result;
} else {
return val.for_each_at_path_with_wildcard(remaining_path, callback);
return val.at_path_with_wildcard(remaining_path);
}
}
}
@@ -339,15 +347,9 @@ simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjs
return first.at_path(json_path);
}
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, SIMDJSON_IMPLEMENTATION::ondemand::value>
#else
template <typename Func>
#endif
simdjson_inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept {
simdjson_inline simdjson_result<std::vector<SIMDJSON_IMPLEMENTATION::ondemand::value>> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::at_path_with_wildcard(std::string_view json_path) noexcept {
if (error()) { return error(); }
return first.for_each_at_path_with_wildcard(json_path, std::forward<Func>(callback));
return first.at_path_with_wildcard(json_path);
}
inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::reset() noexcept {
+4 -18
View File
@@ -172,21 +172,13 @@ public:
inline simdjson_result<value> at_path(std::string_view json_path) noexcept;
/**
* Call the provided callback for each value matching the given JSONPath
* expression with wildcard support.
* Get all values matching the given JSONPath expression with wildcard support.
* Supports wildcard patterns like ".*" to match all object fields.
*
* @param json_path JSONPath expression with wildcards
* @param callback Function called for each matching value
* @return error_code indicating success or failure
* @return Vector of values matching the wildcard pattern
*/
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, value>
#else
template <typename Func>
#endif
inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
inline simdjson_result<std::vector<value>> at_path_with_wildcard(std::string_view json_path) noexcept;
/**
* Reset the iterator so that we are pointing back at the
@@ -336,13 +328,7 @@ public:
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) && noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_pointer(std::string_view json_pointer) noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_path(std::string_view json_path) noexcept;
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, SIMDJSON_IMPLEMENTATION::ondemand::value>
#else
template <typename Func>
#endif
simdjson_inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
simdjson_inline simdjson_result<std::vector<SIMDJSON_IMPLEMENTATION::ondemand::value>> at_path_with_wildcard(std::string_view json_path) noexcept;
inline simdjson_result<bool> reset() noexcept;
inline simdjson_result<bool> is_empty() noexcept;
inline simdjson_result<size_t> count_fields() & noexcept;
@@ -172,7 +172,7 @@ simdjson_pure simdjson_inline size_t parser::max_depth() const noexcept {
}
simdjson_inline void parser::set_max_capacity(size_t max_capacity) noexcept {
if(max_capacity > dom::MINIMAL_DOCUMENT_CAPACITY) {
if(max_capacity < dom::MINIMAL_DOCUMENT_CAPACITY) {
_max_capacity = max_capacity;
} else {
_max_capacity = dom::MINIMAL_DOCUMENT_CAPACITY;
@@ -199,7 +199,7 @@ simdjson_inline simdjson_warn_unused ondemand::parser& parser::get_parser() {
return *parser::get_parser_instance();
}
simdjson_inline bool parser::release_parser() {
simdjson_inline bool release_parser() {
auto &parser_instance = parser::get_threadlocal_parser_if_exists();
if (parser_instance) {
parser_instance.reset();
@@ -388,6 +388,8 @@ public:
static simdjson_inline bool release_parser();
private:
friend bool release_parser();
friend ondemand::parser& get_parser();
/** Get the thread-local parser instance, allocates it if needed */
static simdjson_inline simdjson_warn_unused std::unique_ptr<ondemand::parser>& get_parser_instance();
/** Get the thread-local parser instance, it might be null */
+6 -44
View File
@@ -12,8 +12,6 @@
#include "simdjson/generic/ondemand/value.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#include <limits>
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
namespace ondemand {
@@ -74,18 +72,6 @@ simdjson_inline simdjson_result<int64_t> value::get_int64() noexcept {
simdjson_inline simdjson_result<int64_t> value::get_int64_in_string() noexcept {
return iter.get_int64_in_string();
}
simdjson_inline simdjson_result<uint32_t> value::get_uint32() noexcept {
uint64_t result;
SIMDJSON_TRY(get_uint64().get(result));
if (result > (std::numeric_limits<uint32_t>::max)()) { return NUMBER_OUT_OF_RANGE; }
return static_cast<uint32_t>(result);
}
simdjson_inline simdjson_result<int32_t> value::get_int32() noexcept {
int64_t result;
SIMDJSON_TRY(get_int64().get(result));
if (result > (std::numeric_limits<int32_t>::max)() || result < (std::numeric_limits<int32_t>::min)()) { return NUMBER_OUT_OF_RANGE; }
return static_cast<int32_t>(result);
}
simdjson_inline simdjson_result<bool> value::get_bool() noexcept {
return iter.get_bool();
}
@@ -101,8 +87,6 @@ template<> simdjson_inline simdjson_result<number> value::get() noexcept { retur
template<> simdjson_inline simdjson_result<double> value::get() noexcept { return get_double(); }
template<> simdjson_inline simdjson_result<uint64_t> value::get() noexcept { return get_uint64(); }
template<> simdjson_inline simdjson_result<int64_t> value::get() noexcept { return get_int64(); }
template<> simdjson_inline simdjson_result<uint32_t> value::get() noexcept { return get_uint32(); }
template<> simdjson_inline simdjson_result<int32_t> value::get() noexcept { return get_int32(); }
template<> simdjson_inline simdjson_result<bool> value::get() noexcept { return get_bool(); }
@@ -114,8 +98,6 @@ template<> simdjson_warn_unused simdjson_inline error_code value::get(number& ou
template<> simdjson_warn_unused simdjson_inline error_code value::get(double& out) noexcept { return get_double().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code value::get(uint64_t& out) noexcept { return get_uint64().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code value::get(int64_t& out) noexcept { return get_int64().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code value::get(uint32_t& out) noexcept { return get_uint32().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code value::get(int32_t& out) noexcept { return get_int32().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code value::get(bool& out) noexcept { return get_bool().get(out); }
#if SIMDJSON_EXCEPTIONS
@@ -314,20 +296,14 @@ simdjson_inline simdjson_result<value> value::at_path(std::string_view json_path
}
}
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, value>
#else
template <typename Func>
#endif
inline error_code value::for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept {
inline simdjson_result<std::vector<value>> value::at_path_with_wildcard(std::string_view json_path) noexcept {
json_type t;
SIMDJSON_TRY(type().get(t));
switch (t) {
case json_type::array:
return (*this).get_array().for_each_at_path_with_wildcard(json_path, std::forward<Func>(callback));
return (*this).get_array().at_path_with_wildcard(json_path);
case json_type::object:
return (*this).get_object().for_each_at_path_with_wildcard(json_path, std::forward<Func>(callback));
return (*this).get_object().at_path_with_wildcard(json_path);
default:
return INVALID_JSON_POINTER;
}
@@ -425,14 +401,6 @@ simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_IMPLEMENTATION
if (error()) { return error(); }
return first.get_int64_in_string();
}
simdjson_inline simdjson_result<uint32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_uint32() noexcept {
if (error()) { return error(); }
return first.get_uint32();
}
simdjson_inline simdjson_result<int32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_int32() noexcept {
if (error()) { return error(); }
return first.get_int32();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_double() noexcept {
if (error()) { return error(); }
return first.get_double();
@@ -591,18 +559,12 @@ simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjs
return first.at_path(json_path);
}
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, SIMDJSON_IMPLEMENTATION::ondemand::value>
#else
template <typename Func>
#endif
inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::for_each_at_path_with_wildcard(
std::string_view json_path, Func&& callback) noexcept {
inline simdjson_result<std::vector<SIMDJSON_IMPLEMENTATION::ondemand::value>> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::at_path_with_wildcard(
std::string_view json_path) noexcept {
if (error()) {
return error();
}
return first.for_each_at_path_with_wildcard(json_path, std::forward<Func>(callback));
return first.at_path_with_wildcard(json_path);
}
} // namespace simdjson
+4 -50
View File
@@ -161,28 +161,6 @@ public:
*/
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
/**
* Cast this JSON value to a 32-bit unsigned integer.
*
* Calls get_uint64() and checks that the result fits in a uint32_t.
*
* @returns A 32-bit unsigned integer.
* @returns INCORRECT_TYPE If the JSON value is not an unsigned integer.
* @returns NUMBER_OUT_OF_RANGE If the value does not fit in a uint32_t.
*/
simdjson_inline simdjson_result<uint32_t> get_uint32() noexcept;
/**
* Cast this JSON value to a 32-bit signed integer.
*
* Calls get_int64() and checks that the result fits in an int32_t.
*
* @returns A 32-bit signed integer.
* @returns INCORRECT_TYPE If the JSON value is not an integer.
* @returns NUMBER_OUT_OF_RANGE If the value does not fit in an int32_t.
*/
simdjson_inline simdjson_result<int32_t> get_int32() noexcept;
/**
* Cast this JSON value to a double.
*
@@ -698,21 +676,13 @@ public:
simdjson_inline simdjson_result<value> at_path(std::string_view at_path) noexcept;
/**
* Call the provided callback for each value matching the given JSONPath
* expression with wildcard support.
* Get all values matching the given JSONPath expression with wildcard support.
* Supports wildcard character (*) for arrays or ".*" for objects.
*
* @param json_path JSONPath expression with wildcards
* @param callback Function called for each matching value
* @return error_code indicating success or failure
* @return Vector of values matching the wildcard pattern
*/
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, value>
#else
template <typename Func>
#endif
simdjson_inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
simdjson_inline simdjson_result<std::vector<value>> at_path_with_wildcard(std::string_view json_path) noexcept;
protected:
/**
@@ -776,8 +746,6 @@ public:
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<uint32_t> get_uint32() noexcept;
simdjson_inline simdjson_result<int32_t> get_int32() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
@@ -905,23 +873,9 @@ public:
simdjson_inline simdjson_result<int32_t> current_depth() const noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_pointer(std::string_view json_pointer) noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_path(std::string_view json_path) noexcept;
#if SIMDJSON_SUPPORTS_CONCEPTS
template <typename Func>
requires std::invocable<Func, SIMDJSON_IMPLEMENTATION::ondemand::value>
#else
template <typename Func>
#endif
simdjson_inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
simdjson_inline simdjson_result<std::vector<SIMDJSON_IMPLEMENTATION::ondemand::value>> at_path_with_wildcard(std::string_view json_path) noexcept;
};
// Forward-declare explicit specializations so MSVC /permissive- sees them before
// any template instantiation that would resolve element.get(val) to the primary.
template<> simdjson_inline error_code
simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get<SIMDJSON_IMPLEMENTATION::ondemand::value>(
SIMDJSON_IMPLEMENTATION::ondemand::value &out) noexcept;
template<> simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>
simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get<SIMDJSON_IMPLEMENTATION::ondemand::value>() noexcept;
} // namespace simdjson
#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_H
@@ -212,12 +212,6 @@ protected:
*/
size_t _max_depth{0};
public:
/** Whether to store big integers as strings instead of returning BIGINT_ERROR */
bool _number_as_string{false};
protected:
// Declaring these so that subclasses can use them to implement their constructors.
simdjson_inline dom_parser_implementation() noexcept;
simdjson_inline dom_parser_implementation(dom_parser_implementation &&other) noexcept;
+1 -2
View File
@@ -19,8 +19,7 @@ enum class tape_type {
DOUBLE = 'd',
TRUE_VALUE = 't',
FALSE_VALUE = 'f',
NULL_VALUE = 'n',
BIGINT = 'Z' // Big integer stored as string in string buffer
NULL_VALUE = 'n'
}; // enum class tape_type
} // namespace internal
+4 -14
View File
@@ -168,13 +168,10 @@ inline padded_string::operator padded_string_view() const noexcept simdjson_life
}
inline simdjson_result<padded_string> padded_string::load(std::string_view filename) noexcept {
// std::string_view is not guaranteed to be null-terminated, but std::fopen requires
// a null-terminated C string. Construct a temporary std::string to ensure null-termination.
const std::string null_terminated_filename(filename);
// Open the file
SIMDJSON_PUSH_DISABLE_WARNINGS
SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe
std::FILE *fp = std::fopen(null_terminated_filename.c_str(), "rb");
std::FILE *fp = std::fopen(filename.data(), "rb");
SIMDJSON_POP_DISABLE_WARNINGS
if (fp == nullptr) {
@@ -226,13 +223,10 @@ inline simdjson_result<padded_string> padded_string::load(std::string_view filen
#if defined(_WIN32) && SIMDJSON_CPLUSPLUS17
inline simdjson_result<padded_string> padded_string::load(std::wstring_view filename) noexcept {
// std::wstring_view is not guaranteed to be null-terminated, but _wfopen requires
// a null-terminated wide C string. Construct a temporary std::wstring to ensure null-termination.
const std::wstring null_terminated_filename(filename);
// Open the file using the wide characters
SIMDJSON_PUSH_DISABLE_WARNINGS
SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe
std::FILE *fp = _wfopen(null_terminated_filename.c_str(), L"rb");
std::FILE *fp = _wfopen(filename.data(), L"rb");
SIMDJSON_POP_DISABLE_WARNINGS
if (fp == nullptr) {
@@ -355,9 +349,6 @@ inline padded_string padded_string_builder::convert() noexcept {
}
inline bool padded_string_builder::reserve(size_t additional) noexcept {
if (simdjson_unlikely(additional + size < size)) {
return false; // overflow: cannot satisfy request
}
size_t needed = size + additional;
if (needed <= capacity) {
return true;
@@ -367,9 +358,8 @@ inline bool padded_string_builder::reserve(size_t additional) noexcept {
// repeated allocations.
if (new_capacity < 4096) {
new_capacity *= 2;
// overflow guard: ensure new_capacity + new_capacity/2 does not overflow
} else if (new_capacity + new_capacity / 2 > new_capacity) {
new_capacity += new_capacity / 2; // grow by 1.5x
} else {
new_capacity += new_capacity/2; // grow by 1.5x
}
char *new_data = internal::allocate_padded_buffer(new_capacity);
if (new_data == nullptr) {
+3 -3
View File
@@ -4,7 +4,7 @@
#define SIMDJSON_SIMDJSON_VERSION_H
/** The version of simdjson being used (major.minor.revision) */
#define SIMDJSON_VERSION "4.6.4"
#define SIMDJSON_VERSION "4.4.2"
namespace simdjson {
enum {
@@ -15,11 +15,11 @@ enum {
/**
* The minor version (major.MINOR.revision) of simdjson being used.
*/
SIMDJSON_VERSION_MINOR = 6,
SIMDJSON_VERSION_MINOR = 4,
/**
* The revision (major.minor.REVISION) of simdjson being used.
*/
SIMDJSON_VERSION_REVISION = 4
SIMDJSON_VERSION_REVISION = 2
};
} // namespace simdjson
+11 -297
View File
@@ -1,4 +1,4 @@
/* auto-generated on 2026-05-06 17:28:39 -0400. version 4.6.4 Do not edit! */
/* auto-generated on 2026-03-20 11:11:38 -0400. version 4.4.2 Do not edit! */
/* including simdjson.cpp: */
/* begin file simdjson.cpp */
#define SIMDJSON_SRC_SIMDJSON_CPP
@@ -7308,12 +7308,6 @@ protected:
*/
size_t _max_depth{0};
public:
/** Whether to store big integers as strings instead of returning BIGINT_ERROR */
bool _number_as_string{false};
protected:
// Declaring these so that subclasses can use them to implement their constructors.
simdjson_inline dom_parser_implementation() noexcept;
simdjson_inline dom_parser_implementation(dom_parser_implementation &&other) noexcept;
@@ -7889,8 +7883,7 @@ enum class tape_type {
DOUBLE = 'd',
TRUE_VALUE = 't',
FALSE_VALUE = 'f',
NULL_VALUE = 'n',
BIGINT = 'Z' // Big integer stored as string in string buffer
NULL_VALUE = 'n'
}; // enum class tape_type
} // namespace internal
@@ -14185,9 +14178,6 @@ struct tape_writer {
/** Write a double value to tape. */
simdjson_inline void append_double(double value) noexcept;
/** Write a big integer (as string) to tape. src points to first digit, len is byte count. */
simdjson_inline void append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept;
/**
* Append a tape entry (an 8-bit type,and 56 bits worth of value).
*/
@@ -14271,18 +14261,6 @@ simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, intern
tape_loc = val | ((uint64_t(char(t))) << 56);
}
simdjson_inline void tape_writer::append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept {
// Write to string buffer: [4-byte LE length][digits][null]
uint32_t str_len = uint32_t(len);
memcpy(string_buf, &str_len, sizeof(uint32_t));
memcpy(string_buf + sizeof(uint32_t), src, len);
string_buf[sizeof(uint32_t) + len] = 0;
// Tape entry: offset into string buffer
// The caller must set the offset relative to doc.string_buf base
append(0, internal::tape_type::BIGINT); // placeholder offset, caller patches
string_buf += sizeof(uint32_t) + len + 1;
}
} // namespace stage2
} // unnamed namespace
} // namespace arm64
@@ -15220,23 +15198,7 @@ simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept {
iter.log_value("number");
error_code err = numberparsing::parse_number(value, tape);
if (simdjson_unlikely(err == BIGINT_ERROR &&
iter.dom_parser._number_as_string)) {
// Write big integer to string buffer using the same format as strings.
// Scan digits the same way parse_number does (skip optional '-', then digits).
const uint8_t *p = value;
if (*p == '-') p++;
while (numberparsing::is_digit(*p)) p++;
size_t len = size_t(p - value);
tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::BIGINT);
uint8_t *dst = current_string_buf_loc + sizeof(uint32_t);
memcpy(dst, value, len);
dst += len;
on_end_string(dst);
return SUCCESS;
}
return err;
return numberparsing::parse_number(value, tape);
}
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept {
@@ -20577,9 +20539,6 @@ struct tape_writer {
/** Write a double value to tape. */
simdjson_inline void append_double(double value) noexcept;
/** Write a big integer (as string) to tape. src points to first digit, len is byte count. */
simdjson_inline void append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept;
/**
* Append a tape entry (an 8-bit type,and 56 bits worth of value).
*/
@@ -20663,18 +20622,6 @@ simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, intern
tape_loc = val | ((uint64_t(char(t))) << 56);
}
simdjson_inline void tape_writer::append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept {
// Write to string buffer: [4-byte LE length][digits][null]
uint32_t str_len = uint32_t(len);
memcpy(string_buf, &str_len, sizeof(uint32_t));
memcpy(string_buf + sizeof(uint32_t), src, len);
string_buf[sizeof(uint32_t) + len] = 0;
// Tape entry: offset into string buffer
// The caller must set the offset relative to doc.string_buf base
append(0, internal::tape_type::BIGINT); // placeholder offset, caller patches
string_buf += sizeof(uint32_t) + len + 1;
}
} // namespace stage2
} // unnamed namespace
} // namespace haswell
@@ -21612,23 +21559,7 @@ simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept {
iter.log_value("number");
error_code err = numberparsing::parse_number(value, tape);
if (simdjson_unlikely(err == BIGINT_ERROR &&
iter.dom_parser._number_as_string)) {
// Write big integer to string buffer using the same format as strings.
// Scan digits the same way parse_number does (skip optional '-', then digits).
const uint8_t *p = value;
if (*p == '-') p++;
while (numberparsing::is_digit(*p)) p++;
size_t len = size_t(p - value);
tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::BIGINT);
uint8_t *dst = current_string_buf_loc + sizeof(uint32_t);
memcpy(dst, value, len);
dst += len;
on_end_string(dst);
return SUCCESS;
}
return err;
return numberparsing::parse_number(value, tape);
}
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept {
@@ -26964,9 +26895,6 @@ struct tape_writer {
/** Write a double value to tape. */
simdjson_inline void append_double(double value) noexcept;
/** Write a big integer (as string) to tape. src points to first digit, len is byte count. */
simdjson_inline void append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept;
/**
* Append a tape entry (an 8-bit type,and 56 bits worth of value).
*/
@@ -27050,18 +26978,6 @@ simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, intern
tape_loc = val | ((uint64_t(char(t))) << 56);
}
simdjson_inline void tape_writer::append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept {
// Write to string buffer: [4-byte LE length][digits][null]
uint32_t str_len = uint32_t(len);
memcpy(string_buf, &str_len, sizeof(uint32_t));
memcpy(string_buf + sizeof(uint32_t), src, len);
string_buf[sizeof(uint32_t) + len] = 0;
// Tape entry: offset into string buffer
// The caller must set the offset relative to doc.string_buf base
append(0, internal::tape_type::BIGINT); // placeholder offset, caller patches
string_buf += sizeof(uint32_t) + len + 1;
}
} // namespace stage2
} // unnamed namespace
} // namespace icelake
@@ -27999,23 +27915,7 @@ simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept {
iter.log_value("number");
error_code err = numberparsing::parse_number(value, tape);
if (simdjson_unlikely(err == BIGINT_ERROR &&
iter.dom_parser._number_as_string)) {
// Write big integer to string buffer using the same format as strings.
// Scan digits the same way parse_number does (skip optional '-', then digits).
const uint8_t *p = value;
if (*p == '-') p++;
while (numberparsing::is_digit(*p)) p++;
size_t len = size_t(p - value);
tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::BIGINT);
uint8_t *dst = current_string_buf_loc + sizeof(uint32_t);
memcpy(dst, value, len);
dst += len;
on_end_string(dst);
return SUCCESS;
}
return err;
return numberparsing::parse_number(value, tape);
}
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept {
@@ -33622,9 +33522,6 @@ struct tape_writer {
/** Write a double value to tape. */
simdjson_inline void append_double(double value) noexcept;
/** Write a big integer (as string) to tape. src points to first digit, len is byte count. */
simdjson_inline void append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept;
/**
* Append a tape entry (an 8-bit type,and 56 bits worth of value).
*/
@@ -33708,18 +33605,6 @@ simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, intern
tape_loc = val | ((uint64_t(char(t))) << 56);
}
simdjson_inline void tape_writer::append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept {
// Write to string buffer: [4-byte LE length][digits][null]
uint32_t str_len = uint32_t(len);
memcpy(string_buf, &str_len, sizeof(uint32_t));
memcpy(string_buf + sizeof(uint32_t), src, len);
string_buf[sizeof(uint32_t) + len] = 0;
// Tape entry: offset into string buffer
// The caller must set the offset relative to doc.string_buf base
append(0, internal::tape_type::BIGINT); // placeholder offset, caller patches
string_buf += sizeof(uint32_t) + len + 1;
}
} // namespace stage2
} // unnamed namespace
} // namespace ppc64
@@ -34657,23 +34542,7 @@ simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept {
iter.log_value("number");
error_code err = numberparsing::parse_number(value, tape);
if (simdjson_unlikely(err == BIGINT_ERROR &&
iter.dom_parser._number_as_string)) {
// Write big integer to string buffer using the same format as strings.
// Scan digits the same way parse_number does (skip optional '-', then digits).
const uint8_t *p = value;
if (*p == '-') p++;
while (numberparsing::is_digit(*p)) p++;
size_t len = size_t(p - value);
tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::BIGINT);
uint8_t *dst = current_string_buf_loc + sizeof(uint32_t);
memcpy(dst, value, len);
dst += len;
on_end_string(dst);
return SUCCESS;
}
return err;
return numberparsing::parse_number(value, tape);
}
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept {
@@ -40842,9 +40711,6 @@ struct tape_writer {
/** Write a double value to tape. */
simdjson_inline void append_double(double value) noexcept;
/** Write a big integer (as string) to tape. src points to first digit, len is byte count. */
simdjson_inline void append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept;
/**
* Append a tape entry (an 8-bit type,and 56 bits worth of value).
*/
@@ -40928,18 +40794,6 @@ simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, intern
tape_loc = val | ((uint64_t(char(t))) << 56);
}
simdjson_inline void tape_writer::append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept {
// Write to string buffer: [4-byte LE length][digits][null]
uint32_t str_len = uint32_t(len);
memcpy(string_buf, &str_len, sizeof(uint32_t));
memcpy(string_buf + sizeof(uint32_t), src, len);
string_buf[sizeof(uint32_t) + len] = 0;
// Tape entry: offset into string buffer
// The caller must set the offset relative to doc.string_buf base
append(0, internal::tape_type::BIGINT); // placeholder offset, caller patches
string_buf += sizeof(uint32_t) + len + 1;
}
} // namespace stage2
} // unnamed namespace
} // namespace westmere
@@ -41877,23 +41731,7 @@ simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept {
iter.log_value("number");
error_code err = numberparsing::parse_number(value, tape);
if (simdjson_unlikely(err == BIGINT_ERROR &&
iter.dom_parser._number_as_string)) {
// Write big integer to string buffer using the same format as strings.
// Scan digits the same way parse_number does (skip optional '-', then digits).
const uint8_t *p = value;
if (*p == '-') p++;
while (numberparsing::is_digit(*p)) p++;
size_t len = size_t(p - value);
tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::BIGINT);
uint8_t *dst = current_string_buf_loc + sizeof(uint32_t);
memcpy(dst, value, len);
dst += len;
on_end_string(dst);
return SUCCESS;
}
return err;
return numberparsing::parse_number(value, tape);
}
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept {
@@ -47093,9 +46931,6 @@ struct tape_writer {
/** Write a double value to tape. */
simdjson_inline void append_double(double value) noexcept;
/** Write a big integer (as string) to tape. src points to first digit, len is byte count. */
simdjson_inline void append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept;
/**
* Append a tape entry (an 8-bit type,and 56 bits worth of value).
*/
@@ -47179,18 +47014,6 @@ simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, intern
tape_loc = val | ((uint64_t(char(t))) << 56);
}
simdjson_inline void tape_writer::append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept {
// Write to string buffer: [4-byte LE length][digits][null]
uint32_t str_len = uint32_t(len);
memcpy(string_buf, &str_len, sizeof(uint32_t));
memcpy(string_buf + sizeof(uint32_t), src, len);
string_buf[sizeof(uint32_t) + len] = 0;
// Tape entry: offset into string buffer
// The caller must set the offset relative to doc.string_buf base
append(0, internal::tape_type::BIGINT); // placeholder offset, caller patches
string_buf += sizeof(uint32_t) + len + 1;
}
} // namespace stage2
} // unnamed namespace
} // namespace lasx
@@ -48128,23 +47951,7 @@ simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept {
iter.log_value("number");
error_code err = numberparsing::parse_number(value, tape);
if (simdjson_unlikely(err == BIGINT_ERROR &&
iter.dom_parser._number_as_string)) {
// Write big integer to string buffer using the same format as strings.
// Scan digits the same way parse_number does (skip optional '-', then digits).
const uint8_t *p = value;
if (*p == '-') p++;
while (numberparsing::is_digit(*p)) p++;
size_t len = size_t(p - value);
tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::BIGINT);
uint8_t *dst = current_string_buf_loc + sizeof(uint32_t);
memcpy(dst, value, len);
dst += len;
on_end_string(dst);
return SUCCESS;
}
return err;
return numberparsing::parse_number(value, tape);
}
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept {
@@ -53248,9 +53055,6 @@ struct tape_writer {
/** Write a double value to tape. */
simdjson_inline void append_double(double value) noexcept;
/** Write a big integer (as string) to tape. src points to first digit, len is byte count. */
simdjson_inline void append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept;
/**
* Append a tape entry (an 8-bit type,and 56 bits worth of value).
*/
@@ -53334,18 +53138,6 @@ simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, intern
tape_loc = val | ((uint64_t(char(t))) << 56);
}
simdjson_inline void tape_writer::append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept {
// Write to string buffer: [4-byte LE length][digits][null]
uint32_t str_len = uint32_t(len);
memcpy(string_buf, &str_len, sizeof(uint32_t));
memcpy(string_buf + sizeof(uint32_t), src, len);
string_buf[sizeof(uint32_t) + len] = 0;
// Tape entry: offset into string buffer
// The caller must set the offset relative to doc.string_buf base
append(0, internal::tape_type::BIGINT); // placeholder offset, caller patches
string_buf += sizeof(uint32_t) + len + 1;
}
} // namespace stage2
} // unnamed namespace
} // namespace lsx
@@ -54283,23 +54075,7 @@ simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept {
iter.log_value("number");
error_code err = numberparsing::parse_number(value, tape);
if (simdjson_unlikely(err == BIGINT_ERROR &&
iter.dom_parser._number_as_string)) {
// Write big integer to string buffer using the same format as strings.
// Scan digits the same way parse_number does (skip optional '-', then digits).
const uint8_t *p = value;
if (*p == '-') p++;
while (numberparsing::is_digit(*p)) p++;
size_t len = size_t(p - value);
tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::BIGINT);
uint8_t *dst = current_string_buf_loc + sizeof(uint32_t);
memcpy(dst, value, len);
dst += len;
on_end_string(dst);
return SUCCESS;
}
return err;
return numberparsing::parse_number(value, tape);
}
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept {
@@ -59822,9 +59598,6 @@ struct tape_writer {
/** Write a double value to tape. */
simdjson_inline void append_double(double value) noexcept;
/** Write a big integer (as string) to tape. src points to first digit, len is byte count. */
simdjson_inline void append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept;
/**
* Append a tape entry (an 8-bit type,and 56 bits worth of value).
*/
@@ -59908,18 +59681,6 @@ simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, intern
tape_loc = val | ((uint64_t(char(t))) << 56);
}
simdjson_inline void tape_writer::append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept {
// Write to string buffer: [4-byte LE length][digits][null]
uint32_t str_len = uint32_t(len);
memcpy(string_buf, &str_len, sizeof(uint32_t));
memcpy(string_buf + sizeof(uint32_t), src, len);
string_buf[sizeof(uint32_t) + len] = 0;
// Tape entry: offset into string buffer
// The caller must set the offset relative to doc.string_buf base
append(0, internal::tape_type::BIGINT); // placeholder offset, caller patches
string_buf += sizeof(uint32_t) + len + 1;
}
} // namespace stage2
} // unnamed namespace
} // namespace rvv_vls
@@ -60857,23 +60618,7 @@ simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept {
iter.log_value("number");
error_code err = numberparsing::parse_number(value, tape);
if (simdjson_unlikely(err == BIGINT_ERROR &&
iter.dom_parser._number_as_string)) {
// Write big integer to string buffer using the same format as strings.
// Scan digits the same way parse_number does (skip optional '-', then digits).
const uint8_t *p = value;
if (*p == '-') p++;
while (numberparsing::is_digit(*p)) p++;
size_t len = size_t(p - value);
tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::BIGINT);
uint8_t *dst = current_string_buf_loc + sizeof(uint32_t);
memcpy(dst, value, len);
dst += len;
on_end_string(dst);
return SUCCESS;
}
return err;
return numberparsing::parse_number(value, tape);
}
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept {
@@ -64444,9 +64189,6 @@ struct tape_writer {
/** Write a double value to tape. */
simdjson_inline void append_double(double value) noexcept;
/** Write a big integer (as string) to tape. src points to first digit, len is byte count. */
simdjson_inline void append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept;
/**
* Append a tape entry (an 8-bit type,and 56 bits worth of value).
*/
@@ -64530,18 +64272,6 @@ simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, intern
tape_loc = val | ((uint64_t(char(t))) << 56);
}
simdjson_inline void tape_writer::append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept {
// Write to string buffer: [4-byte LE length][digits][null]
uint32_t str_len = uint32_t(len);
memcpy(string_buf, &str_len, sizeof(uint32_t));
memcpy(string_buf + sizeof(uint32_t), src, len);
string_buf[sizeof(uint32_t) + len] = 0;
// Tape entry: offset into string buffer
// The caller must set the offset relative to doc.string_buf base
append(0, internal::tape_type::BIGINT); // placeholder offset, caller patches
string_buf += sizeof(uint32_t) + len + 1;
}
} // namespace stage2
} // unnamed namespace
} // namespace fallback
@@ -64725,23 +64455,7 @@ simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept {
iter.log_value("number");
error_code err = numberparsing::parse_number(value, tape);
if (simdjson_unlikely(err == BIGINT_ERROR &&
iter.dom_parser._number_as_string)) {
// Write big integer to string buffer using the same format as strings.
// Scan digits the same way parse_number does (skip optional '-', then digits).
const uint8_t *p = value;
if (*p == '-') p++;
while (numberparsing::is_digit(*p)) p++;
size_t len = size_t(p - value);
tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::BIGINT);
uint8_t *dst = current_string_buf_loc + sizeof(uint32_t);
memcpy(dst, value, len);
dst += len;
on_end_string(dst);
return SUCCESS;
}
return err;
return numberparsing::parse_number(value, tape);
}
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept {
+992 -3135
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+1 -17
View File
@@ -172,23 +172,7 @@ simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept {
iter.log_value("number");
error_code err = numberparsing::parse_number(value, tape);
if (simdjson_unlikely(err == BIGINT_ERROR &&
iter.dom_parser._number_as_string)) {
// Write big integer to string buffer using the same format as strings.
// Scan digits the same way parse_number does (skip optional '-', then digits).
const uint8_t *p = value;
if (*p == '-') p++;
while (numberparsing::is_digit(*p)) p++;
size_t len = size_t(p - value);
tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::BIGINT);
uint8_t *dst = current_string_buf_loc + sizeof(uint32_t);
memcpy(dst, value, len);
dst += len;
on_end_string(dst);
return SUCCESS;
}
return err;
return numberparsing::parse_number(value, tape);
}
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept {
-15
View File
@@ -26,9 +26,6 @@ struct tape_writer {
/** Write a double value to tape. */
simdjson_inline void append_double(double value) noexcept;
/** Write a big integer (as string) to tape. src points to first digit, len is byte count. */
simdjson_inline void append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept;
/**
* Append a tape entry (an 8-bit type,and 56 bits worth of value).
*/
@@ -112,18 +109,6 @@ simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, intern
tape_loc = val | ((uint64_t(char(t))) << 56);
}
simdjson_inline void tape_writer::append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept {
// Write to string buffer: [4-byte LE length][digits][null]
uint32_t str_len = uint32_t(len);
memcpy(string_buf, &str_len, sizeof(uint32_t));
memcpy(string_buf + sizeof(uint32_t), src, len);
string_buf[sizeof(uint32_t) + len] = 0;
// Tape entry: offset into string buffer
// The caller must set the offset relative to doc.string_buf base
append(0, internal::tape_type::BIGINT); // placeholder offset, caller patches
string_buf += sizeof(uint32_t) + len + 1;
}
} // namespace stage2
} // unnamed namespace
} // namespace SIMDJSON_IMPLEMENTATION
-1
View File
@@ -11,7 +11,6 @@ add_cpp_test(document_tests LABELS dom acceptance per_implementation
add_cpp_test(errortests 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(big_integer_tests 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)
-151
View File
@@ -1,151 +0,0 @@
#include "simdjson.h"
#include "test_macros.h"
#include <sstream>
using namespace simdjson;
namespace big_integer_tests {
bool option_off_by_default() {
TEST_START();
dom::parser parser;
ASSERT_EQUAL(parser.number_as_string(), false);
TEST_SUCCEED();
}
bool default_returns_bigint_error() {
TEST_START();
dom::parser parser;
auto result = parser.parse(R"({"val":123456789012345678901})"_padded);
ASSERT_EQUAL(result.error(), BIGINT_ERROR);
TEST_SUCCEED();
}
bool opt_in_parses_big_integer() {
TEST_START();
dom::parser parser;
parser.number_as_string(true);
dom::element doc;
ASSERT_SUCCESS(parser.parse(R"({"val":123456789012345678901})"_padded).get(doc));
dom::element val;
ASSERT_SUCCESS(doc["val"].get(val));
ASSERT_EQUAL(val.type(), dom::element_type::BIGINT);
ASSERT_TRUE(val.is_bigint());
std::string_view digits;
ASSERT_SUCCESS(val.get_bigint().get(digits));
ASSERT_EQUAL(digits, "123456789012345678901");
// Verify streaming works (same pattern as readme_examples)
std::ostringstream os;
os << val.get_bigint().value_unsafe();
ASSERT_EQUAL(os.str(), "123456789012345678901");
TEST_SUCCEED();
}
bool negative_big_integer() {
TEST_START();
dom::parser parser;
parser.number_as_string(true);
dom::element doc;
ASSERT_SUCCESS(parser.parse(R"({"val":-12345678901234567890})"_padded).get(doc));
dom::element val;
ASSERT_SUCCESS(doc["val"].get(val));
ASSERT_EQUAL(val.type(), dom::element_type::BIGINT);
std::string_view digits;
ASSERT_SUCCESS(val.get_bigint().get(digits));
ASSERT_EQUAL(digits, "-12345678901234567890");
TEST_SUCCEED();
}
bool big_integer_in_array() {
TEST_START();
dom::parser parser;
parser.number_as_string(true);
dom::element doc;
ASSERT_SUCCESS(parser.parse(R"([1, 123456789012345678901, 3])"_padded).get(doc));
dom::array arr;
ASSERT_SUCCESS(doc.get_array().get(arr));
size_t count = 0;
for (auto elem : arr) { (void)elem; count++; }
ASSERT_EQUAL(count, 3);
TEST_SUCCEED();
}
bool serialization_preserves_digits() {
TEST_START();
dom::parser parser;
parser.number_as_string(true);
dom::element doc;
ASSERT_SUCCESS(parser.parse(R"({"val":123456789012345678901})"_padded).get(doc));
std::string output = simdjson::to_string(doc);
// Raw digits should appear
ASSERT_TRUE(output.find("123456789012345678901") != std::string::npos);
// Must not be quoted — it's a number, not a string
ASSERT_EQUAL(output.find("\"123456789012345678901\""), std::string::npos);
TEST_SUCCEED();
}
bool normal_numbers_unaffected() {
TEST_START();
dom::parser parser;
parser.number_as_string(true);
dom::element doc;
ASSERT_SUCCESS(parser.parse(R"({"a":42,"b":-1,"c":3.14,"d":18446744073709551615})"_padded).get(doc));
int64_t a;
ASSERT_SUCCESS(doc["a"].get_int64().get(a));
ASSERT_EQUAL(a, 42);
uint64_t d;
ASSERT_SUCCESS(doc["d"].get_uint64().get(d));
ASSERT_EQUAL(d, 18446744073709551615ULL);
TEST_SUCCEED();
}
bool type_checks() {
TEST_START();
dom::parser parser;
parser.number_as_string(true);
dom::element doc;
ASSERT_SUCCESS(parser.parse(R"({"val":123456789012345678901})"_padded).get(doc));
dom::element val;
ASSERT_SUCCESS(doc["val"].get(val));
// is_bigint should be true
ASSERT_TRUE(val.is_bigint());
// other type checks should be false
ASSERT_FALSE(val.is_int64());
ASSERT_FALSE(val.is_uint64());
ASSERT_FALSE(val.is_double());
ASSERT_FALSE(val.is_string());
ASSERT_FALSE(val.is_bool());
ASSERT_FALSE(val.is_null());
// get_int64/uint64/double should return INCORRECT_TYPE
ASSERT_ERROR(val.get_int64(), INCORRECT_TYPE);
ASSERT_ERROR(val.get_uint64(), INCORRECT_TYPE);
ASSERT_ERROR(val.get_double(), INCORRECT_TYPE);
ASSERT_ERROR(val.get_string(), INCORRECT_TYPE);
TEST_SUCCEED();
}
bool element_type_output() {
TEST_START();
std::ostringstream os;
os << dom::element_type::BIGINT;
ASSERT_EQUAL(os.str(), "bigint");
TEST_SUCCEED();
}
bool run() {
return option_off_by_default() &&
default_returns_bigint_error() &&
opt_in_parses_big_integer() &&
negative_big_integer() &&
big_integer_in_array() &&
serialization_preserves_digits() &&
normal_numbers_unaffected() &&
type_checks() &&
element_type_output();
}
} // namespace big_integer_tests
int main() {
return big_integer_tests::run() ? 0 : 1;
}
-15
View File
@@ -114,20 +114,6 @@ namespace parser_load {
TEST_SUCCEED();
}
bool parser_load_string_view_subpath() {
TEST_START();
const std::string valid_path(TWITTER_JSON);
const std::string backing = valid_path + ".extra";
const std::string_view view(backing.data(), valid_path.size());
uint64_t count_from_string = 0;
uint64_t count_from_view = 0;
dom::parser parser;
ASSERT_SUCCESS(parser.load(valid_path)["search_metadata"]["count"].get(count_from_string));
ASSERT_SUCCESS(parser.load(view)["search_metadata"]["count"].get(count_from_view));
ASSERT_EQUAL(count_from_view, count_from_string);
TEST_SUCCEED();
}
bool parser_load_chain() {
TEST_START();
dom::parser parser;
@@ -150,7 +136,6 @@ namespace parser_load {
&& parser_load_nonexistent()
&& parser_load_many_nonexistent()
&& padded_string_load_nonexistent()
&& parser_load_string_view_subpath()
&& parser_load_chain()
&& parser_load_many_chain()
&& parser_parse_many_documents_error_in_the_middle()
-3
View File
@@ -273,9 +273,6 @@ namespace treewalk_1 {
case dom::element_type::NULL_VALUE:
cout << "null" << endl;
break;
case dom::element_type::BIGINT:
cout << element.get_bigint().value_unsafe() << endl;
break;
}
}
@@ -884,30 +884,6 @@ namespace document_stream_tests {
TEST_SUCCEED();
}
bool uint32_with_trailing() {
TEST_START();
auto json = R"( 133 badstuff )"_padded;
ondemand::parser parser;
ondemand::document_stream doc;
ASSERT_SUCCESS(parser.iterate_many(json).get(doc));
uint32_t x;
ASSERT_SUCCESS((*doc.begin()).get_uint32().get(x));
ASSERT_EQUAL(x,133);
TEST_SUCCEED();
}
bool int32_with_trailing() {
TEST_START();
auto json = R"( 133 badstuff )"_padded;
ondemand::parser parser;
ondemand::document_stream doc;
ASSERT_SUCCESS(parser.iterate_many(json).get(doc));
int32_t x;
ASSERT_SUCCESS((*doc.begin()).get_int32().get(x));
ASSERT_EQUAL(x,133);
TEST_SUCCEED();
}
bool double_with_trailing() {
TEST_START();
auto json = R"( 133 badstuff )"_padded;
@@ -955,8 +931,6 @@ namespace document_stream_tests {
string_with_trailing() &&
uint64_with_trailing() &&
int64_with_trailing() &&
uint32_with_trailing() &&
int32_with_trailing() &&
bool_with_trailing() &&
null_with_trailing() &&
truncated_utf8() &&
-44
View File
@@ -171,17 +171,6 @@ namespace error_tests {
TEST_SUCCEED();
}
bool parser_set_max_capacity() {
TEST_START();
ondemand::parser parser;
parser.set_max_capacity(1024 * 1024);
ASSERT_EQUAL(parser.max_capacity(), size_t(1024 * 1024));
auto json = R"({"k":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"})"_padded;
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(json).get(doc));
TEST_SUCCEED();
}
bool simple_error_example() {
TEST_START();
ondemand::parser parser;
@@ -223,11 +212,7 @@ namespace error_tests {
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_object(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
@@ -250,11 +235,7 @@ namespace error_tests {
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_object(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
@@ -276,11 +257,7 @@ namespace error_tests {
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_object(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
@@ -302,11 +279,7 @@ namespace error_tests {
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_object(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
@@ -333,11 +306,7 @@ namespace error_tests {
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_object(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
@@ -360,11 +329,7 @@ namespace error_tests {
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_object(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
@@ -385,11 +350,7 @@ namespace error_tests {
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_object(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
@@ -410,11 +371,7 @@ namespace error_tests {
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_object(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint32(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_int64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_uint64(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
@@ -475,7 +432,6 @@ namespace error_tests {
raw_json_string_error() &&
empty_document_error() &&
parser_max_capacity() &&
parser_set_max_capacity() &&
get_fail_then_succeed_bool() &&
get_fail_then_succeed_null() &&
simple_error_example() &&
+1 -104
View File
@@ -545,111 +545,8 @@ namespace number_tests {
TEST_SUCCEED();
}
bool get_int32_values() {
TEST_START();
ondemand::parser parser;
ondemand::document doc;
int32_t val;
padded_string docdata;
// Valid int32 values
docdata = "0"_padded;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_SUCCESS(doc.get_int32().get(val));
ASSERT_EQUAL(val, 0);
docdata = "42"_padded;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_SUCCESS(doc.get_int32().get(val));
ASSERT_EQUAL(val, 42);
docdata = "-1"_padded;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_SUCCESS(doc.get_int32().get(val));
ASSERT_EQUAL(val, -1);
docdata = "2147483647"_padded; // INT32_MAX
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_SUCCESS(doc.get_int32().get(val));
ASSERT_EQUAL(val, 2147483647);
docdata = "-2147483648"_padded; // INT32_MIN
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_SUCCESS(doc.get_int32().get(val));
ASSERT_EQUAL(val, -2147483648);
// Out of range
docdata = "2147483648"_padded; // INT32_MAX + 1
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_ERROR(doc.get_int32(), NUMBER_OUT_OF_RANGE);
docdata = "-2147483649"_padded; // INT32_MIN - 1
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_ERROR(doc.get_int32(), NUMBER_OUT_OF_RANGE);
docdata = "9999999999"_padded;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_ERROR(doc.get_int32(), NUMBER_OUT_OF_RANGE);
// Test via value path
auto json = R"({"x": 42})"_padded;
ASSERT_SUCCESS(parser.iterate(json).get(doc));
ASSERT_SUCCESS(doc["x"].get_int32().get(val));
ASSERT_EQUAL(val, 42);
TEST_SUCCEED();
}
bool get_uint32_values() {
TEST_START();
ondemand::parser parser;
ondemand::document doc;
uint32_t val;
padded_string docdata;
// Valid uint32 values
docdata = "0"_padded;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_SUCCESS(doc.get_uint32().get(val));
ASSERT_EQUAL(val, 0u);
docdata = "42"_padded;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_SUCCESS(doc.get_uint32().get(val));
ASSERT_EQUAL(val, 42u);
docdata = "4294967295"_padded; // UINT32_MAX
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_SUCCESS(doc.get_uint32().get(val));
ASSERT_EQUAL(val, 4294967295u);
// Out of range
docdata = "4294967296"_padded; // UINT32_MAX + 1
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_ERROR(doc.get_uint32(), NUMBER_OUT_OF_RANGE);
docdata = "9999999999"_padded;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_ERROR(doc.get_uint32(), NUMBER_OUT_OF_RANGE);
// Negative values should fail (get_uint64 will fail with INCORRECT_TYPE)
docdata = "-1"_padded;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ASSERT_ERROR(doc.get_uint32(), INCORRECT_TYPE);
// Test via value path
auto json = R"({"x": 42})"_padded;
ASSERT_SUCCESS(parser.iterate(json).get(doc));
ASSERT_SUCCESS(doc["x"].get_uint32().get(val));
ASSERT_EQUAL(val, 42u);
TEST_SUCCEED();
}
bool run() {
return get_int32_values() &&
get_uint32_values() &&
minus_zero() &&
return minus_zero() &&
gigantic_big_int() &&
big_int_not_zero() &&
negative_big_int() &&
@@ -177,68 +177,6 @@ simdjson_inline simdjson_result<Car> simdjson::ondemand::document::get() & noexc
#if SIMDJSON_EXCEPTIONS
// Test matching the doc example in doc/basics.md
// "Using for_each_at_path_with_wildcard for JSONPath Queries (On-Demand)"
bool wildcard_basics_example() {
TEST_START();
simdjson::padded_string json_string = R"(
{
"firstName": "John",
"lastName": "doe",
"age": 26,
"address": {
"streetAddress": "naist street",
"city": "Nara",
"postalCode": "630-0192"
},
"phoneNumbers": [
{
"type": "iPhone",
"numbers": ["0123-4567-8888", "0123-4567-8788"]
},
{
"type": "home",
"numbers": ["0123-4567-8910"]
}
]
})"_padded;
ondemand::parser parser;
ondemand::document doc = parser.iterate(json_string);
// Fetch all fields in the address object
std::vector<std::string_view> fields;
auto error = doc.for_each_at_path_with_wildcard("$.address.*",
[&](ondemand::value value) {
std::string_view field;
if (value.get(field) == SUCCESS) {
fields.push_back(field);
}
});
ASSERT_SUCCESS(error);
ASSERT_EQUAL(fields.size(), 3);
ASSERT_EQUAL(fields[0], "naist street");
ASSERT_EQUAL(fields[1], "Nara");
ASSERT_EQUAL(fields[2], "630-0192");
// Fetch all phone numbers
std::vector<std::string_view> numbers;
error = doc.for_each_at_path_with_wildcard("$.phoneNumbers[*].numbers[*]",
[&](ondemand::value value) {
std::string_view number;
if (value.get(number) == SUCCESS) {
numbers.push_back(number);
}
});
ASSERT_SUCCESS(error);
ASSERT_EQUAL(numbers.size(), 3);
ASSERT_EQUAL(numbers[0], "0123-4567-8888");
ASSERT_EQUAL(numbers[1], "0123-4567-8788");
ASSERT_EQUAL(numbers[2], "0123-4567-8910");
TEST_SUCCEED();
}
void main_capture() {
padded_string json_padded = "{\"a\":[1,2,3], \"b\": 2, \"c\": \"hello\"}"_padded;
std::vector<std::string_view> fields;
@@ -2078,7 +2016,6 @@ bool value_raw_json_object() {
}
#endif
bool run() {
return true
&& fatal_error()
@@ -2138,7 +2075,6 @@ bool run() {
&& current_location_no_error()
&& to_string_example_no_except()
#if SIMDJSON_EXCEPTIONS
&& wildcard_basics_example()
&& issue2215()
&& to_string_example()
&& raw_string()
+86 -104
View File
@@ -21,16 +21,18 @@ namespace wildcard_tests {
ondemand::parser parser;
auto doc = parser.iterate(json);
std::vector<std::string_view> titles;
ASSERT_SUCCESS(doc.for_each_at_path_with_wildcard("$.books[*].title", [&](ondemand::value v) {
std::string_view sv;
if (v.get_string().get(sv) == SUCCESS) { titles.push_back(sv); }
}));
std::vector<ondemand::value> titles;
ASSERT_SUCCESS(doc.at_path_with_wildcard("$.books[*].title").get(titles));
ASSERT_EQUAL(titles.size(), 3);
ASSERT_EQUAL(titles[0], "Book A");
ASSERT_EQUAL(titles[1], "Book B");
ASSERT_EQUAL(titles[2], "Book C");
std::string_view title;
ASSERT_SUCCESS(titles[0].get_string().get(title));
ASSERT_EQUAL(title, "Book A");
ASSERT_SUCCESS(titles[1].get_string().get(title));
ASSERT_EQUAL(title, "Book B");
ASSERT_SUCCESS(titles[2].get_string().get(title));
ASSERT_EQUAL(title, "Book C");
TEST_SUCCEED();
}
@@ -44,16 +46,18 @@ namespace wildcard_tests {
ondemand::parser parser;
auto doc = parser.iterate(json);
std::vector<uint64_t> prices;
ASSERT_SUCCESS(doc.for_each_at_path_with_wildcard("$.prices[*]", [&](ondemand::value v) {
uint64_t p;
if (v.get_uint64().get(p) == SUCCESS) { prices.push_back(p); }
}));
std::vector<ondemand::value> prices;
ASSERT_SUCCESS(doc.at_path_with_wildcard("$.prices[*]").get(prices));
ASSERT_EQUAL(prices.size(), 5);
ASSERT_EQUAL(prices[0], 10);
ASSERT_EQUAL(prices[2], 30);
ASSERT_EQUAL(prices[4], 50);
uint64_t price;
ASSERT_SUCCESS(prices[0].get_uint64().get(price));
ASSERT_EQUAL(price, 10);
ASSERT_SUCCESS(prices[2].get_uint64().get(price));
ASSERT_EQUAL(price, 30);
ASSERT_SUCCESS(prices[4].get_uint64().get(price));
ASSERT_EQUAL(price, 50);
TEST_SUCCEED();
}
@@ -71,14 +75,19 @@ namespace wildcard_tests {
ondemand::parser parser;
auto doc = parser.iterate(json);
std::set<std::string_view> name_set;
auto error = doc.for_each_at_path_with_wildcard("$.users.*.name", [&](ondemand::value v) {
std::string_view sv;
if (v.get_string().get(sv) == SUCCESS) { name_set.insert(sv); }
});
std::vector<ondemand::value> names;
auto error = doc.at_path_with_wildcard("$.users.*.name").get(names);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(name_set.size(), 3);
ASSERT_EQUAL(names.size(), 3);
// Verify we got all three names (order may vary)
std::set<std::string_view> name_set;
for (auto& name : names) {
std::string_view view;
ASSERT_SUCCESS(name.get_string().get(view));
name_set.insert(view);
}
ASSERT_TRUE(name_set.count("Alice") > 0);
ASSERT_TRUE(name_set.count("Bob") > 0);
ASSERT_TRUE(name_set.count("Charlie") > 0);
@@ -108,15 +117,19 @@ namespace wildcard_tests {
ondemand::parser parser;
auto doc = parser.iterate(json);
uint64_t total = 0;
size_t count = 0;
auto error = doc.for_each_at_path_with_wildcard("$.departments.*.employees[*].salary", [&](ondemand::value v) {
uint64_t s;
if (v.get_uint64().get(s) == SUCCESS) { total += s; count++; }
});
std::vector<ondemand::value> salaries;
auto error = doc.at_path_with_wildcard("$.departments.*.employees[*].salary").get(salaries);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(count, 4);
ASSERT_EQUAL(salaries.size(), 4);
// Check sum of all salaries
uint64_t total = 0;
for (auto& salary : salaries) {
uint64_t value;
ASSERT_SUCCESS(salary.get_uint64().get(value));
total += value;
}
ASSERT_EQUAL(total, 360000);
TEST_SUCCEED();
@@ -129,12 +142,11 @@ namespace wildcard_tests {
ondemand::parser parser;
auto doc = parser.iterate(json);
size_t count = 0;
auto error = doc.for_each_at_path_with_wildcard("$.items[*].name", [&](ondemand::value) {
count++;
});
std::vector<ondemand::value> items;
auto error = doc.at_path_with_wildcard("$.items[*].name").get(items);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(count, 0);
ASSERT_EQUAL(items.size(), 0);
TEST_SUCCEED();
}
@@ -146,12 +158,11 @@ namespace wildcard_tests {
ondemand::parser parser;
auto doc = parser.iterate(json);
size_t count = 0;
auto error = doc.for_each_at_path_with_wildcard("$.users.*.name", [&](ondemand::value) {
count++;
});
std::vector<ondemand::value> names;
auto error = doc.at_path_with_wildcard("$.users.*.name").get(names);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(count, 0);
ASSERT_EQUAL(names.size(), 0);
TEST_SUCCEED();
}
@@ -164,7 +175,8 @@ namespace wildcard_tests {
auto doc = parser.iterate(json);
// Can't use array wildcard on scalar
auto error = doc.for_each_at_path_with_wildcard("$.data[*]", [](ondemand::value) {});
std::vector<ondemand::value> values;
auto error = doc.at_path_with_wildcard("$.data[*]").get(values);
ASSERT_ERROR(error, INVALID_JSON_POINTER);
TEST_SUCCEED();
@@ -183,12 +195,12 @@ namespace wildcard_tests {
ondemand::parser parser;
auto doc = parser.iterate(json);
size_t count = 0;
ASSERT_SUCCESS(doc.for_each_at_path_with_wildcard("$.matrix[*]", [&](ondemand::value) {
count++;
}));
// Get all nested arrays
std::vector<ondemand::value> arrays;
ASSERT_SUCCESS(doc.at_path_with_wildcard("$.matrix[*]").get(arrays));
ASSERT_EQUAL(count, 3);
// Verify we got 3 arrays
ASSERT_EQUAL(arrays.size(), 3);
TEST_SUCCEED();
}
@@ -206,16 +218,18 @@ namespace wildcard_tests {
ondemand::parser parser;
auto doc = parser.iterate(json);
std::vector<std::string_view> statuses;
ASSERT_SUCCESS(doc.for_each_at_path_with_wildcard("$.data[*].info.status", [&](ondemand::value v) {
std::string_view sv;
if (v.get_string().get(sv) == SUCCESS) { statuses.push_back(sv); }
}));
std::vector<ondemand::value> statuses;
ASSERT_SUCCESS(doc.at_path_with_wildcard("$.data[*].info.status").get(statuses));
ASSERT_EQUAL(statuses.size(), 3);
ASSERT_EQUAL(statuses[0], "active");
ASSERT_EQUAL(statuses[1], "inactive");
ASSERT_EQUAL(statuses[2], "active");
std::string_view status;
ASSERT_SUCCESS(statuses[0].get_string().get(status));
ASSERT_EQUAL(status, "active");
ASSERT_SUCCESS(statuses[1].get_string().get(status));
ASSERT_EQUAL(status, "inactive");
ASSERT_SUCCESS(statuses[2].get_string().get(status));
ASSERT_EQUAL(status, "active");
TEST_SUCCEED();
}
@@ -236,12 +250,13 @@ namespace wildcard_tests {
ondemand::parser parser;
auto doc = parser.iterate(json);
size_t count = 0;
ASSERT_SUCCESS(doc.for_each_at_path_with_wildcard("$.mixed[*]", [&](ondemand::value) {
count++;
}));
std::vector<ondemand::value> values;
ASSERT_SUCCESS(doc.at_path_with_wildcard("$.mixed[*]").get(values));
ASSERT_EQUAL(count, 6);
// Just verify we got all 6 elements
ASSERT_EQUAL(values.size(), 6);
// Don't try to access the values - they've been consumed by the OnDemand API
TEST_SUCCEED();
}
@@ -260,11 +275,8 @@ namespace wildcard_tests {
auto doc = parser.iterate(json);
// Third element doesn't have "name" field
std::vector<std::string_view> names;
auto error = doc.for_each_at_path_with_wildcard("$.data[*].name", [&](ondemand::value v) {
std::string_view sv;
if (v.get_string().get(sv) == SUCCESS) { names.push_back(sv); }
});
std::vector<ondemand::value> names;
auto error = doc.at_path_with_wildcard("$.data[*].name").get(names);
// This might error or return partial results
if (error) {
@@ -289,47 +301,18 @@ namespace wildcard_tests {
ondemand::parser parser;
auto doc = parser.iterate(json);
std::vector<std::string_view> names;
ASSERT_SUCCESS(doc.for_each_at_path_with_wildcard("$[*].name", [&](ondemand::value v) {
std::string_view sv;
if (v.get_string().get(sv) == SUCCESS) { names.push_back(sv); }
}));
std::vector<ondemand::value> names;
ASSERT_SUCCESS(doc.at_path_with_wildcard("$[*].name").get(names));
ASSERT_EQUAL(names.size(), 3);
ASSERT_EQUAL(names[0], "Item 1");
ASSERT_EQUAL(names[1], "Item 2");
ASSERT_EQUAL(names[2], "Item 3");
TEST_SUCCEED();
}
// https://github.com/simdjson/simdjson/issues/2684
bool wildcard_raw_json_issue_2684() {
TEST_START();
auto json = R"([{"tag_meta":{"meta_code":2000211,"meta_value":""},"tag_value":""}])"_padded;
ondemand::parser parser;
auto doc = parser.iterate(json);
size_t count = 0;
bool raw_json_ok = true;
ASSERT_SUCCESS(doc.for_each_at_path_with_wildcard("$[*].tag_meta", [&](ondemand::value v) {
count++;
std::string_view raw;
if (v.raw_json().get(raw) != SUCCESS) {
raw_json_ok = false;
return;
}
// raw_json() must not leak sibling fields or outer array delimiters
std::string_view expected = R"({"meta_code":2000211,"meta_value":""})";
if (raw != expected || raw.find("tag_value") != std::string_view::npos) {
std::cerr << " raw_json() returned: " << raw << std::endl;
raw_json_ok = false;
}
}));
ASSERT_EQUAL(count, 1);
ASSERT_TRUE(raw_json_ok);
std::string_view name;
ASSERT_SUCCESS(names[0].get_string().get(name));
ASSERT_EQUAL(name, "Item 1");
ASSERT_SUCCESS(names[1].get_string().get(name));
ASSERT_EQUAL(name, "Item 2");
ASSERT_SUCCESS(names[2].get_string().get(name));
ASSERT_EQUAL(name, "Item 3");
TEST_SUCCEED();
}
@@ -346,11 +329,10 @@ namespace wildcard_tests {
wildcard_with_nested_objects() &&
mixed_types_in_array() &&
wildcard_nonexistent_field() &&
root_array_wildcard() &&
wildcard_raw_json_issue_2684();
root_array_wildcard();
}
}
int main(int argc, char *argv[]) {
return test_main(argc, argv, wildcard_tests::run);
}
}