Merge branch 'develop' of https://github.com/nlohmann/json into issue2286

 Conflicts:
	single_include/nlohmann/json.hpp
This commit is contained in:
Niels Lohmann 2020-07-25 21:44:58 +02:00
commit 42f8708940
No known key found for this signature in database
GPG key ID: 7F3CEA63AE251B69
22 changed files with 2770 additions and 2785 deletions

3
.gitignore vendored
View file

@ -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

View file

@ -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

View file

@ -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
########################################################################## ##########################################################################

View file

@ -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

View file

@ -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:

View file

@ -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.

View file

@ -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;
} }

View file

@ -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

View file

@ -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)

View file

@ -0,0 +1,3 @@
#include "Bar.hpp"
class Bar;

View file

@ -0,0 +1,4 @@
#include <nlohmann/json.hpp>
#include "Foo.hpp"
class Bar : public Foo{};

View file

@ -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)

View file

@ -0,0 +1,3 @@
#include "Foo.hpp"
class Foo;

View file

@ -0,0 +1,4 @@
#pragma once
#include <nlohmann/json.hpp>
class Foo{};

View file

@ -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>");

View file

@ -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());
}
} }

View file

@ -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

View file

@ -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))
{ {

View file

@ -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");

View file

@ -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
View 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