Merge branch 'develop' of https://github.com/nlohmann/json into issue2286
Conflicts: single_include/nlohmann/json.hpp
This commit is contained in:
commit
42f8708940
22 changed files with 2770 additions and 2785 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -22,7 +22,7 @@ benchmarks/files/numbers/*.json
|
||||||
.wsjcpp/*
|
.wsjcpp/*
|
||||||
|
|
||||||
.idea
|
.idea
|
||||||
cmake-build-debug
|
/cmake-build-*
|
||||||
|
|
||||||
test/test-*
|
test/test-*
|
||||||
/.vs
|
/.vs
|
||||||
|
@ -32,3 +32,4 @@ doc/mkdocs/docs/images
|
||||||
doc/mkdocs/docs/examples
|
doc/mkdocs/docs/examples
|
||||||
doc/mkdocs/site
|
doc/mkdocs/site
|
||||||
doc/mkdocs/docs/__pycache__/
|
doc/mkdocs/docs/__pycache__/
|
||||||
|
doc/xml
|
||||||
|
|
|
@ -24,7 +24,7 @@ endif ()
|
||||||
option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ON)
|
option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ON)
|
||||||
option(JSON_Install "Install CMake targets during install step." ON)
|
option(JSON_Install "Install CMake targets during install step." ON)
|
||||||
option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OFF)
|
option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OFF)
|
||||||
option(JSON_ImplicitConversions "Enable implicit conversions" ON)
|
option(JSON_ImplicitConversions "Enable implicit conversions." ON)
|
||||||
|
|
||||||
##
|
##
|
||||||
## CONFIGURATION
|
## CONFIGURATION
|
||||||
|
@ -49,6 +49,10 @@ else()
|
||||||
message(STATUS "Using the single-header code from ${NLOHMANN_JSON_INCLUDE_BUILD_DIR}")
|
message(STATUS "Using the single-header code from ${NLOHMANN_JSON_INCLUDE_BUILD_DIR}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (NOT JSON_ImplicitConversions)
|
||||||
|
message(STATUS "Implicit conversions are disabled")
|
||||||
|
endif()
|
||||||
|
|
||||||
##
|
##
|
||||||
## TARGET
|
## TARGET
|
||||||
## create target and add include path
|
## create target and add include path
|
||||||
|
|
78
Makefile
78
Makefile
|
@ -54,13 +54,13 @@ all:
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
rm -fr build_coverage
|
rm -fr cmake-build-coverage
|
||||||
mkdir build_coverage
|
mkdir cmake-build-coverage
|
||||||
cd build_coverage ; cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_Coverage=ON -DJSON_MultipleHeaders=ON
|
cd cmake-build-coverage ; cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_Coverage=ON -DJSON_MultipleHeaders=ON
|
||||||
cd build_coverage ; ninja
|
cd cmake-build-coverage ; ninja
|
||||||
cd build_coverage ; ctest -j10
|
cd cmake-build-coverage ; ctest -j10
|
||||||
cd build_coverage ; ninja lcov_html
|
cd cmake-build-coverage ; ninja lcov_html
|
||||||
open build_coverage/test/html/index.html
|
open cmake-build-coverage/test/html/index.html
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# documentation tests
|
# documentation tests
|
||||||
|
@ -88,7 +88,7 @@ doctest:
|
||||||
# -Wno-switch-enum -Wno-covered-switch-default: pedantic/contradicting warnings about switches
|
# -Wno-switch-enum -Wno-covered-switch-default: pedantic/contradicting warnings about switches
|
||||||
# -Wno-weak-vtables: exception class is defined inline, but has virtual method
|
# -Wno-weak-vtables: exception class is defined inline, but has virtual method
|
||||||
pedantic_clang:
|
pedantic_clang:
|
||||||
rm -fr build_pedantic
|
rm -fr cmake-build-pedantic
|
||||||
CXXFLAGS=" \
|
CXXFLAGS=" \
|
||||||
-std=c++11 -Wno-c++98-compat -Wno-c++98-compat-pedantic \
|
-std=c++11 -Wno-c++98-compat -Wno-c++98-compat-pedantic \
|
||||||
-Werror \
|
-Werror \
|
||||||
|
@ -103,12 +103,12 @@ pedantic_clang:
|
||||||
-Wno-padded \
|
-Wno-padded \
|
||||||
-Wno-range-loop-analysis \
|
-Wno-range-loop-analysis \
|
||||||
-Wno-switch-enum -Wno-covered-switch-default \
|
-Wno-switch-enum -Wno-covered-switch-default \
|
||||||
-Wno-weak-vtables" cmake -S . -B build_pedantic -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On
|
-Wno-weak-vtables" cmake -S . -B cmake-build-pedantic -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On
|
||||||
cmake --build build_pedantic
|
cmake --build cmake-build-pedantic
|
||||||
|
|
||||||
# calling GCC with most warnings
|
# calling GCC with most warnings
|
||||||
pedantic_gcc:
|
pedantic_gcc:
|
||||||
rm -fr build_pedantic
|
rm -fr cmake-build-pedantic
|
||||||
CXXFLAGS=" \
|
CXXFLAGS=" \
|
||||||
-std=c++11 \
|
-std=c++11 \
|
||||||
-pedantic \
|
-pedantic \
|
||||||
|
@ -366,19 +366,19 @@ pedantic_gcc:
|
||||||
-Wwrite-strings \
|
-Wwrite-strings \
|
||||||
-Wzero-as-null-pointer-constant \
|
-Wzero-as-null-pointer-constant \
|
||||||
-Wzero-length-bounds \
|
-Wzero-length-bounds \
|
||||||
" cmake -S . -B build_pedantic -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On
|
" cmake -S . -B cmake-build-pedantic -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On
|
||||||
cmake --build build_pedantic
|
cmake --build cmake-build-pedantic
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# benchmarks
|
# benchmarks
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
run_benchmarks:
|
run_benchmarks:
|
||||||
rm -fr build_benchmarks
|
rm -fr cmake-build-benchmarks
|
||||||
mkdir build_benchmarks
|
mkdir cmake-build-benchmarks
|
||||||
cd build_benchmarks ; cmake ../benchmarks -GNinja -DCMAKE_BUILD_TYPE=Release -DJSON_BuildTests=On
|
cd cmake-build-benchmarks ; cmake ../benchmarks -GNinja -DCMAKE_BUILD_TYPE=Release -DJSON_BuildTests=On
|
||||||
cd build_benchmarks ; ninja
|
cd cmake-build-benchmarks ; ninja
|
||||||
cd build_benchmarks ; ./json_benchmarks
|
cd cmake-build-benchmarks ; ./json_benchmarks
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# fuzzing
|
# fuzzing
|
||||||
|
@ -451,14 +451,14 @@ cppcheck:
|
||||||
|
|
||||||
# call Clang Static Analyzer <https://clang-analyzer.llvm.org>
|
# call Clang Static Analyzer <https://clang-analyzer.llvm.org>
|
||||||
clang_analyze:
|
clang_analyze:
|
||||||
rm -fr clang_analyze_build
|
rm -fr cmake-build-clang-analyze
|
||||||
mkdir clang_analyze_build
|
mkdir cmake-build-clang-analyze
|
||||||
cd clang_analyze_build ; CCC_CXX=$(COMPILER_DIR)/clang++ CXX=$(COMPILER_DIR)/clang++ $(COMPILER_DIR)/scan-build cmake .. -GNinja -DJSON_BuildTests=On
|
cd cmake-build-clang-analyze ; CCC_CXX=$(COMPILER_DIR)/clang++ CXX=$(COMPILER_DIR)/clang++ $(COMPILER_DIR)/scan-build cmake .. -GNinja -DJSON_BuildTests=On
|
||||||
cd clang_analyze_build ; \
|
cd cmake-build-clang-analyze ; \
|
||||||
$(COMPILER_DIR)/scan-build \
|
$(COMPILER_DIR)/scan-build \
|
||||||
-enable-checker alpha.core.BoolAssignment,alpha.core.CallAndMessageUnInitRefArg,alpha.core.CastSize,alpha.core.CastToStruct,alpha.core.Conversion,alpha.core.DynamicTypeChecker,alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,alpha.core.SizeofPtr,alpha.core.StackAddressAsyncEscape,alpha.core.TestAfterDivZero,alpha.deadcode.UnreachableCode,core.builtin.BuiltinFunctions,core.builtin.NoReturnFunctions,core.CallAndMessage,core.DivideZero,core.DynamicTypePropagation,core.NonnilStringConstants,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,core.VLASize,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.SelfAssignment,deadcode.DeadStores,nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull \
|
-enable-checker alpha.core.BoolAssignment,alpha.core.CallAndMessageUnInitRefArg,alpha.core.CastSize,alpha.core.CastToStruct,alpha.core.Conversion,alpha.core.DynamicTypeChecker,alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,alpha.core.SizeofPtr,alpha.core.StackAddressAsyncEscape,alpha.core.TestAfterDivZero,alpha.deadcode.UnreachableCode,core.builtin.BuiltinFunctions,core.builtin.NoReturnFunctions,core.CallAndMessage,core.DivideZero,core.DynamicTypePropagation,core.NonnilStringConstants,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,core.VLASize,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.SelfAssignment,deadcode.DeadStores,nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull \
|
||||||
--use-c++=$(COMPILER_DIR)/clang++ -analyze-headers -o report ninja
|
--use-c++=$(COMPILER_DIR)/clang++ -analyze-headers -o report ninja
|
||||||
open clang_analyze_build/report/*/index.html
|
open cmake-build-clang-analyze/report/*/index.html
|
||||||
|
|
||||||
# call cpplint <https://github.com/cpplint/cpplint>
|
# call cpplint <https://github.com/cpplint/cpplint>
|
||||||
# Note: some errors expected due to false positives
|
# Note: some errors expected due to false positives
|
||||||
|
@ -473,18 +473,18 @@ clang_tidy:
|
||||||
|
|
||||||
# call PVS-Studio Analyzer <https://www.viva64.com/en/pvs-studio/>
|
# call PVS-Studio Analyzer <https://www.viva64.com/en/pvs-studio/>
|
||||||
pvs_studio:
|
pvs_studio:
|
||||||
rm -fr pvs_studio_build
|
rm -fr cmake-build-pvs-studio
|
||||||
mkdir pvs_studio_build
|
mkdir cmake-build-pvs-studio
|
||||||
cd pvs_studio_build ; cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DJSON_MultipleHeaders=ON
|
cd cmake-build-pvs-studio ; cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DJSON_MultipleHeaders=ON
|
||||||
cd pvs_studio_build ; pvs-studio-analyzer analyze -j 10
|
cd cmake-build-pvs-studio ; pvs-studio-analyzer analyze -j 10
|
||||||
cd pvs_studio_build ; plog-converter -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs
|
cd cmake-build-pvs-studio ; plog-converter -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs
|
||||||
open pvs_studio_build/pvs/index.html
|
open cmake-build-pvs-studio/pvs/index.html
|
||||||
|
|
||||||
# call Infer <https://fbinfer.com> static analyzer
|
# call Infer <https://fbinfer.com> static analyzer
|
||||||
infer:
|
infer:
|
||||||
rm -fr infer_build
|
rm -fr cmake-build-infer
|
||||||
mkdir infer_build
|
mkdir cmake-build-infer
|
||||||
cd infer_build ; infer compile -- cmake .. -DJSON_MultipleHeaders=ON ; infer run -- make -j 4
|
cd cmake-build-infer ; infer compile -- cmake .. -DJSON_MultipleHeaders=ON ; infer run -- make -j 4
|
||||||
|
|
||||||
# call OCLint <http://oclint.org> static analyzer
|
# call OCLint <http://oclint.org> static analyzer
|
||||||
oclint:
|
oclint:
|
||||||
|
@ -493,11 +493,11 @@ oclint:
|
||||||
|
|
||||||
# execute the test suite with Clang sanitizers (address and undefined behavior)
|
# execute the test suite with Clang sanitizers (address and undefined behavior)
|
||||||
clang_sanitize:
|
clang_sanitize:
|
||||||
rm -fr clang_sanitize_build
|
rm -fr cmake-build-clang-sanitize
|
||||||
mkdir clang_sanitize_build
|
mkdir cmake-build-clang-sanitize
|
||||||
cd clang_sanitize_build ; CXX=$(COMPILER_DIR)/clang++ cmake .. -DJSON_Sanitizer=On -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On -GNinja
|
cd cmake-build-clang-sanitize ; CXX=$(COMPILER_DIR)/clang++ cmake .. -DJSON_Sanitizer=On -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On -GNinja
|
||||||
cd clang_sanitize_build ; ninja
|
cd cmake-build-clang-sanitize ; ninja
|
||||||
cd clang_sanitize_build ; ctest -j10
|
cd cmake-build-clang-sanitize ; ctest -j10
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
@ -525,7 +525,7 @@ pretty:
|
||||||
--preserve-date \
|
--preserve-date \
|
||||||
--suffix=none \
|
--suffix=none \
|
||||||
--formatted \
|
--formatted \
|
||||||
$(SRCS) $(AMALGAMATED_FILE) test/src/*.cpp benchmarks/src/benchmarks.cpp doc/examples/*.cpp
|
$(SRCS) $(AMALGAMATED_FILE) test/src/*.cpp test/utils/*.hpp benchmarks/src/benchmarks.cpp doc/examples/*.cpp
|
||||||
|
|
||||||
# create single header file
|
# create single header file
|
||||||
amalgamate: $(AMALGAMATED_FILE)
|
amalgamate: $(AMALGAMATED_FILE)
|
||||||
|
@ -625,7 +625,7 @@ clean:
|
||||||
rm -fr json_unit json_benchmarks fuzz fuzz-testing *.dSYM test/*.dSYM oclint_report.html
|
rm -fr json_unit json_benchmarks fuzz fuzz-testing *.dSYM test/*.dSYM oclint_report.html
|
||||||
rm -fr benchmarks/files/numbers/*.json
|
rm -fr benchmarks/files/numbers/*.json
|
||||||
rm -fr cmake-3.1.0-Darwin64.tar.gz cmake-3.1.0-Darwin64
|
rm -fr cmake-3.1.0-Darwin64.tar.gz cmake-3.1.0-Darwin64
|
||||||
rm -fr build_coverage build_benchmarks fuzz-testing clang_analyze_build pvs_studio_build infer_build clang_sanitize_build cmake_build
|
rm -fr cmake-build-coverage cmake-build-benchmarks fuzz-testing cmake-build-clang-analyze cmake-build-pvs-studio cmake-build-infer cmake-build-clang-sanitize cmake_build
|
||||||
$(MAKE) clean -Cdoc
|
$(MAKE) clean -Cdoc
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
|
@ -762,6 +762,7 @@ Supported types can be implicitly converted to JSON values.
|
||||||
|
|
||||||
It is recommended to **NOT USE** implicit conversions **FROM** a JSON value.
|
It is recommended to **NOT USE** implicit conversions **FROM** a JSON value.
|
||||||
You can find more details about this recommendation [here](https://www.github.com/nlohmann/json/issues/958).
|
You can find more details about this recommendation [here](https://www.github.com/nlohmann/json/issues/958).
|
||||||
|
You can switch off implicit conversions by defining `JSON_USE_IMPLICIT_CONVERSIONS` to `0` before including the `json.hpp` header. When using CMake, you can also achieve this by setting the option `JSON_ImplicitConversions` to `OFF`.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
// strings
|
// strings
|
||||||
|
|
|
@ -92,6 +92,10 @@ There are two macros to make your life easier as long as you (1) want to use a J
|
||||||
|
|
||||||
In both macros, the first parameter is the name of the class/struct, and all remaining parameters name the members.
|
In both macros, the first parameter is the name of the class/struct, and all remaining parameters name the members.
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
At most 64 member variables can be passed to `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` or `NLOHMANN_DEFINE_TYPE_INTRUSIVE`.
|
||||||
|
|
||||||
??? example
|
??? example
|
||||||
|
|
||||||
The `to_json`/`from_json` functions for the `person` struct above can be created with:
|
The `to_json`/`from_json` functions for the `person` struct above can be created with:
|
||||||
|
|
|
@ -32,6 +32,26 @@ This macro overrides `#!cpp try` calls inside the library. It has no arguments a
|
||||||
|
|
||||||
See [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example.
|
See [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example.
|
||||||
|
|
||||||
|
## `JSON_USE_IMPLICIT_CONVERSIONS`
|
||||||
|
|
||||||
|
When defined to `0`, implicit conversions are switched off. By default, implicit conversions are switched on.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
This is an example for an implicit conversion:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
json j = "Hello, world!";
|
||||||
|
std::string s = j;
|
||||||
|
```
|
||||||
|
|
||||||
|
When `JSON_USE_IMPLICIT_CONVERSIONS` is defined to `0`, the code above does no longer compile. Instead, it must be written like this:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
json j = "Hello, world!";
|
||||||
|
auto s = j.get<std::string>();
|
||||||
|
```
|
||||||
|
|
||||||
## `NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)`
|
## `NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)`
|
||||||
|
|
||||||
This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object.
|
This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object.
|
||||||
|
|
|
@ -394,14 +394,14 @@ class binary_reader
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@param[in] get_char whether a new character should be retrieved from the
|
@param[in] get_char whether a new character should be retrieved from the
|
||||||
input (true, default) or whether the last read
|
input (true) or whether the last read character should
|
||||||
character should be considered instead
|
be considered instead (false)
|
||||||
@param[in] tag_handler how CBOR tags should be treated
|
@param[in] tag_handler how CBOR tags should be treated
|
||||||
|
|
||||||
@return whether a valid CBOR value was passed to the SAX parser
|
@return whether a valid CBOR value was passed to the SAX parser
|
||||||
*/
|
*/
|
||||||
bool parse_cbor_internal(const bool get_char = true,
|
bool parse_cbor_internal(const bool get_char,
|
||||||
cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
|
const cbor_tag_handler_t tag_handler)
|
||||||
{
|
{
|
||||||
switch (get_char ? get() : current)
|
switch (get_char ? get() : current)
|
||||||
{
|
{
|
||||||
|
@ -607,34 +607,34 @@ class binary_reader
|
||||||
case 0x95:
|
case 0x95:
|
||||||
case 0x96:
|
case 0x96:
|
||||||
case 0x97:
|
case 0x97:
|
||||||
return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
|
return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
|
||||||
|
|
||||||
case 0x98: // array (one-byte uint8_t for n follows)
|
case 0x98: // array (one-byte uint8_t for n follows)
|
||||||
{
|
{
|
||||||
std::uint8_t len{};
|
std::uint8_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x99: // array (two-byte uint16_t for n follow)
|
case 0x99: // array (two-byte uint16_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint16_t len{};
|
std::uint16_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x9A: // array (four-byte uint32_t for n follow)
|
case 0x9A: // array (four-byte uint32_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint32_t len{};
|
std::uint32_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x9B: // array (eight-byte uint64_t for n follow)
|
case 0x9B: // array (eight-byte uint64_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint64_t len{};
|
std::uint64_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x9F: // array (indefinite length)
|
case 0x9F: // array (indefinite length)
|
||||||
return get_cbor_array(std::size_t(-1));
|
return get_cbor_array(std::size_t(-1), tag_handler);
|
||||||
|
|
||||||
// map (0x00..0x17 pairs of data items follow)
|
// map (0x00..0x17 pairs of data items follow)
|
||||||
case 0xA0:
|
case 0xA0:
|
||||||
|
@ -661,34 +661,34 @@ class binary_reader
|
||||||
case 0xB5:
|
case 0xB5:
|
||||||
case 0xB6:
|
case 0xB6:
|
||||||
case 0xB7:
|
case 0xB7:
|
||||||
return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
|
return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
|
||||||
|
|
||||||
case 0xB8: // map (one-byte uint8_t for n follows)
|
case 0xB8: // map (one-byte uint8_t for n follows)
|
||||||
{
|
{
|
||||||
std::uint8_t len{};
|
std::uint8_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xB9: // map (two-byte uint16_t for n follow)
|
case 0xB9: // map (two-byte uint16_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint16_t len{};
|
std::uint16_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xBA: // map (four-byte uint32_t for n follow)
|
case 0xBA: // map (four-byte uint32_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint32_t len{};
|
std::uint32_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xBB: // map (eight-byte uint64_t for n follow)
|
case 0xBB: // map (eight-byte uint64_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint64_t len{};
|
std::uint64_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xBF: // map (indefinite length)
|
case 0xBF: // map (indefinite length)
|
||||||
return get_cbor_object(std::size_t(-1));
|
return get_cbor_object(std::size_t(-1), tag_handler);
|
||||||
|
|
||||||
case 0xC6: // tagged item
|
case 0xC6: // tagged item
|
||||||
case 0xC7:
|
case 0xC7:
|
||||||
|
@ -1031,9 +1031,11 @@ class binary_reader
|
||||||
/*!
|
/*!
|
||||||
@param[in] len the length of the array or std::size_t(-1) for an
|
@param[in] len the length of the array or std::size_t(-1) for an
|
||||||
array of indefinite size
|
array of indefinite size
|
||||||
|
@param[in] tag_handler how CBOR tags should be treated
|
||||||
@return whether array creation completed
|
@return whether array creation completed
|
||||||
*/
|
*/
|
||||||
bool get_cbor_array(const std::size_t len)
|
bool get_cbor_array(const std::size_t len,
|
||||||
|
const cbor_tag_handler_t tag_handler)
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
|
if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
|
||||||
{
|
{
|
||||||
|
@ -1044,7 +1046,7 @@ class binary_reader
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < len; ++i)
|
for (std::size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal()))
|
if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1054,7 +1056,7 @@ class binary_reader
|
||||||
{
|
{
|
||||||
while (get() != 0xFF)
|
while (get() != 0xFF)
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false)))
|
if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1067,9 +1069,11 @@ class binary_reader
|
||||||
/*!
|
/*!
|
||||||
@param[in] len the length of the object or std::size_t(-1) for an
|
@param[in] len the length of the object or std::size_t(-1) for an
|
||||||
object of indefinite size
|
object of indefinite size
|
||||||
|
@param[in] tag_handler how CBOR tags should be treated
|
||||||
@return whether object creation completed
|
@return whether object creation completed
|
||||||
*/
|
*/
|
||||||
bool get_cbor_object(const std::size_t len)
|
bool get_cbor_object(const std::size_t len,
|
||||||
|
const cbor_tag_handler_t tag_handler)
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
|
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
|
||||||
{
|
{
|
||||||
|
@ -1087,7 +1091,7 @@ class binary_reader
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal()))
|
if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1103,7 +1107,7 @@ class binary_reader
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal()))
|
if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,8 +264,8 @@
|
||||||
#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
|
#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
|
||||||
#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
|
#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
|
||||||
|
|
||||||
#define NLOHMANN_JSON_TO(v1) j[#v1] = t.v1;
|
#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
|
||||||
#define NLOHMANN_JSON_FROM(v1) j.at(#v1).get_to(t.v1);
|
#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
|
@ -273,8 +273,8 @@
|
||||||
@since version 3.9.0
|
@since version 3.9.0
|
||||||
*/
|
*/
|
||||||
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
|
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
|
||||||
friend void to_json(nlohmann::json& j, const Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
||||||
friend void from_json(const nlohmann::json& j, Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
|
@ -282,8 +282,8 @@
|
||||||
@since version 3.9.0
|
@since version 3.9.0
|
||||||
*/
|
*/
|
||||||
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
|
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
|
||||||
void to_json(nlohmann::json& j, const Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
||||||
void from_json(const nlohmann::json& j, Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
||||||
|
|
||||||
#ifndef JSON_USE_IMPLICIT_CONVERSIONS
|
#ifndef JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
#define JSON_USE_IMPLICIT_CONVERSIONS 1
|
#define JSON_USE_IMPLICIT_CONVERSIONS 1
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -151,7 +151,7 @@ foreach(file ${files})
|
||||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
|
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
|
||||||
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
||||||
)
|
)
|
||||||
target_include_directories(${testcase} PRIVATE ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map)
|
target_include_directories(${testcase} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/utils ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map)
|
||||||
target_link_libraries(${testcase} PRIVATE ${NLOHMANN_JSON_TARGET_NAME})
|
target_link_libraries(${testcase} PRIVATE ${NLOHMANN_JSON_TARGET_NAME})
|
||||||
|
|
||||||
if (JSON_Coverage)
|
if (JSON_Coverage)
|
||||||
|
|
3
test/cmake_target_include_directories/project/Bar.cpp
Normal file
3
test/cmake_target_include_directories/project/Bar.cpp
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#include "Bar.hpp"
|
||||||
|
|
||||||
|
class Bar;
|
4
test/cmake_target_include_directories/project/Bar.hpp
Normal file
4
test/cmake_target_include_directories/project/Bar.hpp
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include "Foo.hpp"
|
||||||
|
|
||||||
|
class Bar : public Foo{};
|
|
@ -9,3 +9,13 @@ set_target_properties(with_private_target PROPERTIES CXX_STANDARD 11)
|
||||||
add_executable(with_private_system_target main.cpp)
|
add_executable(with_private_system_target main.cpp)
|
||||||
target_include_directories(with_private_system_target PRIVATE SYSTEM ${nlohmann_json_source}/include)
|
target_include_directories(with_private_system_target PRIVATE SYSTEM ${nlohmann_json_source}/include)
|
||||||
set_target_properties(with_private_system_target PROPERTIES CXX_STANDARD 11)
|
set_target_properties(with_private_system_target PROPERTIES CXX_STANDARD 11)
|
||||||
|
|
||||||
|
# regression from https://github.com/nlohmann/json/discussions/2281
|
||||||
|
add_library(Foo STATIC Foo.cpp Bar.cpp)
|
||||||
|
target_include_directories(Foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include)
|
||||||
|
set_target_properties(Foo PROPERTIES CXX_STANDARD 11)
|
||||||
|
|
||||||
|
add_library(Bar STATIC Bar.cpp)
|
||||||
|
target_link_libraries(Bar PRIVATE Foo)
|
||||||
|
target_include_directories(Bar PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include)
|
||||||
|
set_target_properties(Bar PROPERTIES CXX_STANDARD 11)
|
||||||
|
|
3
test/cmake_target_include_directories/project/Foo.cpp
Normal file
3
test/cmake_target_include_directories/project/Foo.cpp
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#include "Foo.hpp"
|
||||||
|
|
||||||
|
class Foo;
|
4
test/cmake_target_include_directories/project/Foo.hpp
Normal file
4
test/cmake_target_include_directories/project/Foo.hpp
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#pragma once
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
class Foo{};
|
|
@ -35,6 +35,7 @@ using nlohmann::json;
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <test_data.hpp>
|
#include <test_data.hpp>
|
||||||
|
#include <test_utils.hpp>
|
||||||
|
|
||||||
TEST_CASE("BSON")
|
TEST_CASE("BSON")
|
||||||
{
|
{
|
||||||
|
@ -1263,10 +1264,7 @@ TEST_CASE("BSON roundtrips" * doctest::skip())
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse BSON file
|
// parse BSON file
|
||||||
std::ifstream f_bson(filename + ".bson", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".bson");
|
||||||
std::vector<std::uint8_t> packed(
|
|
||||||
(std::istreambuf_iterator<char>(f_bson)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_bson(packed));
|
CHECK_NOTHROW(j2 = json::from_bson(packed));
|
||||||
|
|
||||||
|
@ -1296,10 +1294,7 @@ TEST_CASE("BSON roundtrips" * doctest::skip())
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse BSON file
|
// parse BSON file
|
||||||
std::ifstream f_bson(filename + ".bson", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".bson");
|
||||||
std::vector<std::uint8_t> packed(
|
|
||||||
(std::istreambuf_iterator<char>(f_bson)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_bson({packed.data(), packed.size()}));
|
CHECK_NOTHROW(j2 = json::from_bson({packed.data(), packed.size()}));
|
||||||
|
|
||||||
|
@ -1314,10 +1309,7 @@ TEST_CASE("BSON roundtrips" * doctest::skip())
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse BSON file
|
// parse BSON file
|
||||||
std::ifstream f_bson(filename + ".bson", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".bson");
|
||||||
std::vector<std::uint8_t> packed(
|
|
||||||
(std::istreambuf_iterator<char>(f_bson)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
|
|
||||||
{
|
{
|
||||||
INFO_WITH_TEMP(filename + ": output adapters: std::vector<std::uint8_t>");
|
INFO_WITH_TEMP(filename + ": output adapters: std::vector<std::uint8_t>");
|
||||||
|
|
|
@ -39,6 +39,7 @@ using nlohmann::json;
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <test_data.hpp>
|
#include <test_data.hpp>
|
||||||
|
#include <test_utils.hpp>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -1920,9 +1921,7 @@ TEST_CASE("single CBOR roundtrip")
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse CBOR file
|
// parse CBOR file
|
||||||
std::ifstream f_cbor(filename + ".cbor", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".cbor");
|
||||||
std::vector<uint8_t> packed((std::istreambuf_iterator<char>(f_cbor)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_cbor(packed));
|
CHECK_NOTHROW(j2 = json::from_cbor(packed));
|
||||||
|
|
||||||
|
@ -1994,10 +1993,7 @@ TEST_CASE("CBOR regressions")
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// parse CBOR file
|
// parse CBOR file
|
||||||
std::ifstream f_cbor(filename, std::ios::binary);
|
auto vec1 = utils::read_binary_file(filename);
|
||||||
std::vector<uint8_t> vec1(
|
|
||||||
(std::istreambuf_iterator<char>(f_cbor)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
json j1 = json::from_cbor(vec1);
|
json j1 = json::from_cbor(vec1);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -2204,10 +2200,7 @@ TEST_CASE("CBOR roundtrips" * doctest::skip())
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse CBOR file
|
// parse CBOR file
|
||||||
std::ifstream f_cbor(filename + ".cbor", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".cbor");
|
||||||
std::vector<uint8_t> packed(
|
|
||||||
(std::istreambuf_iterator<char>(f_cbor)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_cbor(packed));
|
CHECK_NOTHROW(j2 = json::from_cbor(packed));
|
||||||
|
|
||||||
|
@ -2237,10 +2230,7 @@ TEST_CASE("CBOR roundtrips" * doctest::skip())
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse CBOR file
|
// parse CBOR file
|
||||||
std::ifstream f_cbor(filename + ".cbor", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".cbor");
|
||||||
std::vector<uint8_t> packed(
|
|
||||||
(std::istreambuf_iterator<char>(f_cbor)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_cbor({packed.data(), packed.size()}));
|
CHECK_NOTHROW(j2 = json::from_cbor({packed.data(), packed.size()}));
|
||||||
|
|
||||||
|
@ -2255,10 +2245,7 @@ TEST_CASE("CBOR roundtrips" * doctest::skip())
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse CBOR file
|
// parse CBOR file
|
||||||
std::ifstream f_cbor(filename + ".cbor", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".cbor");
|
||||||
std::vector<uint8_t> packed(
|
|
||||||
(std::istreambuf_iterator<char>(f_cbor)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
|
|
||||||
if (!exclude_packed.count(filename))
|
if (!exclude_packed.count(filename))
|
||||||
{
|
{
|
||||||
|
@ -2493,15 +2480,11 @@ TEST_CASE("examples from RFC 7049 Appendix A")
|
||||||
|
|
||||||
SECTION("byte arrays")
|
SECTION("byte arrays")
|
||||||
{
|
{
|
||||||
std::ifstream f_cbor(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.cbor", std::ios::binary);
|
auto packed = utils::read_binary_file(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.cbor");
|
||||||
std::vector<uint8_t> packed((std::istreambuf_iterator<char>(f_cbor)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
json j;
|
json j;
|
||||||
CHECK_NOTHROW(j = json::from_cbor(packed));
|
CHECK_NOTHROW(j = json::from_cbor(packed));
|
||||||
|
|
||||||
std::ifstream f_bin(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.out", std::ios::binary);
|
auto expected = utils::read_binary_file(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.out");
|
||||||
std::vector<uint8_t> expected((std::istreambuf_iterator<char>(f_bin)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
CHECK(j == json::binary(expected));
|
CHECK(j == json::binary(expected));
|
||||||
|
|
||||||
CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)) == std::vector<uint8_t> {0xd8, 0x42, 0x40});
|
CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)) == std::vector<uint8_t> {0xd8, 0x42, 0x40});
|
||||||
|
@ -2722,4 +2705,25 @@ TEST_CASE("Tagged values")
|
||||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("tagged binary")
|
||||||
|
{
|
||||||
|
// create a binary value of subtype 42
|
||||||
|
json j;
|
||||||
|
j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);
|
||||||
|
|
||||||
|
// convert to CBOR
|
||||||
|
const auto v = json::to_cbor(j);
|
||||||
|
CHECK(v == std::vector<std::uint8_t> {0xA1, 0x66, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79, 0xD8, 0x2A, 0x44, 0xCA, 0xFE, 0xBA, 0xBE});
|
||||||
|
|
||||||
|
// parse error when parsing tagged value
|
||||||
|
CHECK_THROWS_AS(json::from_cbor(v), json::parse_error);
|
||||||
|
CHECK_THROWS_WITH(json::from_cbor(v), "[json.exception.parse_error.112] parse error at byte 9: syntax error while parsing CBOR value: invalid byte: 0xD8");
|
||||||
|
|
||||||
|
// binary without subtype when tags are ignored
|
||||||
|
json jb = json::from_cbor(v, true, true, json::cbor_tag_handler_t::ignore);
|
||||||
|
CHECK(jb.is_object());
|
||||||
|
CHECK(jb["binary"].is_binary());
|
||||||
|
CHECK(!jb["binary"].get_binary().has_subtype());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,8 +278,8 @@ TEST_CASE("value conversion")
|
||||||
SECTION("reserve is called on containers that supports it")
|
SECTION("reserve is called on containers that supports it")
|
||||||
{
|
{
|
||||||
// make sure all values are properly copied
|
// make sure all values are properly copied
|
||||||
json j({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
|
json j2({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
|
||||||
auto v2 = j.get<std::vector<int>>();
|
auto v2 = j2.get<std::vector<int>>();
|
||||||
CHECK(v2.size() == 10);
|
CHECK(v2.size() == 10);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,6 +37,7 @@ using nlohmann::json;
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <test_data.hpp>
|
#include <test_data.hpp>
|
||||||
|
#include <test_utils.hpp>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -514,7 +515,7 @@ TEST_CASE("MessagePack")
|
||||||
(static_cast<uint32_t>(result[2]) << 020) +
|
(static_cast<uint32_t>(result[2]) << 020) +
|
||||||
(static_cast<uint32_t>(result[3]) << 010) +
|
(static_cast<uint32_t>(result[3]) << 010) +
|
||||||
static_cast<uint32_t>(result[4]);
|
static_cast<uint32_t>(result[4]);
|
||||||
CHECK(restored == i);
|
CHECK(static_cast<std::int32_t>(restored) == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
CHECK(json::from_msgpack(result) == j);
|
CHECK(json::from_msgpack(result) == j);
|
||||||
|
@ -1609,9 +1610,7 @@ TEST_CASE("single MessagePack roundtrip")
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse MessagePack file
|
// parse MessagePack file
|
||||||
std::ifstream f_msgpack(filename + ".msgpack", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".msgpack");
|
||||||
std::vector<uint8_t> packed((std::istreambuf_iterator<char>(f_msgpack)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_msgpack(packed));
|
CHECK_NOTHROW(j2 = json::from_msgpack(packed));
|
||||||
|
|
||||||
|
@ -1824,10 +1823,7 @@ TEST_CASE("MessagePack roundtrips" * doctest::skip())
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse MessagePack file
|
// parse MessagePack file
|
||||||
std::ifstream f_msgpack(filename + ".msgpack", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".msgpack");
|
||||||
std::vector<uint8_t> packed(
|
|
||||||
(std::istreambuf_iterator<char>(f_msgpack)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_msgpack(packed));
|
CHECK_NOTHROW(j2 = json::from_msgpack(packed));
|
||||||
|
|
||||||
|
@ -1857,10 +1853,7 @@ TEST_CASE("MessagePack roundtrips" * doctest::skip())
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse MessagePack file
|
// parse MessagePack file
|
||||||
std::ifstream f_msgpack(filename + ".msgpack", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".msgpack");
|
||||||
std::vector<uint8_t> packed(
|
|
||||||
(std::istreambuf_iterator<char>(f_msgpack)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_msgpack({packed.data(), packed.size()}));
|
CHECK_NOTHROW(j2 = json::from_msgpack({packed.data(), packed.size()}));
|
||||||
|
|
||||||
|
@ -1875,10 +1868,7 @@ TEST_CASE("MessagePack roundtrips" * doctest::skip())
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse MessagePack file
|
// parse MessagePack file
|
||||||
std::ifstream f_msgpack(filename + ".msgpack", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".msgpack");
|
||||||
std::vector<uint8_t> packed(
|
|
||||||
(std::istreambuf_iterator<char>(f_msgpack)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
|
|
||||||
if (!exclude_packed.count(filename))
|
if (!exclude_packed.count(filename))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1516,8 +1516,8 @@ TEST_CASE("regression tests")
|
||||||
|
|
||||||
SECTION("issue #838 - incorrect parse error with binary data in keys")
|
SECTION("issue #838 - incorrect parse error with binary data in keys")
|
||||||
{
|
{
|
||||||
uint8_t key1[] = { 103, 92, 117, 48, 48, 48, 55, 92, 114, 215, 126, 214, 95, 92, 34, 174, 40, 71, 38, 174, 40, 71, 38, 223, 134, 247, 127 };
|
uint8_t key1[] = { 103, 92, 117, 48, 48, 48, 55, 92, 114, 215, 126, 214, 95, 92, 34, 174, 40, 71, 38, 174, 40, 71, 38, 223, 134, 247, 127, 0 };
|
||||||
std::string key1_str(key1, key1 + sizeof(key1) / sizeof(key1[0]));
|
std::string key1_str(reinterpret_cast<char*>(key1));
|
||||||
json j = key1_str;
|
json j = key1_str;
|
||||||
CHECK_THROWS_AS(j.dump(), json::type_error&);
|
CHECK_THROWS_AS(j.dump(), json::type_error&);
|
||||||
CHECK_THROWS_WITH(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 10: 0x7E");
|
CHECK_THROWS_WITH(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 10: 0x7E");
|
||||||
|
|
|
@ -36,6 +36,7 @@ using nlohmann::json;
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <test_data.hpp>
|
#include <test_data.hpp>
|
||||||
|
#include <test_utils.hpp>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -2508,11 +2509,8 @@ TEST_CASE("UBJSON roundtrips" * doctest::skip())
|
||||||
std::ifstream f_json(filename);
|
std::ifstream f_json(filename);
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse MessagePack file
|
// parse UBJSON file
|
||||||
std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".ubjson");
|
||||||
std::vector<uint8_t> packed(
|
|
||||||
(std::istreambuf_iterator<char>(f_ubjson)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_ubjson(packed));
|
CHECK_NOTHROW(j2 = json::from_ubjson(packed));
|
||||||
|
|
||||||
|
@ -2526,7 +2524,7 @@ TEST_CASE("UBJSON roundtrips" * doctest::skip())
|
||||||
std::ifstream f_json(filename);
|
std::ifstream f_json(filename);
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse MessagePack file
|
// parse UBJSON file
|
||||||
std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary);
|
std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary);
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_ubjson(f_ubjson));
|
CHECK_NOTHROW(j2 = json::from_ubjson(f_ubjson));
|
||||||
|
@ -2541,11 +2539,8 @@ TEST_CASE("UBJSON roundtrips" * doctest::skip())
|
||||||
std::ifstream f_json(filename);
|
std::ifstream f_json(filename);
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse MessagePack file
|
// parse UBJSON file
|
||||||
std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".ubjson");
|
||||||
std::vector<uint8_t> packed(
|
|
||||||
(std::istreambuf_iterator<char>(f_ubjson)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_ubjson({packed.data(), packed.size()}));
|
CHECK_NOTHROW(j2 = json::from_ubjson({packed.data(), packed.size()}));
|
||||||
|
|
||||||
|
@ -2559,11 +2554,8 @@ TEST_CASE("UBJSON roundtrips" * doctest::skip())
|
||||||
std::ifstream f_json(filename);
|
std::ifstream f_json(filename);
|
||||||
json j1 = json::parse(f_json);
|
json j1 = json::parse(f_json);
|
||||||
|
|
||||||
// parse MessagePack file
|
// parse UBJSON file
|
||||||
std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary);
|
auto packed = utils::read_binary_file(filename + ".ubjson");
|
||||||
std::vector<uint8_t> packed(
|
|
||||||
(std::istreambuf_iterator<char>(f_ubjson)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
|
|
||||||
{
|
{
|
||||||
INFO_WITH_TEMP(filename + ": output adapters: std::vector<uint8_t>");
|
INFO_WITH_TEMP(filename + ": output adapters: std::vector<uint8_t>");
|
||||||
|
|
25
test/utils/test_utils.hpp
Normal file
25
test/utils/test_utils.hpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint> // uint8_t
|
||||||
|
#include <fstream> // ifstream, istreambuf_iterator, ios
|
||||||
|
#include <vector> // vector
|
||||||
|
|
||||||
|
namespace utils
|
||||||
|
{
|
||||||
|
|
||||||
|
inline std::vector<std::uint8_t> read_binary_file(const std::string& filename)
|
||||||
|
{
|
||||||
|
std::ifstream file(filename, std::ios::binary);
|
||||||
|
file.unsetf(std::ios::skipws);
|
||||||
|
|
||||||
|
file.seekg(0, std::ios::end);
|
||||||
|
const auto size = file.tellg();
|
||||||
|
file.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
|
std::vector<std::uint8_t> byte_vector;
|
||||||
|
byte_vector.reserve(static_cast<std::size_t>(size));
|
||||||
|
byte_vector.insert(byte_vector.begin(), std::istream_iterator<std::uint8_t>(file), std::istream_iterator<std::uint8_t>());
|
||||||
|
return byte_vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace utils
|
Loading…
Reference in a new issue