Merge branches 'develop' and 'feature/optional' of https://github.com/nlohmann/json into feature/optional
This commit is contained in:
commit
b61d563ebe
49
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
49
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@ -7,16 +7,51 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
- What is the issue you have?
|
<!-- Provide a concise summary of the issue in the title above. -->
|
||||||
|
|
||||||
- Please describe the steps to reproduce the issue. Can you provide a small but working code example?
|
#### What is the issue you have?
|
||||||
|
|
||||||
- What is the expected behavior?
|
<!-- Provide a detailed introduction to the issue itself, and why you consider it to be a bug. -->
|
||||||
|
<!-- If possible, be specific and add stack traces, error messages, etc. Avoid vague terms like "crash" or "doesn't work". -->
|
||||||
|
|
||||||
- And what is the actual behavior instead?
|
#### Please describe the steps to reproduce the issue.
|
||||||
|
|
||||||
- Which compiler and operating system are you using? Is it a [supported compiler](https://github.com/nlohmann/json#supported-compilers)?
|
<!-- Provide a link to a live example, or an unambiguous set of steps to -->
|
||||||
|
<!-- reproduce this bug. Include code to reproduce, if relevant -->
|
||||||
|
|
||||||
- Did you use a released version of the library or the version from the `develop` branch?
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
|
||||||
- If you experience a compilation error: can you [compile and run the unit tests](https://github.com/nlohmann/json#execute-unit-tests)?
|
#### Can you provide a small but working code example?
|
||||||
|
|
||||||
|
<!-- Please understand that we cannot analyze and debug large code bases. -->
|
||||||
|
|
||||||
|
#### What is the expected behavior?
|
||||||
|
|
||||||
|
<!-- Tell us what should happen -->
|
||||||
|
|
||||||
|
#### And what is the actual behavior instead?
|
||||||
|
|
||||||
|
<!-- Tell us what happens instead. -->
|
||||||
|
|
||||||
|
#### Which compiler and operating system are you using?
|
||||||
|
|
||||||
|
<!-- Include as many relevant details about the environment you experienced the bug in. -->
|
||||||
|
<!-- Make sure you use a supported compiler, see https://github.com/nlohmann/json#supported-compilers. -->
|
||||||
|
|
||||||
|
- Compiler: ___
|
||||||
|
- Operating system: ___
|
||||||
|
|
||||||
|
#### Which version of the library did you use?
|
||||||
|
|
||||||
|
<!-- Please add an `x` to the respective line. -->
|
||||||
|
|
||||||
|
- [ ] latest release version 3.7.3
|
||||||
|
- [ ] other release - please state the version: ___
|
||||||
|
- [ ] the `develop` branch
|
||||||
|
|
||||||
|
#### If you experience a compilation error: can you [compile and run the unit tests](https://github.com/nlohmann/json#execute-unit-tests)?
|
||||||
|
|
||||||
|
- [ ] yes
|
||||||
|
- [ ] no - please copy/paste the error message below
|
||||||
|
|||||||
9
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
9
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
@ -7,6 +7,11 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
- Describe the feature in as much detail as possible.
|
#### Which feature do you want to see in the library?
|
||||||
|
|
||||||
|
<!-- Describe the feature in as much detail as possible. -->
|
||||||
|
|
||||||
|
#### How would the feature be usable for other users?
|
||||||
|
|
||||||
|
<!-- Include sample usage where appropriate. -->
|
||||||
|
|
||||||
- Include sample usage where appropriate.
|
|
||||||
|
|||||||
26
.github/ISSUE_TEMPLATE/question.md
vendored
26
.github/ISSUE_TEMPLATE/question.md
vendored
@ -7,10 +7,28 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
- Describe what you want to achieve.
|
#### What do you want to achieve?
|
||||||
|
|
||||||
- Describe what you tried.
|
<!-- Please describe the feature as detailed as possible. -->
|
||||||
|
|
||||||
- Describe which system (OS, compiler) you are using.
|
#### What have you tried?
|
||||||
|
|
||||||
- Describe which version of the library you are using (release version, develop branch).
|
<!-- There are thousands of issues to search: https://github.com/nlohmann/json/issues?q=is%3Aissue+ -->
|
||||||
|
<!-- There is a full documentation of the API: https://nlohmann.github.io/json/ -->
|
||||||
|
<!-- There is a detailed README file: https://github.com/nlohmann/json/blob/develop/README.md -->
|
||||||
|
|
||||||
|
#### Which compiler and operating system are you using?
|
||||||
|
|
||||||
|
<!-- Include as many relevant details about the environment you experienced the bug in. -->
|
||||||
|
<!-- Make sure you use a supported compiler, see https://github.com/nlohmann/json#supported-compilers. -->
|
||||||
|
|
||||||
|
- Compiler: ___
|
||||||
|
- Operating system: ___
|
||||||
|
|
||||||
|
#### Which version of the library did you use?
|
||||||
|
|
||||||
|
<!-- Please add an `x` to the respective line. -->
|
||||||
|
|
||||||
|
- [ ] latest release version 3.7.3
|
||||||
|
- [ ] other release - please state the version: ___
|
||||||
|
- [ ] the `develop` branch
|
||||||
|
|||||||
19
.github/workflows/ccpp.yml
vendored
19
.github/workflows/ccpp.yml
vendored
@ -1,19 +0,0 @@
|
|||||||
name: C/C++ CI
|
|
||||||
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
- name: prepare
|
|
||||||
run: mkdir build
|
|
||||||
- name: cmake
|
|
||||||
run: cd build ; cmake ..
|
|
||||||
- name: build
|
|
||||||
run: make -C build
|
|
||||||
- name: test
|
|
||||||
run: cd build ; ctest -j 10
|
|
||||||
17
.github/workflows/macos.yml
vendored
Normal file
17
.github/workflows/macos.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
name: macOS
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: macos-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: cmake
|
||||||
|
run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug
|
||||||
|
- name: build
|
||||||
|
run: cmake --build build --parallel 10
|
||||||
|
- name: test
|
||||||
|
run: cd build ; ctest -j 10 --output-on-failure
|
||||||
17
.github/workflows/ubuntu.yml
vendored
Normal file
17
.github/workflows/ubuntu.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
name: Ubuntu
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: cmake
|
||||||
|
run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug
|
||||||
|
- name: build
|
||||||
|
run: cmake --build build --parallel 10
|
||||||
|
- name: test
|
||||||
|
run: cd build ; ctest -j 10 --output-on-failure
|
||||||
17
.github/workflows/windows.yml
vendored
Normal file
17
.github/workflows/windows.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
name: Windows
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: cmake
|
||||||
|
run: cmake -S . -B build -G "Visual Studio 16 2019" -D CMAKE_BUILD_TYPE=Debug
|
||||||
|
- name: build
|
||||||
|
run: cmake --build build --parallel 10
|
||||||
|
- name: test
|
||||||
|
run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure
|
||||||
14
Makefile
14
Makefile
@ -102,7 +102,8 @@ 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:
|
||||||
$(MAKE) json_unit CXX=c++ CXXFLAGS=" \
|
rm -fr build_pedantic
|
||||||
|
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 \
|
||||||
-Weverything \
|
-Weverything \
|
||||||
@ -115,11 +116,13 @@ 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"
|
-Wno-weak-vtables" cmake -S . -B build_pedantic -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_MultipleHeaders=ON
|
||||||
|
cmake --build build_pedantic
|
||||||
|
|
||||||
# calling GCC with most warnings
|
# calling GCC with most warnings
|
||||||
pedantic_gcc:
|
pedantic_gcc:
|
||||||
$(MAKE) json_unit CXX=/usr/local/bin/g++-9 CXXFLAGS=" \
|
rm -fr build_pedantic
|
||||||
|
CXXFLAGS=" \
|
||||||
-std=c++11 \
|
-std=c++11 \
|
||||||
-Waddress \
|
-Waddress \
|
||||||
-Waddress-of-packed-member \
|
-Waddress-of-packed-member \
|
||||||
@ -233,7 +236,7 @@ pedantic_gcc:
|
|||||||
-Wno-system-headers \
|
-Wno-system-headers \
|
||||||
-Wno-templates \
|
-Wno-templates \
|
||||||
-Wno-undef \
|
-Wno-undef \
|
||||||
-Wnoexcept \
|
-Wno-noexcept \
|
||||||
-Wnoexcept-type \
|
-Wnoexcept-type \
|
||||||
-Wnon-template-friend \
|
-Wnon-template-friend \
|
||||||
-Wnon-virtual-dtor \
|
-Wnon-virtual-dtor \
|
||||||
@ -340,7 +343,8 @@ pedantic_gcc:
|
|||||||
-Wvolatile-register-var \
|
-Wvolatile-register-var \
|
||||||
-Wwrite-strings \
|
-Wwrite-strings \
|
||||||
-Wzero-as-null-pointer-constant \
|
-Wzero-as-null-pointer-constant \
|
||||||
"
|
" cmake -S . -B build_pedantic -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_MultipleHeaders=ON
|
||||||
|
cmake --build build_pedantic
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# benchmarks
|
# benchmarks
|
||||||
|
|||||||
104
README.md
104
README.md
@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
[](https://travis-ci.org/nlohmann/json)
|
[](https://travis-ci.org/nlohmann/json)
|
||||||
[](https://ci.appveyor.com/project/nlohmann/json)
|
[](https://ci.appveyor.com/project/nlohmann/json)
|
||||||
|
[](https://github.com/nlohmann/json/actions?query=workflow%3AUbuntu)
|
||||||
|
[](https://github.com/nlohmann/json/actions?query=workflow%3AmacOS)
|
||||||
|
[](https://github.com/nlohmann/json/actions?query=workflow%3AWindows)
|
||||||
[](https://circleci.com/gh/nlohmann/json)
|
[](https://circleci.com/gh/nlohmann/json)
|
||||||
[](https://coveralls.io/r/nlohmann/json)
|
[](https://coveralls.io/github/nlohmann/json?branch=develop)
|
||||||
[](https://scan.coverity.com/projects/nlohmann-json)
|
[](https://scan.coverity.com/projects/nlohmann-json)
|
||||||
[](https://www.codacy.com/app/nlohmann/json?utm_source=github.com&utm_medium=referral&utm_content=nlohmann/json&utm_campaign=Badge_Grade)
|
[](https://www.codacy.com/app/nlohmann/json?utm_source=github.com&utm_medium=referral&utm_content=nlohmann/json&utm_campaign=Badge_Grade)
|
||||||
[](https://lgtm.com/projects/g/nlohmann/json/context:cpp)
|
[](https://lgtm.com/projects/g/nlohmann/json/context:cpp)
|
||||||
@ -1047,13 +1050,43 @@ std::vector<std::uint8_t> v_ubjson = json::to_ubjson(j);
|
|||||||
json j_from_ubjson = json::from_ubjson(v_ubjson);
|
json j_from_ubjson = json::from_ubjson(v_ubjson);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The library also supports binary types from BSON, CBOR (byte strings), and MessagePack (bin, ext, fixext). They are stored by default as `std::vector<std::uint8_t>` to be processed outside of the library.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// CBOR byte string with payload 0xCAFE
|
||||||
|
std::vector<std::uint8_t> v = {0x42, 0xCA, 0xFE};
|
||||||
|
|
||||||
|
// read value
|
||||||
|
json j = json::from_cbor(v);
|
||||||
|
|
||||||
|
// the JSON value has type binary
|
||||||
|
j.is_binary(); // true
|
||||||
|
|
||||||
|
// get reference to stored binary value
|
||||||
|
auto& binary = j.get_binary();
|
||||||
|
|
||||||
|
// the binary value has no subtype (CBOR has no binary subtypes)
|
||||||
|
binary.has_subtype(); // false
|
||||||
|
|
||||||
|
// access std::vector<std::uint8_t> member functions
|
||||||
|
binary.size(); // 2
|
||||||
|
binary[0]; // 0xCA
|
||||||
|
binary[1]; // 0xFE
|
||||||
|
|
||||||
|
// set subtype to 0x10
|
||||||
|
binary.set_subtype(0x10);
|
||||||
|
|
||||||
|
// serialize to MessagePack
|
||||||
|
auto cbor = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Supported compilers
|
## Supported compilers
|
||||||
|
|
||||||
Though it's 2019 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
|
Though it's 2020 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
|
||||||
|
|
||||||
- GCC 4.8 - 9.2 (and possibly later)
|
- GCC 4.8 - 10.0 (and possibly later)
|
||||||
- Clang 3.4 - 9.0 (and possibly later)
|
- Clang 3.4 - 10.0 (and possibly later)
|
||||||
- Intel C++ Compiler 17.0.2 (and possibly later)
|
- Intel C++ Compiler 17.0.2 (and possibly later)
|
||||||
- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
|
- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
|
||||||
- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
|
- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
|
||||||
@ -1078,36 +1111,41 @@ Please note:
|
|||||||
|
|
||||||
- Unsupported versions of GCC and Clang are rejected by `#error` directives. This can be switched off by defining `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`. Note that you can expect no support in this case.
|
- Unsupported versions of GCC and Clang are rejected by `#error` directives. This can be switched off by defining `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`. Note that you can expect no support in this case.
|
||||||
|
|
||||||
The following compilers are currently used in continuous integration at [Travis](https://travis-ci.org/nlohmann/json), [AppVeyor](https://ci.appveyor.com/project/nlohmann/json), and [CircleCI](https://circleci.com/gh/nlohmann/json):
|
The following compilers are currently used in continuous integration at [Travis](https://travis-ci.org/nlohmann/json), [AppVeyor](https://ci.appveyor.com/project/nlohmann/json), [GitHub Actions](https://github.com/nlohmann/json/actions), and [CircleCI](https://circleci.com/gh/nlohmann/json):
|
||||||
|
|
||||||
| Compiler | Operating System | Version String |
|
| Compiler | Operating System | CI Provider |
|
||||||
|-----------------------|------------------------------|----------------|
|
|-----------------------------------------------------------------|--------------------|----------------|
|
||||||
| GCC 4.8.5 | Ubuntu 14.04.5 LTS | g++-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.2) 4.8.5 |
|
| Apple Clang 9.1.0 (clang-902.0.39.1); Xcode 9.3 | macOS 10.13.3 | Travis |
|
||||||
| GCC 4.9.4 | Ubuntu 14.04.1 LTS | g++-4.9 (Ubuntu 4.9.4-2ubuntu1~14.04.1) 4.9.4 |
|
| Apple Clang 9.1.0 (clang-902.0.39.2); Xcode 9.4.1 | macOS 10.13.6 | Travis |
|
||||||
| GCC 5.5.0 | Ubuntu 14.04.1 LTS | g++-5 (Ubuntu 5.5.0-12ubuntu1~14.04) 5.5.0 20171010 |
|
| Apple Clang 10.0.0 (clang-1000.11.45.2); Xcode 10.0 | macOS 10.13.6 | Travis |
|
||||||
| GCC 6.3.0 | Debian 9 (stretch) | g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516 |
|
| Apple Clang 10.0.0 (clang-1000.11.45.5); Xcode 10.1 | macOS 10.13.6 | Travis |
|
||||||
| GCC 6.4.0 | Ubuntu 14.04.1 LTS | g++-6 (Ubuntu 6.4.0-17ubuntu1~14.04) 6.4.0 20180424 |
|
| Apple Clang 10.0.1 (clang-1001.0.46.4); Xcode 10.2.1 | macOS 10.14.4 | Travis |
|
||||||
| GCC 7.3.0 | Ubuntu 14.04.1 LTS | g++-7 (Ubuntu 7.3.0-21ubuntu1~14.04) 7.3.0 |
|
| Apple Clang 11.0.0 (clang-1100.0.33.12); Xcode 11.2.1 | macOS 10.14.6 | Travis |
|
||||||
| GCC 7.3.0 | Windows Server 2012 R2 (x64) | g++ (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 7.3.0 |
|
| Apple Clang 11.0.3 (clang-1103.0.32.59); Xcode 11.4.1 | macOS 10.15.4 | GitHub Actions |
|
||||||
| GCC 8.1.0 | Ubuntu 14.04.1 LTS | g++-8 (Ubuntu 8.1.0-5ubuntu1~14.04) 8.1.0 |
|
| Clang 3.5.0 (3.5.0-4ubuntu2~trusty2) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| GCC 9.2.1 | Ubuntu 14.05.1 LTS | g++-9 (Ubuntu 9.2.1-16ubuntu1~14.04.1) 9.2.1 20191030 |
|
| Clang 3.6.2 (3.6.2-svn240577-1~exp1) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Clang 3.5.0 | Ubuntu 14.04.1 LTS | clang version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) (based on LLVM 3.5.0) |
|
| Clang 3.7.1 (3.7.1-svn253571-1~exp1) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Clang 3.6.2 | Ubuntu 14.04.1 LTS | clang version 3.6.2-svn240577-1~exp1 (branches/release_36) (based on LLVM 3.6.2) |
|
| Clang 3.8.0 (3.8.0-2ubuntu3~trusty5) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Clang 3.7.1 | Ubuntu 14.04.1 LTS | clang version 3.7.1-svn253571-1~exp1 (branches/release_37) (based on LLVM 3.7.1) |
|
| Clang 3.9.1 (3.9.1-4ubuntu3~14.04.3) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Clang 3.8.0 | Ubuntu 14.04.1 LTS | clang version 3.8.0-2ubuntu3~trusty5 (tags/RELEASE_380/final) |
|
| Clang 4.0.1 (4.0.1-svn305264-1~exp1) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Clang 3.9.1 | Ubuntu 14.04.1 LTS | clang version 3.9.1-4ubuntu3~14.04.3 (tags/RELEASE_391/rc2) |
|
| Clang 5.0.2 (version 5.0.2-svn328729-1~exp1~20180509123505.100) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Clang 4.0.1 | Ubuntu 14.04.1 LTS | clang version 4.0.1-svn305264-1~exp1 (branches/release_40) |
|
| Clang 6.0.1 (6.0.1-svn334776-1~exp1~20190309042707.121) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Clang 5.0.2 | Ubuntu 14.04.1 LTS | clang version 5.0.2-svn328729-1~exp1~20180509123505.100 (branches/release_50) |
|
| Clang 7.1.0 (7.1.0-svn353565-1~exp1~20190419134007.64) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Clang 6.0.1 | Ubuntu 14.04.1 LTS | clang version 6.0.1-svn334776-1~exp1~20180726133705.85 (branches/release_60) |
|
| Clang 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) | Ubuntu 18.04.4 LTS | Travis |
|
||||||
| Clang 7.0.1 | Ubuntu 14.04.1 LTS | clang version 7.0.1-svn348686-1~exp1~20181213084532.54 (branches/release_70) |
|
| GCC 4.8.5 (Ubuntu 4.8.5-4ubuntu8~14.04.2) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Clang Xcode 9.3 | OSX 10.13.3 | Apple LLVM version 9.1.0 (clang-902.0.39.2) |
|
| GCC 4.9.4 (Ubuntu 4.9.4-2ubuntu1~14.04.1) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Clang Xcode 10.0 | OSX 10.13.3 | Apple LLVM version 10.0.0 (clang-1000.11.45.2) |
|
| GCC 5.5.0 (Ubuntu 5.5.0-12ubuntu1~14.04) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Clang Xcode 10.1 | OSX 10.13.3 | Apple LLVM version 10.0.0 (clang-1000.11.45.5) |
|
| GCC 6.3.0 (Debian 6.3.0-18+deb9u1) | Debian 9 | Circle CI |
|
||||||
| Clang Xcode 10.2 | OSX 10.14.4 | Apple LLVM version 10.0.1 (clang-1001.0.46.4) |
|
| GCC 6.5.0 (Ubuntu 6.5.0-2ubuntu1~14.04.1) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Clang Xcode 11.2.1 | OSX 10.14.4 | Apple LLVM version 11.0.0 (clang-1100.0.33.12) |
|
| GCC 7.3.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) | Windows-6.3.9600 | AppVeyor |
|
||||||
| Visual Studio 14 2015 | Windows Server 2012 R2 (x64) | Microsoft (R) Build Engine version 14.0.25420.1, MSVC 19.0.24215.1 |
|
| GCC 7.5.0 (Ubuntu 7.5.0-3ubuntu1~14.04.1) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
| Visual Studio 15 2017 | Windows Server 2012 R2 (x64) | Microsoft (R) Build Engine version 15.9.21+g9802d43bc3, MSVC 19.16.27032.1 |
|
| GCC 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) | Ubuntu 18.04.4 LTS | GitHub Actions |
|
||||||
| Visual Studio 16 2019 | Windows Server 2012 R2 (x64) | Microsoft (R) Build Engine version 16.3.1+1def00d3d, MSVC 19.23.28106.4 |
|
| GCC 8.4.0 (Ubuntu 8.4.0-1ubuntu1~14.04) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
|
| GCC 9.3.0 (Ubuntu 9.3.0-11ubuntu0~14.04) | Ubuntu 14.04.5 LTS | Travis |
|
||||||
|
| MSVC 19.0.24241.7 (Build Engine version 14.0.25420.1) | Windows-6.3.9600 | AppVeyor |
|
||||||
|
| MSVC 19.16.27035.0 (15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | AppVeyor |
|
||||||
|
| MSVC 19.25.28614.0 (Build Engine version 16.5.0+d4cbfca49 for .NET Framework) | Windows-10.0.17763 | AppVeyor |
|
||||||
|
| MSVC 19.25.28614.0 (Build Engine version 16.5.0+d4cbfca49 for .NET Framework) | Windows-10.0.17763 | GitHub Actions |
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@ -12,3 +12,40 @@ add_custom_target(download_test_data
|
|||||||
|
|
||||||
# create a header with the path to the downloaded test data
|
# create a header with the path to the downloaded test data
|
||||||
file(WRITE ${CMAKE_BINARY_DIR}/include/test_data.hpp "#define TEST_DATA_DIRECTORY \"${CMAKE_BINARY_DIR}/json_test_data\"\n")
|
file(WRITE ${CMAKE_BINARY_DIR}/include/test_data.hpp "#define TEST_DATA_DIRECTORY \"${CMAKE_BINARY_DIR}/json_test_data\"\n")
|
||||||
|
|
||||||
|
# determine the operating system (for debug and support purposes)
|
||||||
|
find_program(UNAME_COMMAND uname)
|
||||||
|
find_program(VER_COMMAND ver)
|
||||||
|
find_program(LSB_RELEASE_COMMAND lsb_release)
|
||||||
|
find_program(SW_VERS_COMMAND sw_vers)
|
||||||
|
set(OS_VERSION_STRINGS "${CMAKE_SYSTEM}")
|
||||||
|
if (VER_COMMAND)
|
||||||
|
execute_process(COMMAND ${VER_COMMAND} OUTPUT_VARIABLE VER_COMMAND_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
set(OS_VERSION_STRINGS "${OS_VERSION_STRINGS}; ${VER_COMMAND_RESULT}")
|
||||||
|
endif()
|
||||||
|
if (SW_VERS_COMMAND)
|
||||||
|
execute_process(COMMAND ${SW_VERS_COMMAND} OUTPUT_VARIABLE SW_VERS_COMMAND_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
||||||
|
string(REGEX REPLACE "[ ]*\n" "; " SW_VERS_COMMAND_RESULT "${SW_VERS_COMMAND_RESULT}")
|
||||||
|
set(OS_VERSION_STRINGS "${OS_VERSION_STRINGS}; ${SW_VERS_COMMAND_RESULT}")
|
||||||
|
endif()
|
||||||
|
if (LSB_RELEASE_COMMAND)
|
||||||
|
execute_process(COMMAND ${LSB_RELEASE_COMMAND} -a OUTPUT_VARIABLE LSB_RELEASE_COMMAND_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
||||||
|
string(REGEX REPLACE "[ ]*\n" "; " LSB_RELEASE_COMMAND_RESULT "${LSB_RELEASE_COMMAND_RESULT}")
|
||||||
|
set(OS_VERSION_STRINGS "${OS_VERSION_STRINGS}; ${LSB_RELEASE_COMMAND_RESULT}")
|
||||||
|
endif()
|
||||||
|
if (UNAME_COMMAND)
|
||||||
|
execute_process(COMMAND ${UNAME_COMMAND} -a OUTPUT_VARIABLE UNAME_COMMAND_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
||||||
|
set(OS_VERSION_STRINGS "${OS_VERSION_STRINGS}; ${UNAME_COMMAND_RESULT}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Operating system: ${OS_VERSION_STRINGS}")
|
||||||
|
|
||||||
|
# determine the compiler (for debug and support purposes)
|
||||||
|
if (MSVC)
|
||||||
|
execute_process(COMMAND ${CMAKE_CXX_COMPILER} OUTPUT_VARIABLE CXX_VERSION_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_VARIABLE CXX_VERSION_RESULT ERROR_STRIP_TRAILING_WHITESPACE)
|
||||||
|
set(CMAKE_CXX_COMPILER "${CXX_VERSION_RESULT}; MSVC_VERSION=${MSVC_VERSION}; MSVC_TOOLSET_VERSION=${MSVC_TOOLSET_VERSION}")
|
||||||
|
else()
|
||||||
|
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE CXX_VERSION_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
endif()
|
||||||
|
string(REGEX REPLACE "[ ]*\n" "; " CXX_VERSION_RESULT "${CXX_VERSION_RESULT}")
|
||||||
|
message(STATUS "Compiler: ${CXX_VERSION_RESULT}")
|
||||||
|
|||||||
@ -14,6 +14,7 @@ int main()
|
|||||||
json j_object = {{"one", 1}, {"two", 2}};
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
json j_array = {1, 2, 4, 8, 16};
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
json j_string = "Hello, world";
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
// call is_array()
|
// call is_array()
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
@ -25,4 +26,5 @@ int main()
|
|||||||
std::cout << j_object.is_array() << '\n';
|
std::cout << j_object.is_array() << '\n';
|
||||||
std::cout << j_array.is_array() << '\n';
|
std::cout << j_array.is_array() << '\n';
|
||||||
std::cout << j_string.is_array() << '\n';
|
std::cout << j_string.is_array() << '\n';
|
||||||
|
std::cout << j_binary.is_array() << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/EXdpfHah1530TPIE"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/qO60NqUznleA1S7v"><b>online</b></a>
|
||||||
@ -6,3 +6,4 @@ false
|
|||||||
false
|
false
|
||||||
true
|
true
|
||||||
false
|
false
|
||||||
|
false
|
||||||
|
|||||||
30
doc/examples/is_binary.cpp
Normal file
30
doc/examples/is_binary.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// create JSON values
|
||||||
|
json j_null;
|
||||||
|
json j_boolean = true;
|
||||||
|
json j_number_integer = 17;
|
||||||
|
json j_number_unsigned_integer = 12345678987654321u;
|
||||||
|
json j_number_float = 23.42;
|
||||||
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
|
// call is_binary()
|
||||||
|
std::cout << std::boolalpha;
|
||||||
|
std::cout << j_null.is_binary() << '\n';
|
||||||
|
std::cout << j_boolean.is_binary() << '\n';
|
||||||
|
std::cout << j_number_integer.is_binary() << '\n';
|
||||||
|
std::cout << j_number_unsigned_integer.is_binary() << '\n';
|
||||||
|
std::cout << j_number_float.is_binary() << '\n';
|
||||||
|
std::cout << j_object.is_binary() << '\n';
|
||||||
|
std::cout << j_array.is_binary() << '\n';
|
||||||
|
std::cout << j_string.is_binary() << '\n';
|
||||||
|
std::cout << j_binary.is_binary() << '\n';
|
||||||
|
}
|
||||||
1
doc/examples/is_binary.link
Normal file
1
doc/examples/is_binary.link
Normal file
@ -0,0 +1 @@
|
|||||||
|
<a target="_blank" href="https://wandbox.org/permlink/xR6eTQqSySLjtpn6"><b>online</b></a>
|
||||||
9
doc/examples/is_binary.output
Normal file
9
doc/examples/is_binary.output
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
true
|
||||||
@ -14,6 +14,7 @@ int main()
|
|||||||
json j_object = {{"one", 1}, {"two", 2}};
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
json j_array = {1, 2, 4, 8, 16};
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
json j_string = "Hello, world";
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
// call is_boolean()
|
// call is_boolean()
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
@ -25,4 +26,5 @@ int main()
|
|||||||
std::cout << j_object.is_boolean() << '\n';
|
std::cout << j_object.is_boolean() << '\n';
|
||||||
std::cout << j_array.is_boolean() << '\n';
|
std::cout << j_array.is_boolean() << '\n';
|
||||||
std::cout << j_string.is_boolean() << '\n';
|
std::cout << j_string.is_boolean() << '\n';
|
||||||
|
std::cout << j_binary.is_boolean() << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/7sniyNPobbQQdBHJ"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/QVbXnPfNZdvuDHwy"><b>online</b></a>
|
||||||
@ -6,3 +6,4 @@ false
|
|||||||
false
|
false
|
||||||
false
|
false
|
||||||
false
|
false
|
||||||
|
false
|
||||||
|
|||||||
@ -14,6 +14,7 @@ int main()
|
|||||||
json j_object = {{"one", 1}, {"two", 2}};
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
json j_array = {1, 2, 4, 8, 16};
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
json j_string = "Hello, world";
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
// call is_discarded()
|
// call is_discarded()
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
@ -25,4 +26,5 @@ int main()
|
|||||||
std::cout << j_object.is_discarded() << '\n';
|
std::cout << j_object.is_discarded() << '\n';
|
||||||
std::cout << j_array.is_discarded() << '\n';
|
std::cout << j_array.is_discarded() << '\n';
|
||||||
std::cout << j_string.is_discarded() << '\n';
|
std::cout << j_string.is_discarded() << '\n';
|
||||||
|
std::cout << j_binary.is_discarded() << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/hWqzRJtSjY0cSoQV"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/jg033y5pdOFOst14"><b>online</b></a>
|
||||||
@ -6,3 +6,4 @@ false
|
|||||||
false
|
false
|
||||||
false
|
false
|
||||||
false
|
false
|
||||||
|
false
|
||||||
|
|||||||
@ -14,6 +14,7 @@ int main()
|
|||||||
json j_object = {{"one", 1}, {"two", 2}};
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
json j_array = {1, 2, 4, 8, 16};
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
json j_string = "Hello, world";
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
// call is_null()
|
// call is_null()
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
@ -25,4 +26,5 @@ int main()
|
|||||||
std::cout << j_object.is_null() << '\n';
|
std::cout << j_object.is_null() << '\n';
|
||||||
std::cout << j_array.is_null() << '\n';
|
std::cout << j_array.is_null() << '\n';
|
||||||
std::cout << j_string.is_null() << '\n';
|
std::cout << j_string.is_null() << '\n';
|
||||||
|
std::cout << j_binary.is_null() << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/r0Z6mhqY20XowAPj"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/uDLxYO1TseoNS5Iu"><b>online</b></a>
|
||||||
@ -6,3 +6,4 @@ false
|
|||||||
false
|
false
|
||||||
false
|
false
|
||||||
false
|
false
|
||||||
|
false
|
||||||
|
|||||||
@ -14,6 +14,7 @@ int main()
|
|||||||
json j_object = {{"one", 1}, {"two", 2}};
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
json j_array = {1, 2, 4, 8, 16};
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
json j_string = "Hello, world";
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
// call is_number()
|
// call is_number()
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
@ -25,4 +26,5 @@ int main()
|
|||||||
std::cout << j_object.is_number() << '\n';
|
std::cout << j_object.is_number() << '\n';
|
||||||
std::cout << j_array.is_number() << '\n';
|
std::cout << j_array.is_number() << '\n';
|
||||||
std::cout << j_string.is_number() << '\n';
|
std::cout << j_string.is_number() << '\n';
|
||||||
|
std::cout << j_binary.is_number() << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/e0RMOkVT4QrwhPV9"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/a7j4EG9Hvjbby3x0"><b>online</b></a>
|
||||||
@ -6,3 +6,4 @@ true
|
|||||||
false
|
false
|
||||||
false
|
false
|
||||||
false
|
false
|
||||||
|
false
|
||||||
|
|||||||
@ -14,6 +14,7 @@ int main()
|
|||||||
json j_object = {{"one", 1}, {"two", 2}};
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
json j_array = {1, 2, 4, 8, 16};
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
json j_string = "Hello, world";
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
// call is_number_float()
|
// call is_number_float()
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
@ -25,4 +26,5 @@ int main()
|
|||||||
std::cout << j_object.is_number_float() << '\n';
|
std::cout << j_object.is_number_float() << '\n';
|
||||||
std::cout << j_array.is_number_float() << '\n';
|
std::cout << j_array.is_number_float() << '\n';
|
||||||
std::cout << j_string.is_number_float() << '\n';
|
std::cout << j_string.is_number_float() << '\n';
|
||||||
|
std::cout << j_binary.is_number_float() << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/Thh18DVuOoaiYidD"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/cT9J60hwwflg88M9"><b>online</b></a>
|
||||||
@ -6,3 +6,4 @@ true
|
|||||||
false
|
false
|
||||||
false
|
false
|
||||||
false
|
false
|
||||||
|
false
|
||||||
|
|||||||
@ -14,6 +14,7 @@ int main()
|
|||||||
json j_object = {{"one", 1}, {"two", 2}};
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
json j_array = {1, 2, 4, 8, 16};
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
json j_string = "Hello, world";
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
// call is_number_integer()
|
// call is_number_integer()
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
@ -25,4 +26,5 @@ int main()
|
|||||||
std::cout << j_object.is_number_integer() << '\n';
|
std::cout << j_object.is_number_integer() << '\n';
|
||||||
std::cout << j_array.is_number_integer() << '\n';
|
std::cout << j_array.is_number_integer() << '\n';
|
||||||
std::cout << j_string.is_number_integer() << '\n';
|
std::cout << j_string.is_number_integer() << '\n';
|
||||||
|
std::cout << j_binary.is_number_integer() << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/wFZSC6RswWXwSncb"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/j0TgXy0oyXxKkhLN"><b>online</b></a>
|
||||||
@ -6,3 +6,4 @@ false
|
|||||||
false
|
false
|
||||||
false
|
false
|
||||||
false
|
false
|
||||||
|
false
|
||||||
|
|||||||
@ -14,6 +14,7 @@ int main()
|
|||||||
json j_object = {{"one", 1}, {"two", 2}};
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
json j_array = {1, 2, 4, 8, 16};
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
json j_string = "Hello, world";
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
// call is_number_unsigned()
|
// call is_number_unsigned()
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
@ -25,4 +26,5 @@ int main()
|
|||||||
std::cout << j_object.is_number_unsigned() << '\n';
|
std::cout << j_object.is_number_unsigned() << '\n';
|
||||||
std::cout << j_array.is_number_unsigned() << '\n';
|
std::cout << j_array.is_number_unsigned() << '\n';
|
||||||
std::cout << j_string.is_number_unsigned() << '\n';
|
std::cout << j_string.is_number_unsigned() << '\n';
|
||||||
|
std::cout << j_binary.is_number_unsigned() << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/ajo1F1VJwoszcD7Y"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/u5wlpVX9Za6lEC2f"><b>online</b></a>
|
||||||
@ -6,3 +6,4 @@ false
|
|||||||
false
|
false
|
||||||
false
|
false
|
||||||
false
|
false
|
||||||
|
false
|
||||||
|
|||||||
@ -14,6 +14,7 @@ int main()
|
|||||||
json j_object = {{"one", 1}, {"two", 2}};
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
json j_array = {1, 2, 4, 8, 16};
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
json j_string = "Hello, world";
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
// call is_object()
|
// call is_object()
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
@ -25,4 +26,5 @@ int main()
|
|||||||
std::cout << j_object.is_object() << '\n';
|
std::cout << j_object.is_object() << '\n';
|
||||||
std::cout << j_array.is_object() << '\n';
|
std::cout << j_array.is_object() << '\n';
|
||||||
std::cout << j_string.is_object() << '\n';
|
std::cout << j_string.is_object() << '\n';
|
||||||
|
std::cout << j_binary.is_object() << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/ojKk5AMVK9xF9bmQ"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/QJQ2avqtJEd4uI23"><b>online</b></a>
|
||||||
@ -6,3 +6,4 @@ false
|
|||||||
true
|
true
|
||||||
false
|
false
|
||||||
false
|
false
|
||||||
|
false
|
||||||
|
|||||||
@ -14,6 +14,7 @@ int main()
|
|||||||
json j_object = {{"one", 1}, {"two", 2}};
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
json j_array = {1, 2, 4, 8, 16};
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
json j_string = "Hello, world";
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
// call is_primitive()
|
// call is_primitive()
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
@ -25,4 +26,5 @@ int main()
|
|||||||
std::cout << j_object.is_primitive() << '\n';
|
std::cout << j_object.is_primitive() << '\n';
|
||||||
std::cout << j_array.is_primitive() << '\n';
|
std::cout << j_array.is_primitive() << '\n';
|
||||||
std::cout << j_string.is_primitive() << '\n';
|
std::cout << j_string.is_primitive() << '\n';
|
||||||
|
std::cout << j_binary.is_primitive() << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/B7F0eMkW0EKdZGcC"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/a4WQ1RXZbD1YQELx"><b>online</b></a>
|
||||||
@ -6,3 +6,4 @@ true
|
|||||||
false
|
false
|
||||||
false
|
false
|
||||||
true
|
true
|
||||||
|
true
|
||||||
|
|||||||
@ -14,6 +14,7 @@ int main()
|
|||||||
json j_object = {{"one", 1}, {"two", 2}};
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
json j_array = {1, 2, 4, 8, 16};
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
json j_string = "Hello, world";
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
// call is_string()
|
// call is_string()
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
@ -25,4 +26,5 @@ int main()
|
|||||||
std::cout << j_object.is_string() << '\n';
|
std::cout << j_object.is_string() << '\n';
|
||||||
std::cout << j_array.is_string() << '\n';
|
std::cout << j_array.is_string() << '\n';
|
||||||
std::cout << j_string.is_string() << '\n';
|
std::cout << j_string.is_string() << '\n';
|
||||||
|
std::cout << j_binary.is_string() << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/2Iq9wtaxEvrb5B68"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/vj3Wo1roaNjE3fPo"><b>online</b></a>
|
||||||
@ -6,3 +6,4 @@ false
|
|||||||
false
|
false
|
||||||
false
|
false
|
||||||
true
|
true
|
||||||
|
false
|
||||||
|
|||||||
@ -14,6 +14,7 @@ int main()
|
|||||||
json j_object = {{"one", 1}, {"two", 2}};
|
json j_object = {{"one", 1}, {"two", 2}};
|
||||||
json j_array = {1, 2, 4, 8, 16};
|
json j_array = {1, 2, 4, 8, 16};
|
||||||
json j_string = "Hello, world";
|
json j_string = "Hello, world";
|
||||||
|
json j_binary = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
// call is_structured()
|
// call is_structured()
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
@ -25,4 +26,5 @@ int main()
|
|||||||
std::cout << j_object.is_structured() << '\n';
|
std::cout << j_object.is_structured() << '\n';
|
||||||
std::cout << j_array.is_structured() << '\n';
|
std::cout << j_array.is_structured() << '\n';
|
||||||
std::cout << j_string.is_structured() << '\n';
|
std::cout << j_string.is_structured() << '\n';
|
||||||
|
std::cout << j_binary.is_structured() << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/44jkAs0G7D0XB24j"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/BoS03RLCyI6oDMbc"><b>online</b></a>
|
||||||
@ -6,3 +6,4 @@ false
|
|||||||
true
|
true
|
||||||
true
|
true
|
||||||
false
|
false
|
||||||
|
false
|
||||||
|
|||||||
@ -79,7 +79,7 @@ class sax_event_consumer : public json::json_sax_t
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool binary(binary_t& val) override
|
bool binary(json::binary_t& val) override
|
||||||
{
|
{
|
||||||
events.push_back("binary");
|
events.push_back("binary");
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<a target="_blank" href="https://wandbox.org/permlink/AoOilNQQoDbzgBYz"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/SbFNpOHK4By29meM"><b>online</b></a>
|
||||||
20
doc/examples/swap__binary_t.cpp
Normal file
20
doc/examples/swap__binary_t.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// create a binary value
|
||||||
|
json value = json::binary_array({1, 2, 3});
|
||||||
|
|
||||||
|
// create a binary_t
|
||||||
|
json::binary_t binary = {{4, 5, 6}};
|
||||||
|
|
||||||
|
// swap the object stored in the JSON value
|
||||||
|
value.swap(binary);
|
||||||
|
|
||||||
|
// output the values
|
||||||
|
std::cout << "value = " << value << '\n';
|
||||||
|
std::cout << "binary = " << json(binary) << '\n';
|
||||||
|
}
|
||||||
2
doc/examples/swap__binary_t.output
Normal file
2
doc/examples/swap__binary_t.output
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
value = {"bytes":[4,5,6],"subtype":null}
|
||||||
|
binary = {"bytes":[1,2,3],"subtype":null}
|
||||||
@ -22,12 +22,14 @@ These pages contain the API documentation of JSON for Modern C++, a C++11 header
|
|||||||
@link nlohmann::basic_json::is_object is_object @endlink,
|
@link nlohmann::basic_json::is_object is_object @endlink,
|
||||||
@link nlohmann::basic_json::is_array is_array @endlink,
|
@link nlohmann::basic_json::is_array is_array @endlink,
|
||||||
@link nlohmann::basic_json::is_string is_string @endlink,
|
@link nlohmann::basic_json::is_string is_string @endlink,
|
||||||
@link nlohmann::basic_json::is_discarded is_discarded @endlink -- check for value type
|
@link nlohmann::basic_json::is_discarded is_discarded @endlink,
|
||||||
|
@link nlohmann::basic_json::is_binary is_binary @endlink -- check for value type
|
||||||
- @link nlohmann::basic_json::operator value_t() const operator value_t @endlink -- type of the value (implicit conversion)
|
- @link nlohmann::basic_json::operator value_t() const operator value_t @endlink -- type of the value (implicit conversion)
|
||||||
- value access
|
- value access
|
||||||
- @link nlohmann::basic_json::get get @endlink -- get a value
|
- @link nlohmann::basic_json::get get @endlink -- get a value
|
||||||
- @link nlohmann::basic_json::get_ptr get_ptr @endlink -- get a value pointer
|
- @link nlohmann::basic_json::get_ptr get_ptr @endlink -- get a value pointer
|
||||||
- @link nlohmann::basic_json::get_ref get_ref @endlink -- get a value reference
|
- @link nlohmann::basic_json::get_ref get_ref @endlink -- get a value reference
|
||||||
|
- @link nlohmann::basic_json::get_binary get_binary @endlink -- get a binary value
|
||||||
- @link nlohmann::basic_json::operator ValueType() const operator ValueType @endlink -- get a value (implicit conversion)
|
- @link nlohmann::basic_json::operator ValueType() const operator ValueType @endlink -- get a value (implicit conversion)
|
||||||
- @link nlohmann::basic_json::value value @endlink -- get a value from an object and return default value if key is not present
|
- @link nlohmann::basic_json::value value @endlink -- get a value from an object and return default value if key is not present
|
||||||
- exceptions
|
- exceptions
|
||||||
@ -67,8 +69,9 @@ These pages contain the API documentation of JSON for Modern C++, a C++11 header
|
|||||||
- @link nlohmann::basic_json::number_integer_t signed integers @endlink
|
- @link nlohmann::basic_json::number_integer_t signed integers @endlink
|
||||||
- @link nlohmann::basic_json::number_unsigned_t unsigned integers @endlink
|
- @link nlohmann::basic_json::number_unsigned_t unsigned integers @endlink
|
||||||
- @link nlohmann::basic_json::number_float_t floating-point @endlink
|
- @link nlohmann::basic_json::number_float_t floating-point @endlink
|
||||||
|
- @link nlohmann::basic_json::binary_t binary values @endlink
|
||||||
- further JSON standards
|
- further JSON standards
|
||||||
- @link nlohmann::json_pointer JSON Pointer @endlink (REF 6901)
|
- @link nlohmann::json_pointer JSON Pointer @endlink (RFC 6901)
|
||||||
- @link nlohmann::basic_json::patch JSON Patch @endlink (RFC 6902)
|
- @link nlohmann::basic_json::patch JSON Patch @endlink (RFC 6902)
|
||||||
- @link nlohmann::basic_json::merge_patch JSON Merge Patch @endlink (RFC 7396)
|
- @link nlohmann::basic_json::merge_patch JSON Merge Patch @endlink (RFC 7396)
|
||||||
|
|
||||||
@ -324,7 +327,7 @@ Note that this table only lists those exceptions thrown due to the type. For ins
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@copyright Copyright © 2013-2019 Niels Lohmann. The code is licensed under the [MIT License](http://opensource.org/licenses/MIT).
|
@copyright Copyright © 2013-2020 Niels Lohmann. The code is licensed under the [MIT License](http://opensource.org/licenses/MIT).
|
||||||
|
|
||||||
@author [Niels Lohmann](http://nlohmann.me)
|
@author [Niels Lohmann](http://nlohmann.me)
|
||||||
@see https://github.com/nlohmann/json to download the source code
|
@see https://github.com/nlohmann/json to download the source code
|
||||||
|
|||||||
167
include/nlohmann/byte_container_with_subtype.hpp
Normal file
167
include/nlohmann/byte_container_with_subtype.hpp
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint> // uint8_t
|
||||||
|
#include <tuple> // tie
|
||||||
|
#include <utility> // move
|
||||||
|
|
||||||
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief an internal type for a backed binary type
|
||||||
|
|
||||||
|
This type extends the template parameter @a BinaryType provided to `basic_json`
|
||||||
|
with a subtype used by BSON and MessagePack. This type exists so that the user
|
||||||
|
does not have to specify a type themselves with a specific naming scheme in
|
||||||
|
order to override the binary type.
|
||||||
|
|
||||||
|
@tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by
|
||||||
|
default)
|
||||||
|
|
||||||
|
@since version 3.8.0
|
||||||
|
*/
|
||||||
|
template<typename BinaryType>
|
||||||
|
class byte_container_with_subtype : public BinaryType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// the type of the underlying container
|
||||||
|
using container_type = BinaryType;
|
||||||
|
|
||||||
|
byte_container_with_subtype() noexcept(noexcept(container_type()))
|
||||||
|
: container_type()
|
||||||
|
{}
|
||||||
|
|
||||||
|
byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
|
||||||
|
: container_type(b)
|
||||||
|
{}
|
||||||
|
|
||||||
|
byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
|
||||||
|
: container_type(std::move(b))
|
||||||
|
{}
|
||||||
|
|
||||||
|
byte_container_with_subtype(const container_type& b,
|
||||||
|
std::uint8_t subtype) noexcept(noexcept(container_type(b)))
|
||||||
|
: container_type(b)
|
||||||
|
, m_subtype(subtype)
|
||||||
|
, m_has_subtype(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
|
||||||
|
: container_type(std::move(b))
|
||||||
|
, m_subtype(subtype)
|
||||||
|
, m_has_subtype(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool operator==(const byte_container_with_subtype& rhs) const
|
||||||
|
{
|
||||||
|
return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
|
||||||
|
std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const byte_container_with_subtype& rhs) const
|
||||||
|
{
|
||||||
|
return !(rhs == *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief sets the binary subtype
|
||||||
|
|
||||||
|
Sets the binary subtype of the value, also flags a binary JSON value as
|
||||||
|
having a subtype, which has implications for serialization.
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@exceptionsafety No-throw guarantee: this member function never throws
|
||||||
|
exceptions.
|
||||||
|
|
||||||
|
@sa @ref subtype() -- return the binary subtype
|
||||||
|
@sa @ref clear_subtype() -- clears the binary subtype
|
||||||
|
@sa @ref has_subtype() -- returns whether or not the binary value has a
|
||||||
|
subtype
|
||||||
|
|
||||||
|
@since version 3.8.0
|
||||||
|
*/
|
||||||
|
void set_subtype(std::uint8_t subtype) noexcept
|
||||||
|
{
|
||||||
|
m_subtype = subtype;
|
||||||
|
m_has_subtype = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief return the binary subtype
|
||||||
|
|
||||||
|
Returns the numerical subtype of the value if it has a subtype. If it does
|
||||||
|
not have a subtype, this function will return size_t(-1) as a sentinel
|
||||||
|
value.
|
||||||
|
|
||||||
|
@return the numerical subtype of the binary value
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@exceptionsafety No-throw guarantee: this member function never throws
|
||||||
|
exceptions.
|
||||||
|
|
||||||
|
@sa @ref set_subtype() -- sets the binary subtype
|
||||||
|
@sa @ref clear_subtype() -- clears the binary subtype
|
||||||
|
@sa @ref has_subtype() -- returns whether or not the binary value has a
|
||||||
|
subtype
|
||||||
|
|
||||||
|
@since version 3.8.0
|
||||||
|
*/
|
||||||
|
constexpr std::uint8_t subtype() const noexcept
|
||||||
|
{
|
||||||
|
return m_subtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief return whether the value has a subtype
|
||||||
|
|
||||||
|
@return whether the value has a subtype
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@exceptionsafety No-throw guarantee: this member function never throws
|
||||||
|
exceptions.
|
||||||
|
|
||||||
|
@sa @ref subtype() -- return the binary subtype
|
||||||
|
@sa @ref set_subtype() -- sets the binary subtype
|
||||||
|
@sa @ref clear_subtype() -- clears the binary subtype
|
||||||
|
|
||||||
|
@since version 3.8.0
|
||||||
|
*/
|
||||||
|
constexpr bool has_subtype() const noexcept
|
||||||
|
{
|
||||||
|
return m_has_subtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief clears the binary subtype
|
||||||
|
|
||||||
|
Clears the binary subtype and flags the value as not having a subtype, which
|
||||||
|
has implications for serialization; for instance MessagePack will prefer the
|
||||||
|
bin family over the ext family.
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@exceptionsafety No-throw guarantee: this member function never throws
|
||||||
|
exceptions.
|
||||||
|
|
||||||
|
@sa @ref subtype() -- return the binary subtype
|
||||||
|
@sa @ref set_subtype() -- sets the binary subtype
|
||||||
|
@sa @ref has_subtype() -- returns whether or not the binary value has a
|
||||||
|
subtype
|
||||||
|
|
||||||
|
@since version 3.8.0
|
||||||
|
*/
|
||||||
|
void clear_subtype() noexcept
|
||||||
|
{
|
||||||
|
m_subtype = 0;
|
||||||
|
m_has_subtype = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::uint8_t m_subtype = 0;
|
||||||
|
bool m_has_subtype = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace nlohmann
|
||||||
8
include/nlohmann/detail/boolean_operators.hpp
Normal file
8
include/nlohmann/detail/boolean_operators.hpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Header <ciso646> is removed in C++20.
|
||||||
|
// See <https://github.com/nlohmann/json/issues/2089> for more information.
|
||||||
|
|
||||||
|
#if __cplusplus <= 201703L
|
||||||
|
#include <ciso646> // and, not, or
|
||||||
|
#endif
|
||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <algorithm> // transform
|
#include <algorithm> // transform
|
||||||
#include <array> // array
|
#include <array> // array
|
||||||
#include <ciso646> // and, not
|
|
||||||
#include <forward_list> // forward_list
|
#include <forward_list> // forward_list
|
||||||
#include <iterator> // inserter, front_inserter, end
|
#include <iterator> // inserter, front_inserter, end
|
||||||
#include <map> // map
|
#include <map> // map
|
||||||
@ -13,6 +12,7 @@
|
|||||||
#include <utility> // pair, declval
|
#include <utility> // pair, declval
|
||||||
#include <valarray> // valarray
|
#include <valarray> // valarray
|
||||||
|
|
||||||
|
#include <nlohmann/detail/boolean_operators.hpp>
|
||||||
#include <nlohmann/detail/exceptions.hpp>
|
#include <nlohmann/detail/exceptions.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
#include <nlohmann/detail/meta/cpp_future.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
@ -243,9 +243,9 @@ template <typename BasicJsonType, typename ConstructibleArrayType,
|
|||||||
is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
|
is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
|
||||||
not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
|
not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
|
||||||
not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
|
not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
|
||||||
|
not std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value and
|
||||||
not is_basic_json<ConstructibleArrayType>::value,
|
not is_basic_json<ConstructibleArrayType>::value,
|
||||||
int > = 0 >
|
int > = 0 >
|
||||||
|
|
||||||
auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
|
auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
|
||||||
-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
|
-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
|
||||||
j.template get<typename ConstructibleArrayType::value_type>(),
|
j.template get<typename ConstructibleArrayType::value_type>(),
|
||||||
@ -260,6 +260,17 @@ void())
|
|||||||
from_json_array_impl(j, arr, priority_tag<3> {});
|
from_json_array_impl(j, arr, priority_tag<3> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename BasicJsonType>
|
||||||
|
void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
|
||||||
|
{
|
||||||
|
if (JSON_HEDLEY_UNLIKELY(not j.is_binary()))
|
||||||
|
{
|
||||||
|
JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
|
||||||
|
}
|
||||||
|
|
||||||
|
bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleObjectType,
|
template<typename BasicJsonType, typename ConstructibleObjectType,
|
||||||
enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
|
enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
|
||||||
void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
||||||
|
|||||||
@ -2,12 +2,13 @@
|
|||||||
|
|
||||||
#include <array> // array
|
#include <array> // array
|
||||||
#include <cassert> // assert
|
#include <cassert> // assert
|
||||||
#include <ciso646> // or, and, not
|
|
||||||
#include <cmath> // signbit, isfinite
|
#include <cmath> // signbit, isfinite
|
||||||
#include <cstdint> // intN_t, uintN_t
|
#include <cstdint> // intN_t, uintN_t
|
||||||
#include <cstring> // memcpy, memmove
|
#include <cstring> // memcpy, memmove
|
||||||
#include <limits> // numeric_limits
|
#include <limits> // numeric_limits
|
||||||
#include <type_traits> // conditional
|
#include <type_traits> // conditional
|
||||||
|
|
||||||
|
#include <nlohmann/detail/boolean_operators.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm> // copy
|
#include <algorithm> // copy
|
||||||
#include <ciso646> // or, and, not
|
|
||||||
#include <iterator> // begin, end
|
#include <iterator> // begin, end
|
||||||
#include <string> // string
|
#include <string> // string
|
||||||
#include <tuple> // tuple, get
|
#include <tuple> // tuple, get
|
||||||
@ -10,6 +9,7 @@
|
|||||||
#include <valarray> // valarray
|
#include <valarray> // valarray
|
||||||
#include <vector> // vector
|
#include <vector> // vector
|
||||||
|
|
||||||
|
#include <nlohmann/detail/boolean_operators.hpp>
|
||||||
#include <nlohmann/detail/iterators/iteration_proxy.hpp>
|
#include <nlohmann/detail/iterators/iteration_proxy.hpp>
|
||||||
#include <nlohmann/detail/meta/cpp_future.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
#include <nlohmann/detail/meta/type_traits.hpp>
|
#include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
@ -74,7 +74,7 @@ struct external_constructor<value_t::binary>
|
|||||||
static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
|
static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
|
||||||
{
|
{
|
||||||
j.m_type = value_t::binary;
|
j.m_type = value_t::binary;
|
||||||
typename BasicJsonType::internal_binary_t value{b};
|
typename BasicJsonType::binary_t value{b};
|
||||||
j.m_value = value;
|
j.m_value = value;
|
||||||
j.assert_invariant();
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ struct external_constructor<value_t::binary>
|
|||||||
static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
|
static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
|
||||||
{
|
{
|
||||||
j.m_type = value_t::binary;
|
j.m_type = value_t::binary;
|
||||||
typename BasicJsonType::internal_binary_t value{std::move(b)};
|
typename BasicJsonType::binary_t value{std::move(b)};
|
||||||
j.m_value = value;
|
j.m_value = value;
|
||||||
j.assert_invariant();
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
@ -294,9 +294,9 @@ void to_json(BasicJsonType& j, const std::vector<bool>& e)
|
|||||||
template <typename BasicJsonType, typename CompatibleArrayType,
|
template <typename BasicJsonType, typename CompatibleArrayType,
|
||||||
enable_if_t<is_compatible_array_type<BasicJsonType,
|
enable_if_t<is_compatible_array_type<BasicJsonType,
|
||||||
CompatibleArrayType>::value and
|
CompatibleArrayType>::value and
|
||||||
not is_compatible_object_type<
|
not is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value and
|
||||||
BasicJsonType, CompatibleArrayType>::value and
|
|
||||||
not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
|
not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
|
||||||
|
not std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value and
|
||||||
not is_basic_json<CompatibleArrayType>::value,
|
not is_basic_json<CompatibleArrayType>::value,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
|
void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
|
||||||
@ -304,6 +304,12 @@ void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
|
|||||||
external_constructor<value_t::array>::construct(j, arr);
|
external_constructor<value_t::array>::construct(j, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename BasicJsonType>
|
||||||
|
void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
|
||||||
|
{
|
||||||
|
external_constructor<value_t::binary>::construct(j, bin);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T,
|
template<typename BasicJsonType, typename T,
|
||||||
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
|
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
|
||||||
void to_json(BasicJsonType& j, const std::valarray<T>& arr)
|
void to_json(BasicJsonType& j, const std::valarray<T>& arr)
|
||||||
|
|||||||
@ -32,7 +32,7 @@ namespace detail
|
|||||||
|
|
||||||
@note from https://stackoverflow.com/a/1001328/266378
|
@note from https://stackoverflow.com/a/1001328/266378
|
||||||
*/
|
*/
|
||||||
static bool little_endianess(int num = 1) noexcept
|
static inline bool little_endianess(int num = 1) noexcept
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<char*>(&num) == 1;
|
return *reinterpret_cast<char*>(&num) == 1;
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ class binary_reader
|
|||||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
using number_float_t = typename BasicJsonType::number_float_t;
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
using internal_binary_t = typename BasicJsonType::internal_binary_t;
|
using binary_t = typename BasicJsonType::binary_t;
|
||||||
using json_sax_t = SAX;
|
using json_sax_t = SAX;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -219,7 +219,7 @@ class binary_reader
|
|||||||
@return `true` if the byte array was successfully parsed
|
@return `true` if the byte array was successfully parsed
|
||||||
*/
|
*/
|
||||||
template<typename NumberType>
|
template<typename NumberType>
|
||||||
bool get_bson_binary(const NumberType len, internal_binary_t& result)
|
bool get_bson_binary(const NumberType len, binary_t& result)
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(len < 0))
|
if (JSON_HEDLEY_UNLIKELY(len < 0))
|
||||||
{
|
{
|
||||||
@ -227,8 +227,10 @@ class binary_reader
|
|||||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary")));
|
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary")));
|
||||||
}
|
}
|
||||||
|
|
||||||
result.has_subtype = true; // All BSON binary values have a subtype
|
// All BSON binary values have a subtype
|
||||||
get_number<std::uint8_t>(input_format_t::bson, result.subtype);
|
std::uint8_t subtype;
|
||||||
|
get_number<std::uint8_t>(input_format_t::bson, subtype);
|
||||||
|
result.set_subtype(subtype);
|
||||||
|
|
||||||
return get_binary(input_format_t::bson, len, result);
|
return get_binary(input_format_t::bson, len, result);
|
||||||
}
|
}
|
||||||
@ -274,7 +276,7 @@ class binary_reader
|
|||||||
case 0x05: // binary
|
case 0x05: // binary
|
||||||
{
|
{
|
||||||
std::int32_t len;
|
std::int32_t len;
|
||||||
internal_binary_t value;
|
binary_t value;
|
||||||
return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_binary(len, value) and sax->binary(value);
|
return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_binary(len, value) and sax->binary(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,7 +532,7 @@ class binary_reader
|
|||||||
case 0x5B: // Binary data (eight-byte uint64_t for n follow)
|
case 0x5B: // Binary data (eight-byte uint64_t for n follow)
|
||||||
case 0x5F: // Binary data (indefinite length)
|
case 0x5F: // Binary data (indefinite length)
|
||||||
{
|
{
|
||||||
internal_binary_t b;
|
binary_t b;
|
||||||
return get_cbor_binary(b) and sax->binary(b);
|
return get_cbor_binary(b) and sax->binary(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -860,7 +862,7 @@ class binary_reader
|
|||||||
|
|
||||||
@return whether byte array creation completed
|
@return whether byte array creation completed
|
||||||
*/
|
*/
|
||||||
bool get_cbor_binary(internal_binary_t& result)
|
bool get_cbor_binary(binary_t& result)
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "binary")))
|
if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "binary")))
|
||||||
{
|
{
|
||||||
@ -901,32 +903,36 @@ class binary_reader
|
|||||||
case 0x58: // Binary data (one-byte uint8_t for n follows)
|
case 0x58: // Binary data (one-byte uint8_t for n follows)
|
||||||
{
|
{
|
||||||
std::uint8_t len;
|
std::uint8_t len;
|
||||||
return get_number(input_format_t::cbor, len) and get_binary(input_format_t::cbor, len, result);
|
return get_number(input_format_t::cbor, len) and
|
||||||
|
get_binary(input_format_t::cbor, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x59: // Binary data (two-byte uint16_t for n follow)
|
case 0x59: // Binary data (two-byte uint16_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint16_t len;
|
std::uint16_t len;
|
||||||
return get_number(input_format_t::cbor, len) and get_binary(input_format_t::cbor, len, result);
|
return get_number(input_format_t::cbor, len) and
|
||||||
|
get_binary(input_format_t::cbor, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x5A: // Binary data (four-byte uint32_t for n follow)
|
case 0x5A: // Binary data (four-byte uint32_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint32_t len;
|
std::uint32_t len;
|
||||||
return get_number(input_format_t::cbor, len) and get_binary(input_format_t::cbor, len, result);
|
return get_number(input_format_t::cbor, len) and
|
||||||
|
get_binary(input_format_t::cbor, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x5B: // Binary data (eight-byte uint64_t for n follow)
|
case 0x5B: // Binary data (eight-byte uint64_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint64_t len;
|
std::uint64_t len;
|
||||||
return get_number(input_format_t::cbor, len) and get_binary(input_format_t::cbor, len, result);
|
return get_number(input_format_t::cbor, len) and
|
||||||
|
get_binary(input_format_t::cbor, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x5F: // Binary data (indefinite length)
|
case 0x5F: // Binary data (indefinite length)
|
||||||
{
|
{
|
||||||
while (get() != 0xFF)
|
while (get() != 0xFF)
|
||||||
{
|
{
|
||||||
internal_binary_t chunk;
|
binary_t chunk;
|
||||||
if (not get_cbor_binary(chunk))
|
if (not get_cbor_binary(chunk))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -1276,7 +1282,7 @@ class binary_reader
|
|||||||
case 0xD7: // fixext 8
|
case 0xD7: // fixext 8
|
||||||
case 0xD8: // fixext 16
|
case 0xD8: // fixext 16
|
||||||
{
|
{
|
||||||
internal_binary_t b;
|
binary_t b;
|
||||||
return get_msgpack_binary(b) and sax->binary(b);
|
return get_msgpack_binary(b) and sax->binary(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1499,83 +1505,106 @@ class binary_reader
|
|||||||
|
|
||||||
@return whether byte array creation completed
|
@return whether byte array creation completed
|
||||||
*/
|
*/
|
||||||
bool get_msgpack_binary(internal_binary_t& result)
|
bool get_msgpack_binary(binary_t& result)
|
||||||
{
|
{
|
||||||
|
// helper function to set the subtype
|
||||||
|
auto assign_and_return_true = [&result](std::int8_t subtype)
|
||||||
|
{
|
||||||
|
result.set_subtype(static_cast<std::uint8_t>(subtype));
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
switch (current)
|
switch (current)
|
||||||
{
|
{
|
||||||
case 0xC4: // bin 8
|
case 0xC4: // bin 8
|
||||||
{
|
{
|
||||||
std::uint8_t len;
|
std::uint8_t len;
|
||||||
return get_number(input_format_t::msgpack, len) and get_binary(input_format_t::msgpack, len, result);
|
return get_number(input_format_t::msgpack, len) and
|
||||||
|
get_binary(input_format_t::msgpack, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xC5: // bin 16
|
case 0xC5: // bin 16
|
||||||
{
|
{
|
||||||
std::uint16_t len;
|
std::uint16_t len;
|
||||||
return get_number(input_format_t::msgpack, len) and get_binary(input_format_t::msgpack, len, result);
|
return get_number(input_format_t::msgpack, len) and
|
||||||
|
get_binary(input_format_t::msgpack, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xC6: // bin 32
|
case 0xC6: // bin 32
|
||||||
{
|
{
|
||||||
std::uint32_t len;
|
std::uint32_t len;
|
||||||
return get_number(input_format_t::msgpack, len) and get_binary(input_format_t::msgpack, len, result);
|
return get_number(input_format_t::msgpack, len) and
|
||||||
|
get_binary(input_format_t::msgpack, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xC7: // ext 8
|
case 0xC7: // ext 8
|
||||||
{
|
{
|
||||||
std::uint8_t len;
|
std::uint8_t len;
|
||||||
result.has_subtype = true;
|
std::int8_t subtype;
|
||||||
return get_number(input_format_t::msgpack, len) and
|
return get_number(input_format_t::msgpack, len) and
|
||||||
get_number(input_format_t::msgpack, result.subtype) and
|
get_number(input_format_t::msgpack, subtype) and
|
||||||
get_binary(input_format_t::msgpack, len, result);
|
get_binary(input_format_t::msgpack, len, result) and
|
||||||
|
assign_and_return_true(subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xC8: // ext 16
|
case 0xC8: // ext 16
|
||||||
{
|
{
|
||||||
std::uint16_t len;
|
std::uint16_t len;
|
||||||
result.has_subtype = true;
|
std::int8_t subtype;
|
||||||
return get_number(input_format_t::msgpack, len) and
|
return get_number(input_format_t::msgpack, len) and
|
||||||
get_number(input_format_t::msgpack, result.subtype) and
|
get_number(input_format_t::msgpack, subtype) and
|
||||||
get_binary(input_format_t::msgpack, len, result);
|
get_binary(input_format_t::msgpack, len, result) and
|
||||||
|
assign_and_return_true(subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xC9: // ext 32
|
case 0xC9: // ext 32
|
||||||
{
|
{
|
||||||
std::uint32_t len;
|
std::uint32_t len;
|
||||||
result.has_subtype = true;
|
std::int8_t subtype;
|
||||||
return get_number(input_format_t::msgpack, len) and
|
return get_number(input_format_t::msgpack, len) and
|
||||||
get_number(input_format_t::msgpack, result.subtype) and
|
get_number(input_format_t::msgpack, subtype) and
|
||||||
get_binary(input_format_t::msgpack, len, result);
|
get_binary(input_format_t::msgpack, len, result) and
|
||||||
|
assign_and_return_true(subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD4: // fixext 1
|
case 0xD4: // fixext 1
|
||||||
{
|
{
|
||||||
result.has_subtype = true;
|
std::int8_t subtype;
|
||||||
return get_number(input_format_t::msgpack, result.subtype) and get_binary(input_format_t::msgpack, 1, result);
|
return get_number(input_format_t::msgpack, subtype) and
|
||||||
|
get_binary(input_format_t::msgpack, 1, result) and
|
||||||
|
assign_and_return_true(subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD5: // fixext 2
|
case 0xD5: // fixext 2
|
||||||
{
|
{
|
||||||
result.has_subtype = true;
|
std::int8_t subtype;
|
||||||
return get_number(input_format_t::msgpack, result.subtype) and get_binary(input_format_t::msgpack, 2, result);
|
return get_number(input_format_t::msgpack, subtype) and
|
||||||
|
get_binary(input_format_t::msgpack, 2, result) and
|
||||||
|
assign_and_return_true(subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD6: // fixext 4
|
case 0xD6: // fixext 4
|
||||||
{
|
{
|
||||||
result.has_subtype = true;
|
std::int8_t subtype;
|
||||||
return get_number(input_format_t::msgpack, result.subtype) and get_binary(input_format_t::msgpack, 4, result);
|
return get_number(input_format_t::msgpack, subtype) and
|
||||||
|
get_binary(input_format_t::msgpack, 4, result) and
|
||||||
|
assign_and_return_true(subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD7: // fixext 8
|
case 0xD7: // fixext 8
|
||||||
{
|
{
|
||||||
result.has_subtype = true;
|
std::int8_t subtype;
|
||||||
return get_number(input_format_t::msgpack, result.subtype) and get_binary(input_format_t::msgpack, 8, result);
|
return get_number(input_format_t::msgpack, subtype) and
|
||||||
|
get_binary(input_format_t::msgpack, 8, result) and
|
||||||
|
assign_and_return_true(subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD8: // fixext 16
|
case 0xD8: // fixext 16
|
||||||
{
|
{
|
||||||
result.has_subtype = true;
|
std::int8_t subtype;
|
||||||
return get_number(input_format_t::msgpack, result.subtype) and get_binary(input_format_t::msgpack, 16, result);
|
return get_number(input_format_t::msgpack, subtype) and
|
||||||
|
get_binary(input_format_t::msgpack, 16, result) and
|
||||||
|
assign_and_return_true(subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
default: // LCOV_EXCL_LINE
|
default: // LCOV_EXCL_LINE
|
||||||
@ -2194,7 +2223,7 @@ class binary_reader
|
|||||||
template<typename NumberType>
|
template<typename NumberType>
|
||||||
bool get_binary(const input_format_t format,
|
bool get_binary(const input_format_t format,
|
||||||
const NumberType len,
|
const NumberType len,
|
||||||
internal_binary_t& result)
|
binary_t& result)
|
||||||
{
|
{
|
||||||
bool success = true;
|
bool success = true;
|
||||||
std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
|
std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
|
||||||
|
|||||||
@ -23,13 +23,9 @@ input.
|
|||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
struct json_sax
|
struct json_sax
|
||||||
{
|
{
|
||||||
/// type for (signed) integers
|
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
/// type for unsigned integers
|
|
||||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
/// type for floating-point numbers
|
|
||||||
using number_float_t = typename BasicJsonType::number_float_t;
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
/// type for strings
|
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
using binary_t = typename BasicJsonType::binary_t;
|
using binary_t = typename BasicJsonType::binary_t;
|
||||||
|
|
||||||
@ -214,7 +210,7 @@ class json_sax_dom_parser
|
|||||||
|
|
||||||
bool binary(binary_t& val)
|
bool binary(binary_t& val)
|
||||||
{
|
{
|
||||||
handle_value(BasicJsonType::binary_array(std::move(val)));
|
handle_value(std::move(val));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +400,7 @@ class json_sax_dom_callback_parser
|
|||||||
|
|
||||||
bool binary(binary_t& val)
|
bool binary(binary_t& val)
|
||||||
{
|
{
|
||||||
handle_value(BasicJsonType::binary_array(val));
|
handle_value(std::move(val));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ template<typename BasicJsonType> struct internal_iterator
|
|||||||
/// iterator for JSON arrays
|
/// iterator for JSON arrays
|
||||||
typename BasicJsonType::array_t::iterator array_iterator {};
|
typename BasicJsonType::array_t::iterator array_iterator {};
|
||||||
/// iterator for JSON binary arrays
|
/// iterator for JSON binary arrays
|
||||||
typename BasicJsonType::binary_t::iterator binary_iterator {};
|
typename BasicJsonType::binary_t::container_type::iterator binary_iterator {};
|
||||||
/// generic iterator for all other types
|
/// generic iterator for all other types
|
||||||
primitive_iterator_t primitive_iterator {};
|
primitive_iterator_t primitive_iterator {};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ciso646> // not
|
|
||||||
#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
|
#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
|
||||||
#include <type_traits> // conditional, is_const, remove_const
|
#include <type_traits> // conditional, is_const, remove_const
|
||||||
|
|
||||||
|
#include <nlohmann/detail/boolean_operators.hpp>
|
||||||
#include <nlohmann/detail/exceptions.hpp>
|
#include <nlohmann/detail/exceptions.hpp>
|
||||||
#include <nlohmann/detail/iterators/internal_iterator.hpp>
|
#include <nlohmann/detail/iterators/internal_iterator.hpp>
|
||||||
#include <nlohmann/detail/iterators/primitive_iterator.hpp>
|
#include <nlohmann/detail/iterators/primitive_iterator.hpp>
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ciso646> // not
|
|
||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
|
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
|
||||||
|
|
||||||
|
#include <nlohmann/detail/boolean_operators.hpp>
|
||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ciso646> // not
|
|
||||||
#include <limits> // numeric_limits
|
#include <limits> // numeric_limits
|
||||||
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
|
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
|
||||||
#include <utility> // declval
|
#include <utility> // declval
|
||||||
|
|
||||||
|
#include <nlohmann/detail/boolean_operators.hpp>
|
||||||
#include <nlohmann/detail/iterators/iterator_traits.hpp>
|
#include <nlohmann/detail/iterators/iterator_traits.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
#include <nlohmann/detail/meta/cpp_future.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
|||||||
@ -27,7 +27,7 @@ template<typename BasicJsonType, typename CharType>
|
|||||||
class binary_writer
|
class binary_writer
|
||||||
{
|
{
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
using internal_binary_t = typename BasicJsonType::internal_binary_t;
|
using binary_t = typename BasicJsonType::binary_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
@ -194,9 +194,9 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (j.m_value.number_float >= std::numeric_limits<float>::lowest() and
|
if (static_cast<double>(j.m_value.number_float) >= static_cast<double>(std::numeric_limits<float>::lowest()) and
|
||||||
j.m_value.number_float <= std::numeric_limits<float>::max() and
|
static_cast<double>(j.m_value.number_float) <= static_cast<double>((std::numeric_limits<float>::max)()) and
|
||||||
static_cast<double>(static_cast<float>(j.m_value.number_float)) == j.m_value.number_float)
|
static_cast<double>(static_cast<float>(j.m_value.number_float)) == static_cast<double>(j.m_value.number_float))
|
||||||
{
|
{
|
||||||
oa->write_character(get_cbor_float_prefix(static_cast<float>(j.m_value.number_float)));
|
oa->write_character(get_cbor_float_prefix(static_cast<float>(j.m_value.number_float)));
|
||||||
write_number(static_cast<float>(j.m_value.number_float));
|
write_number(static_cast<float>(j.m_value.number_float));
|
||||||
@ -578,7 +578,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
// step 0: determine if the binary type has a set subtype to
|
// step 0: determine if the binary type has a set subtype to
|
||||||
// determine whether or not to use the ext or fixext types
|
// determine whether or not to use the ext or fixext types
|
||||||
const bool use_ext = j.m_value.binary->has_subtype;
|
const bool use_ext = j.m_value.binary->has_subtype();
|
||||||
|
|
||||||
// step 1: write control byte and the byte string length
|
// step 1: write control byte and the byte string length
|
||||||
const auto N = j.m_value.binary->size();
|
const auto N = j.m_value.binary->size();
|
||||||
@ -658,7 +658,7 @@ class binary_writer
|
|||||||
// step 1.5: if this is an ext type, write the subtype
|
// step 1.5: if this is an ext type, write the subtype
|
||||||
if (use_ext)
|
if (use_ext)
|
||||||
{
|
{
|
||||||
write_number(j.m_value.binary->subtype);
|
write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 2: write the byte string
|
// step 2: write the byte string
|
||||||
@ -1080,7 +1080,7 @@ class binary_writer
|
|||||||
/*!
|
/*!
|
||||||
@return The size of the BSON-encoded binary array @a value
|
@return The size of the BSON-encoded binary array @a value
|
||||||
*/
|
*/
|
||||||
static std::size_t calc_bson_binary_size(const typename BasicJsonType::internal_binary_t& value)
|
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
|
||||||
{
|
{
|
||||||
return sizeof(std::int32_t) + value.size() + 1ul;
|
return sizeof(std::int32_t) + value.size() + 1ul;
|
||||||
}
|
}
|
||||||
@ -1108,17 +1108,12 @@ class binary_writer
|
|||||||
@brief Writes a BSON element with key @a name and binary value @a value
|
@brief Writes a BSON element with key @a name and binary value @a value
|
||||||
*/
|
*/
|
||||||
void write_bson_binary(const string_t& name,
|
void write_bson_binary(const string_t& name,
|
||||||
const internal_binary_t& value)
|
const binary_t& value)
|
||||||
{
|
{
|
||||||
write_bson_entry_header(name, 0x05);
|
write_bson_entry_header(name, 0x05);
|
||||||
|
|
||||||
write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
|
write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
|
||||||
std::uint8_t subtype = 0x00; // Generic Binary Subtype
|
write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
|
||||||
if (value.has_subtype)
|
|
||||||
{
|
|
||||||
subtype = value.subtype;
|
|
||||||
}
|
|
||||||
write_number(subtype);
|
|
||||||
|
|
||||||
oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
|
oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
#include <algorithm> // reverse, remove, fill, find, none_of
|
#include <algorithm> // reverse, remove, fill, find, none_of
|
||||||
#include <array> // array
|
#include <array> // array
|
||||||
#include <cassert> // assert
|
#include <cassert> // assert
|
||||||
#include <ciso646> // and, or
|
|
||||||
#include <clocale> // localeconv, lconv
|
#include <clocale> // localeconv, lconv
|
||||||
#include <cmath> // labs, isfinite, isnan, signbit
|
#include <cmath> // labs, isfinite, isnan, signbit
|
||||||
#include <cstddef> // size_t, ptrdiff_t
|
#include <cstddef> // size_t, ptrdiff_t
|
||||||
@ -14,6 +13,7 @@
|
|||||||
#include <type_traits> // is_same
|
#include <type_traits> // is_same
|
||||||
#include <utility> // move
|
#include <utility> // move
|
||||||
|
|
||||||
|
#include <nlohmann/detail/boolean_operators.hpp>
|
||||||
#include <nlohmann/detail/conversions/to_chars.hpp>
|
#include <nlohmann/detail/conversions/to_chars.hpp>
|
||||||
#include <nlohmann/detail/exceptions.hpp>
|
#include <nlohmann/detail/exceptions.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
@ -45,7 +45,7 @@ class serializer
|
|||||||
using number_float_t = typename BasicJsonType::number_float_t;
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
using binary_t = typename BasicJsonType::binary_t;
|
using binary_char_t = typename BasicJsonType::binary_t::value_type;
|
||||||
static constexpr std::uint8_t UTF8_ACCEPT = 0;
|
static constexpr std::uint8_t UTF8_ACCEPT = 0;
|
||||||
static constexpr std::uint8_t UTF8_REJECT = 1;
|
static constexpr std::uint8_t UTF8_REJECT = 1;
|
||||||
|
|
||||||
@ -84,19 +84,22 @@ class serializer
|
|||||||
- strings and object keys are escaped using `escape_string()`
|
- strings and object keys are escaped using `escape_string()`
|
||||||
- integer numbers are converted implicitly via `operator<<`
|
- integer numbers are converted implicitly via `operator<<`
|
||||||
- floating-point numbers are converted to a string using `"%g"` format
|
- floating-point numbers are converted to a string using `"%g"` format
|
||||||
- if specified to, binary values are output using the syntax `b[]`, otherwise an exception is thrown
|
- binary values are serialized as objects containing the subtype and the
|
||||||
|
byte array
|
||||||
|
|
||||||
@param[in] val value to serialize
|
@param[in] val value to serialize
|
||||||
@param[in] pretty_print whether the output shall be pretty-printed
|
@param[in] pretty_print whether the output shall be pretty-printed
|
||||||
|
@param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
|
||||||
|
in the output are escaped with `\uXXXX` sequences, and the result consists
|
||||||
|
of ASCII characters only.
|
||||||
@param[in] indent_step the indent level
|
@param[in] indent_step the indent level
|
||||||
@param[in] current_indent the current indent level (only used internally)
|
@param[in] current_indent the current indent level (only used internally)
|
||||||
@param[in] serialize_binary whether the output shall include non-standard binary output
|
|
||||||
*/
|
*/
|
||||||
void dump(const BasicJsonType& val, const bool pretty_print,
|
void dump(const BasicJsonType& val,
|
||||||
|
const bool pretty_print,
|
||||||
const bool ensure_ascii,
|
const bool ensure_ascii,
|
||||||
const unsigned int indent_step,
|
const unsigned int indent_step,
|
||||||
const unsigned int current_indent = 0,
|
const unsigned int current_indent = 0)
|
||||||
const bool serialize_binary = false)
|
|
||||||
{
|
{
|
||||||
switch (val.m_type)
|
switch (val.m_type)
|
||||||
{
|
{
|
||||||
@ -127,7 +130,7 @@ class serializer
|
|||||||
o->write_character('\"');
|
o->write_character('\"');
|
||||||
dump_escaped(i->first, ensure_ascii);
|
dump_escaped(i->first, ensure_ascii);
|
||||||
o->write_characters("\": ", 3);
|
o->write_characters("\": ", 3);
|
||||||
dump(i->second, true, ensure_ascii, indent_step, new_indent, serialize_binary);
|
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
||||||
o->write_characters(",\n", 2);
|
o->write_characters(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +141,7 @@ class serializer
|
|||||||
o->write_character('\"');
|
o->write_character('\"');
|
||||||
dump_escaped(i->first, ensure_ascii);
|
dump_escaped(i->first, ensure_ascii);
|
||||||
o->write_characters("\": ", 3);
|
o->write_characters("\": ", 3);
|
||||||
dump(i->second, true, ensure_ascii, indent_step, new_indent, serialize_binary);
|
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
||||||
|
|
||||||
o->write_character('\n');
|
o->write_character('\n');
|
||||||
o->write_characters(indent_string.c_str(), current_indent);
|
o->write_characters(indent_string.c_str(), current_indent);
|
||||||
@ -155,7 +158,7 @@ class serializer
|
|||||||
o->write_character('\"');
|
o->write_character('\"');
|
||||||
dump_escaped(i->first, ensure_ascii);
|
dump_escaped(i->first, ensure_ascii);
|
||||||
o->write_characters("\":", 2);
|
o->write_characters("\":", 2);
|
||||||
dump(i->second, false, ensure_ascii, indent_step, current_indent, serialize_binary);
|
dump(i->second, false, ensure_ascii, indent_step, current_indent);
|
||||||
o->write_character(',');
|
o->write_character(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +168,7 @@ class serializer
|
|||||||
o->write_character('\"');
|
o->write_character('\"');
|
||||||
dump_escaped(i->first, ensure_ascii);
|
dump_escaped(i->first, ensure_ascii);
|
||||||
o->write_characters("\":", 2);
|
o->write_characters("\":", 2);
|
||||||
dump(i->second, false, ensure_ascii, indent_step, current_indent, serialize_binary);
|
dump(i->second, false, ensure_ascii, indent_step, current_indent);
|
||||||
|
|
||||||
o->write_character('}');
|
o->write_character('}');
|
||||||
}
|
}
|
||||||
@ -197,14 +200,14 @@ class serializer
|
|||||||
i != val.m_value.array->cend() - 1; ++i)
|
i != val.m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o->write_characters(indent_string.c_str(), new_indent);
|
||||||
dump(*i, true, ensure_ascii, indent_step, new_indent, serialize_binary);
|
dump(*i, true, ensure_ascii, indent_step, new_indent);
|
||||||
o->write_characters(",\n", 2);
|
o->write_characters(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(not val.m_value.array->empty());
|
assert(not val.m_value.array->empty());
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o->write_characters(indent_string.c_str(), new_indent);
|
||||||
dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent, serialize_binary);
|
dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
|
||||||
|
|
||||||
o->write_character('\n');
|
o->write_character('\n');
|
||||||
o->write_characters(indent_string.c_str(), current_indent);
|
o->write_characters(indent_string.c_str(), current_indent);
|
||||||
@ -218,13 +221,13 @@ class serializer
|
|||||||
for (auto i = val.m_value.array->cbegin();
|
for (auto i = val.m_value.array->cbegin();
|
||||||
i != val.m_value.array->cend() - 1; ++i)
|
i != val.m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
dump(*i, false, ensure_ascii, indent_step, current_indent, serialize_binary);
|
dump(*i, false, ensure_ascii, indent_step, current_indent);
|
||||||
o->write_character(',');
|
o->write_character(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(not val.m_value.array->empty());
|
assert(not val.m_value.array->empty());
|
||||||
dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent, serialize_binary);
|
dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
|
||||||
|
|
||||||
o->write_character(']');
|
o->write_character(']');
|
||||||
}
|
}
|
||||||
@ -242,27 +245,73 @@ class serializer
|
|||||||
|
|
||||||
case value_t::binary:
|
case value_t::binary:
|
||||||
{
|
{
|
||||||
if (not serialize_binary)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
JSON_THROW(type_error::create(317, "cannot serialize binary data to text JSON"));
|
o->write_characters("{\n", 2);
|
||||||
}
|
|
||||||
|
|
||||||
if (val.m_value.binary->empty())
|
// variable to hold indentation for recursive calls
|
||||||
{
|
const auto new_indent = current_indent + indent_step;
|
||||||
o->write_characters("b[]", 3);
|
if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
|
||||||
|
{
|
||||||
|
indent_string.resize(indent_string.size() * 2, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
o->write_characters(indent_string.c_str(), new_indent);
|
||||||
|
|
||||||
|
o->write_characters("\"bytes\": [", 10);
|
||||||
|
|
||||||
|
if (not val.m_value.binary->empty())
|
||||||
|
{
|
||||||
|
for (auto i = val.m_value.binary->cbegin();
|
||||||
|
i != val.m_value.binary->cend() - 1; ++i)
|
||||||
|
{
|
||||||
|
dump_integer(*i);
|
||||||
|
o->write_characters(", ", 2);
|
||||||
|
}
|
||||||
|
dump_integer(val.m_value.binary->back());
|
||||||
|
}
|
||||||
|
|
||||||
|
o->write_characters("],\n", 3);
|
||||||
|
o->write_characters(indent_string.c_str(), new_indent);
|
||||||
|
|
||||||
|
o->write_characters("\"subtype\": ", 11);
|
||||||
|
if (val.m_value.binary->has_subtype())
|
||||||
|
{
|
||||||
|
dump_integer(val.m_value.binary->subtype());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
o->write_characters("null", 4);
|
||||||
|
}
|
||||||
|
o->write_character('\n');
|
||||||
|
o->write_characters(indent_string.c_str(), current_indent);
|
||||||
|
o->write_character('}');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o->write_characters("b[", 2);
|
o->write_characters("{\"bytes\":[", 10);
|
||||||
for (auto i = val.m_value.binary->cbegin();
|
|
||||||
i != val.m_value.binary->cend() - 1; ++i)
|
if (not val.m_value.binary->empty())
|
||||||
{
|
{
|
||||||
dump_integer(*i);
|
for (auto i = val.m_value.binary->cbegin();
|
||||||
o->write_character(',');
|
i != val.m_value.binary->cend() - 1; ++i)
|
||||||
|
{
|
||||||
|
dump_integer(*i);
|
||||||
|
o->write_character(',');
|
||||||
|
}
|
||||||
|
dump_integer(val.m_value.binary->back());
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_integer(val.m_value.binary->back());
|
o->write_characters("],\"subtype\":", 12);
|
||||||
o->write_character(']');
|
if (val.m_value.binary->has_subtype())
|
||||||
|
{
|
||||||
|
dump_integer(val.m_value.binary->subtype());
|
||||||
|
o->write_character('}');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
o->write_characters("null}", 5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -624,7 +673,7 @@ class serializer
|
|||||||
template<typename NumberType, detail::enable_if_t<
|
template<typename NumberType, detail::enable_if_t<
|
||||||
std::is_same<NumberType, number_unsigned_t>::value or
|
std::is_same<NumberType, number_unsigned_t>::value or
|
||||||
std::is_same<NumberType, number_integer_t>::value or
|
std::is_same<NumberType, number_integer_t>::value or
|
||||||
std::is_same<NumberType, typename binary_t::value_type>::value,
|
std::is_same<NumberType, binary_char_t>::value,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
void dump_integer(NumberType x)
|
void dump_integer(NumberType x)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array> // array
|
#include <array> // array
|
||||||
#include <ciso646> // and
|
|
||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
#include <cstdint> // uint8_t
|
#include <cstdint> // uint8_t
|
||||||
#include <string> // string
|
#include <string> // string
|
||||||
|
|
||||||
|
#include <nlohmann/detail/boolean_operators.hpp>
|
||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
|
|||||||
@ -36,7 +36,6 @@ SOFTWARE.
|
|||||||
|
|
||||||
#include <algorithm> // all_of, find, for_each
|
#include <algorithm> // all_of, find, for_each
|
||||||
#include <cassert> // assert
|
#include <cassert> // assert
|
||||||
#include <ciso646> // and, not, or
|
|
||||||
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
|
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
|
||||||
#include <functional> // hash, less
|
#include <functional> // hash, less
|
||||||
#include <initializer_list> // initializer_list
|
#include <initializer_list> // initializer_list
|
||||||
@ -49,6 +48,8 @@ SOFTWARE.
|
|||||||
#include <vector> // vector
|
#include <vector> // vector
|
||||||
|
|
||||||
#include <nlohmann/adl_serializer.hpp>
|
#include <nlohmann/adl_serializer.hpp>
|
||||||
|
#include <nlohmann/byte_container_with_subtype.hpp>
|
||||||
|
#include <nlohmann/detail/boolean_operators.hpp>
|
||||||
#include <nlohmann/detail/conversions/from_json.hpp>
|
#include <nlohmann/detail/conversions/from_json.hpp>
|
||||||
#include <nlohmann/detail/conversions/to_json.hpp>
|
#include <nlohmann/detail/conversions/to_json.hpp>
|
||||||
#include <nlohmann/detail/exceptions.hpp>
|
#include <nlohmann/detail/exceptions.hpp>
|
||||||
@ -838,21 +839,20 @@ class basic_json
|
|||||||
|
|
||||||
This type is a type designed to carry binary data that appears in various
|
This type is a type designed to carry binary data that appears in various
|
||||||
serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
|
serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
|
||||||
BSON's generic binary subtype. This type is NOT a part of standard JSON and
|
BSON's generic binary subtype. This type is NOT a part of standard JSON and
|
||||||
exists solely for compatibility with these binary types. As such, it is
|
exists solely for compatibility with these binary types. As such, it is
|
||||||
simply defined as an ordered sequence of zero or more byte values.
|
simply defined as an ordered sequence of zero or more byte values.
|
||||||
|
|
||||||
Additionally, as an implementation detail, the subtype of the binary data is
|
Additionally, as an implementation detail, the subtype of the binary data is
|
||||||
carried around as a `unint8_t`, which is compatible with both of the binary
|
carried around as a `std::uint8_t`, which is compatible with both of the
|
||||||
data formats that use binary subtyping, (though the specific numbering is
|
binary data formats that use binary subtyping, (though the specific
|
||||||
incompatible with each other, and it is up to the user to translate between
|
numbering is incompatible with each other, and it is up to the user to
|
||||||
them).
|
translate between them).
|
||||||
|
|
||||||
[CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
|
[CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
|
||||||
as:
|
as:
|
||||||
> Major type 2: a byte string. The string's length in bytes is
|
> Major type 2: a byte string. The string's length in bytes is represented
|
||||||
> represented following the rules for positive integers (major type
|
> following the rules for positive integers (major type 0).
|
||||||
> 0).
|
|
||||||
|
|
||||||
[MessagePack's documentation on the bin type
|
[MessagePack's documentation on the bin type
|
||||||
family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
|
family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
|
||||||
@ -868,7 +868,7 @@ class basic_json
|
|||||||
|
|
||||||
None of these impose any limitations on the internal representation other
|
None of these impose any limitations on the internal representation other
|
||||||
than the basic unit of storage be some type of array whose parts are
|
than the basic unit of storage be some type of array whose parts are
|
||||||
decomposible into bytes.
|
decomposable into bytes.
|
||||||
|
|
||||||
The default representation of this binary format is a
|
The default representation of this binary format is a
|
||||||
`std::vector<std::uint8_t>`, which is a very common way to represent a byte
|
`std::vector<std::uint8_t>`, which is a very common way to represent a byte
|
||||||
@ -880,53 +880,30 @@ class basic_json
|
|||||||
|
|
||||||
#### Storage
|
#### Storage
|
||||||
|
|
||||||
Binary Arrays are stored as pointers in a @ref basic_json type. That is,
|
Binary Arrays are stored as pointers in a @ref basic_json type. That is,
|
||||||
for any access to array values, a pointer of the type `binary_t*` must be
|
for any access to array values, a pointer of the type `binary_t*` must be
|
||||||
dereferenced.
|
dereferenced.
|
||||||
|
|
||||||
@sa @ref array_t -- type for an array value
|
#### Notes on subtypes
|
||||||
|
|
||||||
|
- CBOR
|
||||||
|
- Binary values are represented as byte strings. No subtypes are
|
||||||
|
supported and will be ignored when CBOR is written.
|
||||||
|
- MessagePack
|
||||||
|
- If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
|
||||||
|
or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
|
||||||
|
is used. For other sizes, the ext family (ext8, ext16, ext32) is used.
|
||||||
|
The subtype is then added as singed 8-bit integer.
|
||||||
|
- If no subtype is given, the bin family (bin8, bin16, bin32) is used.
|
||||||
|
- BSON
|
||||||
|
- If a subtype is given, it is used and added as unsigned 8-bit integer.
|
||||||
|
- If no subtype is given, the generic binary subtype 0x00 is used.
|
||||||
|
|
||||||
|
@sa @ref binary -- create a binary array
|
||||||
|
|
||||||
@since version 3.8.0
|
@since version 3.8.0
|
||||||
*/
|
*/
|
||||||
using binary_t = BinaryType;
|
using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief an internal type for a backed binary type
|
|
||||||
|
|
||||||
This type is designed to be `binary_t` but with the subtype implementation
|
|
||||||
detail. This type exists so that the user does not have to specify a struct
|
|
||||||
his- or herself with a specific naming scheme in order to override the
|
|
||||||
binary type. I.e. it's for ease of use.
|
|
||||||
*/
|
|
||||||
struct internal_binary_t : public BinaryType
|
|
||||||
{
|
|
||||||
using BinaryType::BinaryType;
|
|
||||||
internal_binary_t() noexcept(noexcept(BinaryType()))
|
|
||||||
: BinaryType()
|
|
||||||
{}
|
|
||||||
internal_binary_t(const BinaryType& bint) noexcept(noexcept(BinaryType(bint)))
|
|
||||||
: BinaryType(bint)
|
|
||||||
{}
|
|
||||||
internal_binary_t(BinaryType&& bint) noexcept(noexcept(BinaryType(std::move(bint))))
|
|
||||||
: BinaryType(std::move(bint))
|
|
||||||
{}
|
|
||||||
internal_binary_t(const BinaryType& bint, std::uint8_t st) noexcept(noexcept(BinaryType(bint)))
|
|
||||||
: BinaryType(bint)
|
|
||||||
, subtype(st)
|
|
||||||
, has_subtype(true)
|
|
||||||
{}
|
|
||||||
internal_binary_t(BinaryType&& bint, std::uint8_t st) noexcept(noexcept(BinaryType(std::move(bint))))
|
|
||||||
: BinaryType(std::move(bint))
|
|
||||||
, subtype(st)
|
|
||||||
, has_subtype(true)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// TOOD: If minimum C++ version is ever bumped to C++17, this field
|
|
||||||
// deserves to be a std::optional
|
|
||||||
std::uint8_t subtype = 0;
|
|
||||||
bool has_subtype = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -969,7 +946,7 @@ class basic_json
|
|||||||
number | number_integer | @ref number_integer_t
|
number | number_integer | @ref number_integer_t
|
||||||
number | number_unsigned | @ref number_unsigned_t
|
number | number_unsigned | @ref number_unsigned_t
|
||||||
number | number_float | @ref number_float_t
|
number | number_float | @ref number_float_t
|
||||||
binary | binary | pointer to @ref internal_binary_t
|
binary | binary | pointer to @ref binary_t
|
||||||
null | null | *no value is stored*
|
null | null | *no value is stored*
|
||||||
|
|
||||||
@note Variable-length types (objects, arrays, and strings) are stored as
|
@note Variable-length types (objects, arrays, and strings) are stored as
|
||||||
@ -987,7 +964,7 @@ class basic_json
|
|||||||
/// string (stored with pointer to save storage)
|
/// string (stored with pointer to save storage)
|
||||||
string_t* string;
|
string_t* string;
|
||||||
/// binary (stored with pointer to save storage)
|
/// binary (stored with pointer to save storage)
|
||||||
internal_binary_t* binary;
|
binary_t* binary;
|
||||||
/// boolean
|
/// boolean
|
||||||
boolean_t boolean;
|
boolean_t boolean;
|
||||||
/// number (integer)
|
/// number (integer)
|
||||||
@ -1032,7 +1009,7 @@ class basic_json
|
|||||||
|
|
||||||
case value_t::binary:
|
case value_t::binary:
|
||||||
{
|
{
|
||||||
binary = create<internal_binary_t>();
|
binary = create<binary_t>();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1115,27 +1092,27 @@ class basic_json
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// constructor for binary arrays
|
/// constructor for binary arrays
|
||||||
json_value(const binary_t& value)
|
json_value(const typename binary_t::container_type& value)
|
||||||
{
|
{
|
||||||
binary = create<internal_binary_t>(value);
|
binary = create<binary_t>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// constructor for rvalue binary arrays
|
/// constructor for rvalue binary arrays
|
||||||
json_value(binary_t&& value)
|
json_value(typename binary_t::container_type&& value)
|
||||||
{
|
{
|
||||||
binary = create<internal_binary_t>(std::move(value));
|
binary = create<binary_t>(std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// constructor for binary arrays (internal type)
|
/// constructor for binary arrays (internal type)
|
||||||
json_value(const internal_binary_t& value)
|
json_value(const binary_t& value)
|
||||||
{
|
{
|
||||||
binary = create<internal_binary_t>(value);
|
binary = create<binary_t>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// constructor for rvalue binary arrays (internal type)
|
/// constructor for rvalue binary arrays (internal type)
|
||||||
json_value(internal_binary_t&& value)
|
json_value(binary_t&& value)
|
||||||
{
|
{
|
||||||
binary = create<internal_binary_t>(std::move(value));
|
binary = create<binary_t>(std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy(value_t t) noexcept
|
void destroy(value_t t) noexcept
|
||||||
@ -1215,7 +1192,7 @@ class basic_json
|
|||||||
|
|
||||||
case value_t::binary:
|
case value_t::binary:
|
||||||
{
|
{
|
||||||
AllocatorType<internal_binary_t> alloc;
|
AllocatorType<binary_t> alloc;
|
||||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
|
std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
|
||||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
|
std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
|
||||||
break;
|
break;
|
||||||
@ -1501,7 +1478,7 @@ class basic_json
|
|||||||
using other_string_t = typename BasicJsonType::string_t;
|
using other_string_t = typename BasicJsonType::string_t;
|
||||||
using other_object_t = typename BasicJsonType::object_t;
|
using other_object_t = typename BasicJsonType::object_t;
|
||||||
using other_array_t = typename BasicJsonType::array_t;
|
using other_array_t = typename BasicJsonType::array_t;
|
||||||
using other_binary_t = typename BasicJsonType::internal_binary_t;
|
using other_binary_t = typename BasicJsonType::binary_t;
|
||||||
|
|
||||||
switch (val.type())
|
switch (val.type())
|
||||||
{
|
{
|
||||||
@ -1668,22 +1645,22 @@ class basic_json
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief explicitly create a binary array from an already constructed copy of
|
@brief explicitly create a binary array (without subtype)
|
||||||
its base type
|
|
||||||
|
|
||||||
Creates a JSON binary array value from a given `binary_t`. Binary values are
|
Creates a JSON binary array value from a given binary container. Binary
|
||||||
part of various binary formats, such as CBOR, MsgPack, and BSON. And this
|
values are part of various binary formats, such as CBOR, MessagePack, and
|
||||||
constructor is used to create a value for serialization to those formats.
|
BSON. This constructor is used to create a value for serialization to those
|
||||||
|
formats.
|
||||||
|
|
||||||
@note Note, this function exists because of the difficulty in correctly
|
@note Note, this function exists because of the difficulty in correctly
|
||||||
specifying the correct template overload in the standard value ctor, as both
|
specifying the correct template overload in the standard value ctor, as both
|
||||||
JSON arrays and JSON binary arrays are backed with some form of a
|
JSON arrays and JSON binary arrays are backed with some form of a
|
||||||
`std::vector`. Because JSON binary arrays are a non-standard extension it
|
`std::vector`. Because JSON binary arrays are a non-standard extension it
|
||||||
was decided that it would be best to prevent automatic initialization of a
|
was decided that it would be best to prevent automatic initialization of a
|
||||||
binary array type, for backwards compatibility and so it does not happen on
|
binary array type, for backwards compatibility and so it does not happen on
|
||||||
accident.
|
accident.
|
||||||
|
|
||||||
@param[in] init `binary_t` with JSON values to create a binary array from
|
@param[in] init container containing bytes to use as binary type
|
||||||
|
|
||||||
@return JSON binary array value
|
@return JSON binary array value
|
||||||
|
|
||||||
@ -1695,7 +1672,7 @@ class basic_json
|
|||||||
@since version 3.8.0
|
@since version 3.8.0
|
||||||
*/
|
*/
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
static basic_json binary_array(const binary_t& init)
|
static basic_json binary(const typename binary_t::container_type& init)
|
||||||
{
|
{
|
||||||
auto res = basic_json();
|
auto res = basic_json();
|
||||||
res.m_type = value_t::binary;
|
res.m_type = value_t::binary;
|
||||||
@ -1703,32 +1680,24 @@ class basic_json
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
|
||||||
static basic_json binary_array(const binary_t& init, std::uint8_t subtype)
|
|
||||||
{
|
|
||||||
auto res = basic_json();
|
|
||||||
res.m_type = value_t::binary;
|
|
||||||
res.m_value = internal_binary_t(init, subtype);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief explicitly create a binary array from an already constructed rvalue
|
@brief explicitly create a binary array (with subtype)
|
||||||
copy of its base type
|
|
||||||
|
|
||||||
Creates a JSON binary array value from a given `binary_t`. Binary values are
|
Creates a JSON binary array value from a given binary container. Binary
|
||||||
part of various binary formats, such as CBOR, MsgPack, and BSON. And this
|
values are part of various binary formats, such as CBOR, MessagePack, and
|
||||||
constructor is used to create a value for serialization to those formats.
|
BSON. This constructor is used to create a value for serialization to those
|
||||||
|
formats.
|
||||||
|
|
||||||
@note Note, this function exists because of the difficulty in correctly
|
@note Note, this function exists because of the difficulty in correctly
|
||||||
specifying the correct template overload in the standard value ctor, as both
|
specifying the correct template overload in the standard value ctor, as both
|
||||||
JSON arrays and JSON binary arrays are backed with some form of a
|
JSON arrays and JSON binary arrays are backed with some form of a
|
||||||
`std::vector`. Because JSON binary arrays are a non-standard extension it
|
`std::vector`. Because JSON binary arrays are a non-standard extension it
|
||||||
was decided that it would be best to prevent automatic initialization of a
|
was decided that it would be best to prevent automatic initialization of a
|
||||||
binary array type, for backwards compatibility and so it doesn't happen on
|
binary array type, for backwards compatibility and so it does not happen on
|
||||||
accident.
|
accident.
|
||||||
|
|
||||||
@param[in] init `binary_t` with JSON values to create a binary array from
|
@param[in] init container containing bytes to use as binary type
|
||||||
|
@param[in] subtype subtype to use in MessagePack and BSON
|
||||||
|
|
||||||
@return JSON binary array value
|
@return JSON binary array value
|
||||||
|
|
||||||
@ -1740,7 +1709,17 @@ class basic_json
|
|||||||
@since version 3.8.0
|
@since version 3.8.0
|
||||||
*/
|
*/
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
static basic_json binary_array(binary_t&& init)
|
static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
|
||||||
|
{
|
||||||
|
auto res = basic_json();
|
||||||
|
res.m_type = value_t::binary;
|
||||||
|
res.m_value = binary_t(init, subtype);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @copydoc binary(const typename binary_t::container_type&)
|
||||||
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
static basic_json binary(typename binary_t::container_type&& init)
|
||||||
{
|
{
|
||||||
auto res = basic_json();
|
auto res = basic_json();
|
||||||
res.m_type = value_t::binary;
|
res.m_type = value_t::binary;
|
||||||
@ -1748,12 +1727,13 @@ class basic_json
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @copydoc binary(const typename binary_t::container_type&, std::uint8_t)
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
static basic_json binary_array(binary_t&& init, std::uint8_t subtype)
|
static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
|
||||||
{
|
{
|
||||||
auto res = basic_json();
|
auto res = basic_json();
|
||||||
res.m_type = value_t::binary;
|
res.m_type = value_t::binary;
|
||||||
res.m_value = internal_binary_t(std::move(init), subtype);
|
res.m_value = binary_t(std::move(init), subtype);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2257,16 +2237,15 @@ class basic_json
|
|||||||
possible values: `strict` (throws and exception in case a decoding error
|
possible values: `strict` (throws and exception in case a decoding error
|
||||||
occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
|
occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
|
||||||
and `ignore` (ignore invalid UTF-8 sequences during serialization).
|
and `ignore` (ignore invalid UTF-8 sequences during serialization).
|
||||||
@param[in] serialize_binary Whether or not to allow serialization of binary
|
|
||||||
types to JSON. Because binary types are non-standard, this will produce
|
|
||||||
non-conformant JSON, and is disabled by default. This flag is primarily
|
|
||||||
useful for debugging. Will output the binary value as a list of 8-bit
|
|
||||||
numbers prefixed by "b" (e.g. "bindata" = b[3, 0, 42, 255]).
|
|
||||||
|
|
||||||
@return string containing the serialization of the JSON value
|
@return string containing the serialization of the JSON value
|
||||||
|
|
||||||
@throw type_error.316 if a string stored inside the JSON value is not
|
@throw type_error.316 if a string stored inside the JSON value is not
|
||||||
UTF-8 encoded
|
UTF-8 encoded and @a error_handler is set to strict
|
||||||
|
|
||||||
|
@note Binary values are serialized as object containing two keys:
|
||||||
|
- "bytes": an array of bytes as integers
|
||||||
|
- "subtype": the subtype as integer or "null" if the binary has no subtype
|
||||||
|
|
||||||
@complexity Linear.
|
@complexity Linear.
|
||||||
|
|
||||||
@ -2281,24 +2260,24 @@ class basic_json
|
|||||||
|
|
||||||
@since version 1.0.0; indentation character @a indent_char, option
|
@since version 1.0.0; indentation character @a indent_char, option
|
||||||
@a ensure_ascii and exceptions added in version 3.0.0; error
|
@a ensure_ascii and exceptions added in version 3.0.0; error
|
||||||
handlers added in version 3.4.0.
|
handlers added in version 3.4.0; serialization of binary values added
|
||||||
|
in version 3.8.0.
|
||||||
*/
|
*/
|
||||||
string_t dump(const int indent = -1,
|
string_t dump(const int indent = -1,
|
||||||
const char indent_char = ' ',
|
const char indent_char = ' ',
|
||||||
const bool ensure_ascii = false,
|
const bool ensure_ascii = false,
|
||||||
const error_handler_t error_handler = error_handler_t::strict,
|
const error_handler_t error_handler = error_handler_t::strict) const
|
||||||
const bool serialize_binary = false) const
|
|
||||||
{
|
{
|
||||||
string_t result;
|
string_t result;
|
||||||
serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
|
serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
|
||||||
|
|
||||||
if (indent >= 0)
|
if (indent >= 0)
|
||||||
{
|
{
|
||||||
s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent), 0, serialize_binary);
|
s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s.dump(*this, false, ensure_ascii, 0, 0, serialize_binary);
|
s.dump(*this, false, ensure_ascii, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -2805,7 +2784,7 @@ class basic_json
|
|||||||
/// get a pointer to the value (binary)
|
/// get a pointer to the value (binary)
|
||||||
binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
|
binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
return is_binary() ? reinterpret_cast<binary_t*>(m_value.binary) : nullptr;
|
return is_binary() ? m_value.binary : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get a pointer to the value (binary)
|
/// get a pointer to the value (binary)
|
||||||
@ -2814,18 +2793,6 @@ class basic_json
|
|||||||
return is_binary() ? m_value.binary : nullptr;
|
return is_binary() ? m_value.binary : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get a pointer to the value (binary)
|
|
||||||
internal_binary_t* get_impl_ptr(internal_binary_t* /*unused*/) noexcept
|
|
||||||
{
|
|
||||||
return is_binary() ? m_value.binary : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// get a pointer to the value (binary)
|
|
||||||
constexpr const internal_binary_t* get_impl_ptr(const internal_binary_t* /*unused*/) const noexcept
|
|
||||||
{
|
|
||||||
return is_binary() ? m_value.binary : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief helper function to implement get_ref()
|
@brief helper function to implement get_ref()
|
||||||
|
|
||||||
@ -3251,6 +3218,36 @@ class basic_json
|
|||||||
return get<ValueType>();
|
return get<ValueType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@return reference to the binary value
|
||||||
|
|
||||||
|
@throw type_error.302 if the value is not binary
|
||||||
|
|
||||||
|
@sa @ref is_binary() to check if the value is binary
|
||||||
|
|
||||||
|
@since version 3.8.0
|
||||||
|
*/
|
||||||
|
binary_t& get_binary()
|
||||||
|
{
|
||||||
|
if (not is_binary())
|
||||||
|
{
|
||||||
|
JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return *get_ptr<binary_t*>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @copydoc get_binary()
|
||||||
|
const binary_t& get_binary() const
|
||||||
|
{
|
||||||
|
if (not is_binary())
|
||||||
|
{
|
||||||
|
JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return *get_ptr<const binary_t*>();
|
||||||
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
@ -3873,120 +3870,6 @@ class basic_json
|
|||||||
return value(ptr, string_t(default_value));
|
return value(ptr, string_t(default_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief return the binary subtype
|
|
||||||
|
|
||||||
Returns the numerical subtype of the JSON value, if the JSON value is of
|
|
||||||
type "binary", and it has a subtype. If it does not have a subtype (or the
|
|
||||||
object is not of type binary) this function will return size_t(-1) as a
|
|
||||||
sentinel value.
|
|
||||||
|
|
||||||
@return the numerical subtype of the binary JSON value
|
|
||||||
|
|
||||||
@complexity Constant.
|
|
||||||
|
|
||||||
@exceptionsafety No-throw guarantee: this member function never throws
|
|
||||||
exceptions.
|
|
||||||
|
|
||||||
@sa @ref set_subtype() -- sets the binary subtype
|
|
||||||
@sa @ref clear_subtype() -- clears the binary subtype
|
|
||||||
@sa @ref has_subtype() -- returns whether or not the binary value has a
|
|
||||||
subtype
|
|
||||||
|
|
||||||
@since version 3.8.0
|
|
||||||
*/
|
|
||||||
std::size_t get_subtype() const noexcept
|
|
||||||
{
|
|
||||||
if (is_binary() and m_value.binary->has_subtype)
|
|
||||||
{
|
|
||||||
return m_value.binary->subtype;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::size_t(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief sets the binary subtype
|
|
||||||
|
|
||||||
Sets the binary subtype of the JSON value, also flags a binary JSON value as
|
|
||||||
having a subtype, which has implications for serialization to msgpack (will
|
|
||||||
prefer ext file formats over bin). If the JSON value is not a binary value,
|
|
||||||
this function does nothing.
|
|
||||||
|
|
||||||
@complexity Constant.
|
|
||||||
|
|
||||||
@exceptionsafety No-throw guarantee: this member function never throws
|
|
||||||
exceptions.
|
|
||||||
|
|
||||||
@sa @ref get_subtype() -- return the binary subtype
|
|
||||||
@sa @ref clear_subtype() -- clears the binary subtype
|
|
||||||
@sa @ref has_subtype() -- returns whether or not the binary value has a
|
|
||||||
subtype
|
|
||||||
|
|
||||||
@since version 3.8.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
void set_subtype(std::uint8_t subtype) noexcept
|
|
||||||
{
|
|
||||||
if (is_binary())
|
|
||||||
{
|
|
||||||
m_value.binary->has_subtype = true;
|
|
||||||
m_value.binary->subtype = subtype;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief clears the binary subtype
|
|
||||||
|
|
||||||
Clears the binary subtype of the JSON value, also flags a binary JSON value
|
|
||||||
as not having a subtype, which has implications for serialization to msgpack
|
|
||||||
(will prefer bin file formats over ext). If the JSON value is not a binary
|
|
||||||
value, this function does nothing.
|
|
||||||
|
|
||||||
@complexity Constant.
|
|
||||||
|
|
||||||
@exceptionsafety No-throw guarantee: this member function never throws
|
|
||||||
exceptions.
|
|
||||||
|
|
||||||
@sa @ref get_subtype() -- return the binary subtype
|
|
||||||
@sa @ref set_subtype() -- sets the binary subtype
|
|
||||||
@sa @ref has_subtype() -- returns whether or not the binary value has a
|
|
||||||
subtype
|
|
||||||
|
|
||||||
@since version 3.8.0
|
|
||||||
*/
|
|
||||||
void clear_subtype() noexcept
|
|
||||||
{
|
|
||||||
if (is_binary())
|
|
||||||
{
|
|
||||||
m_value.binary->has_subtype = false;
|
|
||||||
m_value.binary->subtype = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief return whether or not the binary subtype has a value
|
|
||||||
|
|
||||||
Returns whether or not the binary subtype has a value.
|
|
||||||
|
|
||||||
@return whether or not the binary subtype has a value.
|
|
||||||
|
|
||||||
@complexity Constant.
|
|
||||||
|
|
||||||
@exceptionsafety No-throw guarantee: this member function never throws
|
|
||||||
exceptions.
|
|
||||||
|
|
||||||
@sa @ref get_subtype() -- return the binary subtype
|
|
||||||
@sa @ref set_subtype() -- sets the binary subtype
|
|
||||||
@sa @ref clear_subtype() -- clears the binary subtype
|
|
||||||
|
|
||||||
@since version 3.8.0
|
|
||||||
*/
|
|
||||||
bool has_subtype() const noexcept
|
|
||||||
{
|
|
||||||
return is_binary() and m_value.binary->has_subtype;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief access the first element
|
@brief access the first element
|
||||||
|
|
||||||
@ -4156,7 +4039,7 @@ class basic_json
|
|||||||
}
|
}
|
||||||
else if (is_binary())
|
else if (is_binary())
|
||||||
{
|
{
|
||||||
AllocatorType<internal_binary_t> alloc;
|
AllocatorType<binary_t> alloc;
|
||||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
|
std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
|
||||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
|
std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
|
||||||
m_value.binary = nullptr;
|
m_value.binary = nullptr;
|
||||||
@ -4270,7 +4153,7 @@ class basic_json
|
|||||||
}
|
}
|
||||||
else if (is_binary())
|
else if (is_binary())
|
||||||
{
|
{
|
||||||
AllocatorType<internal_binary_t> alloc;
|
AllocatorType<binary_t> alloc;
|
||||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
|
std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
|
||||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
|
std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
|
||||||
m_value.binary = nullptr;
|
m_value.binary = nullptr;
|
||||||
@ -6110,6 +5993,20 @@ class basic_json
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @copydoc swap(binary_t)
|
||||||
|
void swap(typename binary_t::container_type& other)
|
||||||
|
{
|
||||||
|
// swap only works for strings
|
||||||
|
if (JSON_HEDLEY_LIKELY(is_binary()))
|
||||||
|
{
|
||||||
|
std::swap(*(m_value.binary), other);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -7065,7 +6962,8 @@ class basic_json
|
|||||||
number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
|
number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
|
||||||
number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
|
number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
|
||||||
number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
|
number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
|
||||||
number_float | *any value* | Double-Precision Float | 0xFB
|
number_float | *any value representable by a float* | Single-Precision Float | 0xFA
|
||||||
|
number_float | *any value NOT representable by a float* | Double-Precision Float | 0xFB
|
||||||
string | *length*: 0..23 | UTF-8 string | 0x60..0x77
|
string | *length*: 0..23 | UTF-8 string | 0x60..0x77
|
||||||
string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
|
string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
|
||||||
string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
|
string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
|
||||||
@ -7107,7 +7005,7 @@ class basic_json
|
|||||||
- expected conversions (0xD5..0xD7)
|
- expected conversions (0xD5..0xD7)
|
||||||
- simple values (0xE0..0xF3, 0xF8)
|
- simple values (0xE0..0xF3, 0xF8)
|
||||||
- undefined (0xF7)
|
- undefined (0xF7)
|
||||||
- half and single-precision floats (0xF9-0xFA)
|
- half-precision floats (0xF9)
|
||||||
- break (0xFF)
|
- break (0xFF)
|
||||||
|
|
||||||
@param[in] j JSON value to serialize
|
@param[in] j JSON value to serialize
|
||||||
@ -7125,7 +7023,8 @@ class basic_json
|
|||||||
@sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
|
@sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
|
||||||
related UBJSON format
|
related UBJSON format
|
||||||
|
|
||||||
@since version 2.0.9
|
@since version 2.0.9; compact representation of floating-point numbers
|
||||||
|
since version 3.8.0
|
||||||
*/
|
*/
|
||||||
static std::vector<uint8_t> to_cbor(const basic_json& j)
|
static std::vector<uint8_t> to_cbor(const basic_json& j)
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -499,7 +499,7 @@ TEST_CASE("BSON")
|
|||||||
const auto s = std::vector<std::uint8_t>(N, 'x');
|
const auto s = std::vector<std::uint8_t>(N, 'x');
|
||||||
json j =
|
json j =
|
||||||
{
|
{
|
||||||
{ "entry", json::binary_array(s) }
|
{ "entry", json::binary(s, 0) }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::uint8_t> expected =
|
std::vector<std::uint8_t> expected =
|
||||||
@ -529,7 +529,7 @@ TEST_CASE("BSON")
|
|||||||
const std::vector<std::uint8_t> md5hash = {0xd7, 0x7e, 0x27, 0x54, 0xbe, 0x12, 0x37, 0xfe, 0xd6, 0x0c, 0x33, 0x98, 0x30, 0x3b, 0x8d, 0xc4};
|
const std::vector<std::uint8_t> md5hash = {0xd7, 0x7e, 0x27, 0x54, 0xbe, 0x12, 0x37, 0xfe, 0xd6, 0x0c, 0x33, 0x98, 0x30, 0x3b, 0x8d, 0xc4};
|
||||||
json j =
|
json j =
|
||||||
{
|
{
|
||||||
{ "entry", json::binary_array(md5hash, 5) }
|
{ "entry", json::binary(md5hash, 5) }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::uint8_t> expected =
|
std::vector<std::uint8_t> expected =
|
||||||
|
|||||||
@ -925,7 +925,7 @@ TEST_CASE("CBOR")
|
|||||||
}
|
}
|
||||||
SECTION("3.40282e+38(max float)")
|
SECTION("3.40282e+38(max float)")
|
||||||
{
|
{
|
||||||
float v = std::numeric_limits<float>::max();
|
float v = (std::numeric_limits<float>::max)();
|
||||||
json j = v;
|
json j = v;
|
||||||
std::vector<uint8_t> expected =
|
std::vector<uint8_t> expected =
|
||||||
{
|
{
|
||||||
@ -939,7 +939,7 @@ TEST_CASE("CBOR")
|
|||||||
}
|
}
|
||||||
SECTION("-3.40282e+38(lowest float)")
|
SECTION("-3.40282e+38(lowest float)")
|
||||||
{
|
{
|
||||||
double v = std::numeric_limits<float>::lowest();
|
double v = static_cast<double>(std::numeric_limits<float>::lowest());
|
||||||
json j = v;
|
json j = v;
|
||||||
std::vector<uint8_t> expected =
|
std::vector<uint8_t> expected =
|
||||||
{
|
{
|
||||||
@ -953,7 +953,7 @@ TEST_CASE("CBOR")
|
|||||||
}
|
}
|
||||||
SECTION("1 + 3.40282e+38(more than max float)")
|
SECTION("1 + 3.40282e+38(more than max float)")
|
||||||
{
|
{
|
||||||
double v = std::numeric_limits<float>::max() + 0.1e+34;
|
double v = static_cast<double>((std::numeric_limits<float>::max)()) + 0.1e+34;
|
||||||
json j = v;
|
json j = v;
|
||||||
std::vector<uint8_t> expected =
|
std::vector<uint8_t> expected =
|
||||||
{
|
{
|
||||||
@ -968,7 +968,7 @@ TEST_CASE("CBOR")
|
|||||||
}
|
}
|
||||||
SECTION("-1 - 3.40282e+38(less than lowest float)")
|
SECTION("-1 - 3.40282e+38(less than lowest float)")
|
||||||
{
|
{
|
||||||
double v = std::numeric_limits<float>::lowest() - 1;
|
double v = static_cast<double>(std::numeric_limits<float>::lowest()) - 1.0;
|
||||||
json j = v;
|
json j = v;
|
||||||
std::vector<uint8_t> expected =
|
std::vector<uint8_t> expected =
|
||||||
{
|
{
|
||||||
@ -1450,7 +1450,7 @@ TEST_CASE("CBOR")
|
|||||||
|
|
||||||
// create JSON value with byte array containing of N * 'x'
|
// create JSON value with byte array containing of N * 'x'
|
||||||
const auto s = std::vector<uint8_t>(N, 'x');
|
const auto s = std::vector<uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> expected;
|
std::vector<uint8_t> expected;
|
||||||
@ -1484,7 +1484,7 @@ TEST_CASE("CBOR")
|
|||||||
|
|
||||||
// create JSON value with string containing of N * 'x'
|
// create JSON value with string containing of N * 'x'
|
||||||
const auto s = std::vector<uint8_t>(N, 'x');
|
const auto s = std::vector<uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> expected;
|
std::vector<uint8_t> expected;
|
||||||
@ -1519,7 +1519,7 @@ TEST_CASE("CBOR")
|
|||||||
|
|
||||||
// create JSON value with string containing of N * 'x'
|
// create JSON value with string containing of N * 'x'
|
||||||
const auto s = std::vector<uint8_t>(N, 'x');
|
const auto s = std::vector<uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
|
|
||||||
// create expected byte vector (hack: create string first)
|
// create expected byte vector (hack: create string first)
|
||||||
std::vector<uint8_t> expected(N, 'x');
|
std::vector<uint8_t> expected(N, 'x');
|
||||||
@ -1552,7 +1552,7 @@ TEST_CASE("CBOR")
|
|||||||
|
|
||||||
// create JSON value with string containing of N * 'x'
|
// create JSON value with string containing of N * 'x'
|
||||||
const auto s = std::vector<uint8_t>(N, 'x');
|
const auto s = std::vector<uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
|
|
||||||
// create expected byte vector (hack: create string first)
|
// create expected byte vector (hack: create string first)
|
||||||
std::vector<uint8_t> expected(N, 'x');
|
std::vector<uint8_t> expected(N, 'x');
|
||||||
@ -1581,8 +1581,8 @@ TEST_CASE("CBOR")
|
|||||||
std::vector<std::uint8_t> input = {0x5F, 0x44, 0xaa, 0xbb, 0xcc, 0xdd, 0x43, 0xee, 0xff, 0x99, 0xFF};
|
std::vector<std::uint8_t> input = {0x5F, 0x44, 0xaa, 0xbb, 0xcc, 0xdd, 0x43, 0xee, 0xff, 0x99, 0xFF};
|
||||||
auto j = json::from_cbor(input);
|
auto j = json::from_cbor(input);
|
||||||
CHECK(j.is_binary());
|
CHECK(j.is_binary());
|
||||||
auto k = json::binary_array({0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x99});
|
auto k = json::binary({0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x99});
|
||||||
CAPTURE(j.dump(0, ' ', false, json::error_handler_t::strict, true));
|
CAPTURE(j.dump(0, ' ', false, json::error_handler_t::strict))
|
||||||
CHECK(j == k);
|
CHECK(j == k);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1633,7 +1633,7 @@ TEST_CASE("CBOR")
|
|||||||
0x00, 0x00, 0x00, 0x01, 0x61
|
0x00, 0x00, 0x00, 0x01, 0x61
|
||||||
};
|
};
|
||||||
json j = json::from_cbor(given);
|
json j = json::from_cbor(given);
|
||||||
CHECK(j == json::binary_array(std::vector<uint8_t> {'a'}));
|
CHECK(j == json::binary(std::vector<uint8_t> {'a'}));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("0x7b (string)")
|
SECTION("0x7b (string)")
|
||||||
@ -2502,7 +2502,7 @@ TEST_CASE("examples from RFC 7049 Appendix A")
|
|||||||
std::ifstream f_bin(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.out", std::ios::binary);
|
std::ifstream f_bin(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.out", std::ios::binary);
|
||||||
std::vector<uint8_t> expected((std::istreambuf_iterator<char>(f_bin)),
|
std::vector<uint8_t> expected((std::istreambuf_iterator<char>(f_bin)),
|
||||||
std::istreambuf_iterator<char>());
|
std::istreambuf_iterator<char>());
|
||||||
CHECK(j == json::binary_array(expected));
|
CHECK(j == json::binary(expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("arrays")
|
SECTION("arrays")
|
||||||
|
|||||||
@ -77,7 +77,7 @@ class SaxEventLogger
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool binary(std::vector<std::uint8_t>& val)
|
bool binary(json::binary_t& val)
|
||||||
{
|
{
|
||||||
std::string binary_contents = "binary(";
|
std::string binary_contents = "binary(";
|
||||||
std::string comma_space = "";
|
std::string comma_space = "";
|
||||||
@ -183,7 +183,7 @@ class SaxCountdown : public nlohmann::json::json_sax_t
|
|||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool binary(std::vector<std::uint8_t>&) override
|
bool binary(json::binary_t&) override
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,7 +101,7 @@ TEST_CASE("lexicographical comparison operators")
|
|||||||
true, false,
|
true, false,
|
||||||
{1, 2, 3}, {"one", "two", "three"},
|
{1, 2, 3}, {"one", "two", "three"},
|
||||||
{{"first", 1}, {"second", 2}}, {{"a", "A"}, {"b", {"B"}}},
|
{{"first", 1}, {"second", 2}}, {{"a", "A"}, {"b", {"B"}}},
|
||||||
json::binary_array({1, 2, 3}), json::binary_array({1, 2, 4})
|
json::binary({1, 2, 3}), json::binary({1, 2, 4})
|
||||||
};
|
};
|
||||||
|
|
||||||
SECTION("comparison: equal")
|
SECTION("comparison: equal")
|
||||||
|
|||||||
@ -121,7 +121,7 @@ TEST_CASE("constructors")
|
|||||||
auto t = json::value_t::binary;
|
auto t = json::value_t::binary;
|
||||||
json j(t);
|
json j(t);
|
||||||
CHECK(j.type() == t);
|
CHECK(j.type() == t);
|
||||||
CHECK(j == json::binary_array({}));
|
CHECK(j == json::binary({}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,6 +481,23 @@ TEST_CASE("constructors")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("create a binary (explicit)")
|
||||||
|
{
|
||||||
|
SECTION("empty binary")
|
||||||
|
{
|
||||||
|
json::binary_t b{};
|
||||||
|
json j(b);
|
||||||
|
CHECK(j.type() == json::value_t::binary);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("filled binary")
|
||||||
|
{
|
||||||
|
json::binary_t b({1, 2, 3});
|
||||||
|
json j(b);
|
||||||
|
CHECK(j.type() == json::value_t::binary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("create an integer number (explicit)")
|
SECTION("create an integer number (explicit)")
|
||||||
{
|
{
|
||||||
SECTION("uninitialized value")
|
SECTION("uninitialized value")
|
||||||
@ -1465,12 +1482,12 @@ TEST_CASE("constructors")
|
|||||||
SECTION("binary")
|
SECTION("binary")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
json j = json::binary_array({1, 2, 3});
|
json j = json::binary({1, 2, 3});
|
||||||
json j_new(j.begin(), j.end());
|
json j_new(j.begin(), j.end());
|
||||||
CHECK((j == j_new));
|
CHECK((j == j_new));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json j = json::binary_array({1, 2, 3});
|
json j = json::binary({1, 2, 3});
|
||||||
json j_new(j.cbegin(), j.cend());
|
json j_new(j.cbegin(), j.cend());
|
||||||
CHECK((j == j_new));
|
CHECK((j == j_new));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,7 +94,7 @@ TEST_CASE("other constructors and destructor")
|
|||||||
|
|
||||||
SECTION("binary")
|
SECTION("binary")
|
||||||
{
|
{
|
||||||
json j = json::binary_array({1, 2, 3});
|
json j = json::binary({1, 2, 3});
|
||||||
json k(j);
|
json k(j);
|
||||||
CHECK(j == k);
|
CHECK(j == k);
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@ TEST_CASE("other constructors and destructor")
|
|||||||
|
|
||||||
SECTION("binary")
|
SECTION("binary")
|
||||||
{
|
{
|
||||||
json j = json::binary_array({1, 2, 3});
|
json j = json::binary({1, 2, 3});
|
||||||
json k;
|
json k;
|
||||||
k = j;
|
k = j;
|
||||||
CHECK(j == k);
|
CHECK(j == k);
|
||||||
|
|||||||
@ -1266,6 +1266,124 @@ TEST_CASE("value conversion")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("get a binary value (explicit)")
|
||||||
|
{
|
||||||
|
json::binary_t n_reference{{1, 2, 3}};
|
||||||
|
json j(n_reference);
|
||||||
|
|
||||||
|
SECTION("binary_t")
|
||||||
|
{
|
||||||
|
json::binary_t b = j.get<json::binary_t>();
|
||||||
|
CHECK(*json(b).m_value.binary == *j.m_value.binary);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("get_binary()")
|
||||||
|
{
|
||||||
|
SECTION("non-const")
|
||||||
|
{
|
||||||
|
auto& b = j.get_binary();
|
||||||
|
CHECK(*json(b).m_value.binary == *j.m_value.binary);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("non-const")
|
||||||
|
{
|
||||||
|
const json j_const = j;
|
||||||
|
const auto& b = j_const.get_binary();
|
||||||
|
CHECK(*json(b).m_value.binary == *j.m_value.binary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("exception in case of a non-string type")
|
||||||
|
{
|
||||||
|
json j_null(json::value_t::null);
|
||||||
|
json j_object(json::value_t::object);
|
||||||
|
json j_array(json::value_t::array);
|
||||||
|
json j_string(json::value_t::string);
|
||||||
|
json j_boolean(json::value_t::boolean);
|
||||||
|
const json j_null_const(json::value_t::null);
|
||||||
|
const json j_object_const(json::value_t::object);
|
||||||
|
const json j_array_const(json::value_t::array);
|
||||||
|
const json j_string_const(json::value_t::string);
|
||||||
|
const json j_boolean_const(json::value_t::boolean);
|
||||||
|
|
||||||
|
CHECK_THROWS_WITH_AS(j_null.get<json::binary_t>(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is null",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_object.get<json::binary_t>(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is object",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_array.get<json::binary_t>(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is array",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_string.get<json::binary_t>(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is string",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_boolean.get<json::binary_t>(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is boolean",
|
||||||
|
json::type_error&);
|
||||||
|
|
||||||
|
CHECK_THROWS_WITH_AS(j_null_const.get<json::binary_t>(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is null",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_object_const.get<json::binary_t>(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is object",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_array_const.get<json::binary_t>(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is array",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_string_const.get<json::binary_t>(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is string",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_boolean_const.get<json::binary_t>(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is boolean",
|
||||||
|
json::type_error&);
|
||||||
|
|
||||||
|
CHECK_THROWS_WITH_AS(j_null.get_binary(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is null",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_object.get_binary(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is object",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_array.get_binary(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is array",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_string.get_binary(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is string",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_boolean.get_binary(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is boolean",
|
||||||
|
json::type_error&);
|
||||||
|
|
||||||
|
CHECK_THROWS_WITH_AS(j_null_const.get_binary(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is null",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_object_const.get_binary(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is object",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_array_const.get_binary(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is array",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_string_const.get_binary(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is string",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_boolean_const.get_binary(),
|
||||||
|
"[json.exception.type_error.302] type must be binary, but is boolean",
|
||||||
|
json::type_error&);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("get a binary value (implicit)")
|
||||||
|
{
|
||||||
|
json::binary_t n_reference{{1, 2, 3}};
|
||||||
|
json j(n_reference);
|
||||||
|
|
||||||
|
SECTION("binary_t")
|
||||||
|
{
|
||||||
|
json::binary_t b = j;
|
||||||
|
CHECK(*json(b).m_value.binary == *j.m_value.binary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("get an enum")
|
SECTION("get an enum")
|
||||||
{
|
{
|
||||||
enum c_enum { value_1, value_2 };
|
enum c_enum { value_1, value_2 };
|
||||||
|
|||||||
@ -76,7 +76,7 @@ struct SaxEventLogger : public nlohmann::json_sax<json>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool binary(std::vector<std::uint8_t>& val) override
|
bool binary(json::binary_t& val) override
|
||||||
{
|
{
|
||||||
std::string binary_contents = "binary(";
|
std::string binary_contents = "binary(";
|
||||||
std::string comma_space = "";
|
std::string comma_space = "";
|
||||||
|
|||||||
@ -698,13 +698,13 @@ TEST_CASE("element access 1")
|
|||||||
SECTION("binary")
|
SECTION("binary")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
json j = json::binary_array({1, 2, 3});
|
json j = json::binary({1, 2, 3});
|
||||||
json::iterator it = j.erase(j.begin());
|
json::iterator it = j.erase(j.begin());
|
||||||
CHECK(j.type() == json::value_t::null);
|
CHECK(j.type() == json::value_t::null);
|
||||||
CHECK(it == j.end());
|
CHECK(it == j.end());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json j = json::binary_array({1, 2, 3});
|
json j = json::binary({1, 2, 3});
|
||||||
json::const_iterator it = j.erase(j.cbegin());
|
json::const_iterator it = j.erase(j.cbegin());
|
||||||
CHECK(j.type() == json::value_t::null);
|
CHECK(j.type() == json::value_t::null);
|
||||||
CHECK(it == j.end());
|
CHECK(it == j.end());
|
||||||
@ -896,13 +896,13 @@ TEST_CASE("element access 1")
|
|||||||
SECTION("binary")
|
SECTION("binary")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
json j = json::binary_array({1, 2, 3});
|
json j = json::binary({1, 2, 3});
|
||||||
json::iterator it = j.erase(j.begin(), j.end());
|
json::iterator it = j.erase(j.begin(), j.end());
|
||||||
CHECK(j.type() == json::value_t::null);
|
CHECK(j.type() == json::value_t::null);
|
||||||
CHECK(it == j.end());
|
CHECK(it == j.end());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json j = json::binary_array({1, 2, 3});
|
json j = json::binary({1, 2, 3});
|
||||||
json::const_iterator it = j.erase(j.cbegin(), j.cend());
|
json::const_iterator it = j.erase(j.cbegin(), j.cend());
|
||||||
CHECK(j.type() == json::value_t::null);
|
CHECK(j.type() == json::value_t::null);
|
||||||
CHECK(it == j.end());
|
CHECK(it == j.end());
|
||||||
|
|||||||
@ -261,6 +261,9 @@ TEST_CASE("object inspection")
|
|||||||
// important test, because it yields a resize of the indent_string
|
// important test, because it yields a resize of the indent_string
|
||||||
// inside the dump() function
|
// inside the dump() function
|
||||||
CHECK(j.dump(1024).size() == 15472);
|
CHECK(j.dump(1024).size() == 15472);
|
||||||
|
|
||||||
|
const auto binary = json::binary({1, 2, 3}, 128);
|
||||||
|
CHECK(binary.dump(1024).size() == 2086);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("dump and floating-point numbers")
|
SECTION("dump and floating-point numbers")
|
||||||
@ -469,7 +472,7 @@ TEST_CASE("object inspection")
|
|||||||
|
|
||||||
SECTION("binary")
|
SECTION("binary")
|
||||||
{
|
{
|
||||||
json j = json::binary_array({});
|
json j = json::binary({});
|
||||||
json::value_t t = j;
|
json::value_t t = j;
|
||||||
CHECK(t == j.type());
|
CHECK(t == j.type());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -110,7 +110,7 @@ TEST_CASE("modifiers")
|
|||||||
{
|
{
|
||||||
SECTION("empty binary")
|
SECTION("empty binary")
|
||||||
{
|
{
|
||||||
json j = json::binary_array({});
|
json j = json::binary({});
|
||||||
json k = j;
|
json k = j;
|
||||||
|
|
||||||
j.clear();
|
j.clear();
|
||||||
@ -121,7 +121,7 @@ TEST_CASE("modifiers")
|
|||||||
|
|
||||||
SECTION("filled binary")
|
SECTION("filled binary")
|
||||||
{
|
{
|
||||||
json j = json::binary_array({1, 2, 3, 4, 5});
|
json j = json::binary({1, 2, 3, 4, 5});
|
||||||
json k = j;
|
json k = j;
|
||||||
|
|
||||||
j.clear();
|
j.clear();
|
||||||
@ -967,25 +967,40 @@ TEST_CASE("modifiers")
|
|||||||
{
|
{
|
||||||
SECTION("binary_t type")
|
SECTION("binary_t type")
|
||||||
{
|
{
|
||||||
json j = json::binary_array({1, 2, 3, 4});
|
json j = json::binary({1, 2, 3, 4});
|
||||||
json::binary_t s = {1, 2, 3, 4};
|
json::binary_t s = {{5, 6, 7, 8}};
|
||||||
|
|
||||||
j.swap(s);
|
j.swap(s);
|
||||||
|
|
||||||
CHECK(j == json::binary_array({1, 2, 3, 4}));
|
CHECK(j == json::binary({5, 6, 7, 8}));
|
||||||
|
|
||||||
j.swap(s);
|
j.swap(s);
|
||||||
|
|
||||||
CHECK(j == json::binary_array({1, 2, 3, 4}));
|
CHECK(j == json::binary({1, 2, 3, 4}));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("non-string_t type")
|
SECTION("binary_t::container_type type")
|
||||||
|
{
|
||||||
|
json j = json::binary({1, 2, 3, 4});
|
||||||
|
std::vector<std::uint8_t> s = {{5, 6, 7, 8}};
|
||||||
|
|
||||||
|
j.swap(s);
|
||||||
|
|
||||||
|
CHECK(j == json::binary({5, 6, 7, 8}));
|
||||||
|
|
||||||
|
j.swap(s);
|
||||||
|
|
||||||
|
CHECK(j == json::binary({1, 2, 3, 4}));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("non-binary_t type")
|
||||||
{
|
{
|
||||||
json j = 17;
|
json j = 17;
|
||||||
json::binary_t s = {1, 2, 3, 4};
|
json::binary_t s1 = {{1, 2, 3, 4}};
|
||||||
|
std::vector<std::uint8_t> s2 = {{5, 6, 7, 8}};
|
||||||
|
|
||||||
CHECK_THROWS_AS(j.swap(s), json::type_error&);
|
CHECK_THROWS_WITH_AS(j.swap(s1), "[json.exception.type_error.310] cannot use swap() with number", json::type_error);
|
||||||
CHECK_THROWS_WITH(j.swap(s), "[json.exception.type_error.310] cannot use swap() with number");
|
CHECK_THROWS_WITH_AS(j.swap(s2), "[json.exception.type_error.310] cannot use swap() with number", json::type_error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1132,9 +1132,9 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
// create JSON value with byte array containing of N * 'x'
|
// create JSON value with byte array containing of N * 'x'
|
||||||
const auto s = std::vector<uint8_t>(N, 'x');
|
const auto s = std::vector<uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
std::uint8_t subtype = 42;
|
std::uint8_t subtype = 42;
|
||||||
j.set_subtype(subtype);
|
j.get_binary().set_subtype(subtype);
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> expected;
|
std::vector<uint8_t> expected;
|
||||||
@ -1207,9 +1207,9 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
// create JSON value with string containing of N * 'x'
|
// create JSON value with string containing of N * 'x'
|
||||||
const auto s = std::vector<uint8_t>(N, 'x');
|
const auto s = std::vector<uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
std::uint8_t subtype = 42;
|
std::uint8_t subtype = 42;
|
||||||
j.set_subtype(subtype);
|
j.get_binary().set_subtype(subtype);
|
||||||
|
|
||||||
// create expected byte vector (hack: create string first)
|
// create expected byte vector (hack: create string first)
|
||||||
std::vector<uint8_t> expected(N, 'x');
|
std::vector<uint8_t> expected(N, 'x');
|
||||||
@ -1243,9 +1243,9 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
// create JSON value with string containing of N * 'x'
|
// create JSON value with string containing of N * 'x'
|
||||||
const auto s = std::vector<uint8_t>(N, 'x');
|
const auto s = std::vector<uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
std::uint8_t subtype = 42;
|
std::uint8_t subtype = 42;
|
||||||
j.set_subtype(subtype);
|
j.get_binary().set_subtype(subtype);
|
||||||
|
|
||||||
// create expected byte vector (hack: create string first)
|
// create expected byte vector (hack: create string first)
|
||||||
std::vector<uint8_t> expected(N, 'x');
|
std::vector<uint8_t> expected(N, 'x');
|
||||||
@ -1281,7 +1281,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
// create JSON value with byte array containing of N * 'x'
|
// create JSON value with byte array containing of N * 'x'
|
||||||
const auto s = std::vector<uint8_t>(N, 'x');
|
const auto s = std::vector<uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<std::uint8_t> expected;
|
std::vector<std::uint8_t> expected;
|
||||||
@ -1319,7 +1319,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
// create JSON value with string containing of N * 'x'
|
// create JSON value with string containing of N * 'x'
|
||||||
const auto s = std::vector<std::uint8_t>(N, 'x');
|
const auto s = std::vector<std::uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
|
|
||||||
// create expected byte vector (hack: create string first)
|
// create expected byte vector (hack: create string first)
|
||||||
std::vector<std::uint8_t> expected(N, 'x');
|
std::vector<std::uint8_t> expected(N, 'x');
|
||||||
@ -1352,7 +1352,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
// create JSON value with string containing of N * 'x'
|
// create JSON value with string containing of N * 'x'
|
||||||
const auto s = std::vector<std::uint8_t>(N, 'x');
|
const auto s = std::vector<std::uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
|
|
||||||
// create expected byte vector (hack: create string first)
|
// create expected byte vector (hack: create string first)
|
||||||
std::vector<uint8_t> expected(N, 'x');
|
std::vector<uint8_t> expected(N, 'x');
|
||||||
|
|||||||
@ -46,7 +46,12 @@ void to_json(json&, pod) noexcept;
|
|||||||
void to_json(json&, pod_bis);
|
void to_json(json&, pod_bis);
|
||||||
void from_json(const json&, pod) noexcept;
|
void from_json(const json&, pod) noexcept;
|
||||||
void from_json(const json&, pod_bis);
|
void from_json(const json&, pod_bis);
|
||||||
static json* j;
|
void to_json(json&, pod) noexcept {}
|
||||||
|
void to_json(json&, pod_bis) {}
|
||||||
|
void from_json(const json&, pod) noexcept {}
|
||||||
|
void from_json(const json&, pod_bis) {}
|
||||||
|
|
||||||
|
static json* j = nullptr;
|
||||||
|
|
||||||
static_assert(noexcept(json{}), "");
|
static_assert(noexcept(json{}), "");
|
||||||
static_assert(noexcept(nlohmann::to_json(*j, 2)), "");
|
static_assert(noexcept(nlohmann::to_json(*j, 2)), "");
|
||||||
@ -79,4 +84,14 @@ TEST_CASE("runtime checks")
|
|||||||
CHECK(std::is_nothrow_copy_constructible<json::out_of_range>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);
|
CHECK(std::is_nothrow_copy_constructible<json::out_of_range>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);
|
||||||
CHECK(std::is_nothrow_copy_constructible<json::other_error>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);
|
CHECK(std::is_nothrow_copy_constructible<json::other_error>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("silence -Wunneeded-internal-declaration errors")
|
||||||
|
{
|
||||||
|
j = nullptr;
|
||||||
|
json j2;
|
||||||
|
to_json(j2, pod());
|
||||||
|
to_json(j2, pod_bis());
|
||||||
|
from_json(j2, pod());
|
||||||
|
from_json(j2, pod_bis());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,7 +61,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to const object_t")
|
SECTION("pointer access to const object_t")
|
||||||
@ -91,7 +90,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to array_t")
|
SECTION("pointer access to array_t")
|
||||||
@ -121,7 +119,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to const array_t")
|
SECTION("pointer access to const array_t")
|
||||||
@ -151,7 +148,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to string_t")
|
SECTION("pointer access to string_t")
|
||||||
@ -181,7 +177,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to const string_t")
|
SECTION("pointer access to const string_t")
|
||||||
@ -211,7 +206,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to boolean_t")
|
SECTION("pointer access to boolean_t")
|
||||||
@ -241,7 +235,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to const boolean_t")
|
SECTION("pointer access to const boolean_t")
|
||||||
@ -271,8 +264,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
|
||||||
CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to number_integer_t")
|
SECTION("pointer access to number_integer_t")
|
||||||
@ -302,7 +293,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to const number_integer_t")
|
SECTION("pointer access to const number_integer_t")
|
||||||
@ -332,7 +322,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to number_unsigned_t")
|
SECTION("pointer access to number_unsigned_t")
|
||||||
@ -362,7 +351,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<json::number_unsigned_t*>() != nullptr);
|
CHECK(value.get_ptr<json::number_unsigned_t*>() != nullptr);
|
||||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to const number_unsigned_t")
|
SECTION("pointer access to const number_unsigned_t")
|
||||||
@ -392,7 +380,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() != nullptr);
|
CHECK(value.get_ptr<const json::number_unsigned_t*>() != nullptr);
|
||||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to number_float_t")
|
SECTION("pointer access to number_float_t")
|
||||||
@ -422,7 +409,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::number_float_t*>() != nullptr);
|
CHECK(value.get_ptr<json::number_float_t*>() != nullptr);
|
||||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("pointer access to const number_float_t")
|
SECTION("pointer access to const number_float_t")
|
||||||
@ -457,20 +443,20 @@ TEST_CASE("pointer access")
|
|||||||
SECTION("pointer access to const binary_t")
|
SECTION("pointer access to const binary_t")
|
||||||
{
|
{
|
||||||
using test_type = const json::binary_t;
|
using test_type = const json::binary_t;
|
||||||
const json value = json::binary_array({});
|
const json value = json::binary({1, 2, 3});
|
||||||
|
|
||||||
// check if pointers are returned correctly
|
// check if pointers are returned correctly
|
||||||
test_type* p1 = value.get_ptr<test_type*>();
|
test_type* p1 = value.get_ptr<test_type*>();
|
||||||
CHECK(p1 == value.get_ptr<test_type*>());
|
CHECK(p1 == value.get_ptr<test_type*>());
|
||||||
//CHECK(*p1 == value.get<test_type>());
|
CHECK(*p1 == value.get<test_type>());
|
||||||
|
|
||||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||||
//CHECK(*p2 == value.get<test_type>());
|
CHECK(*p2 == value.get<test_type>());
|
||||||
|
|
||||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||||
//CHECK(*p3 == value.get<test_type>());
|
CHECK(*p3 == value.get<test_type>());
|
||||||
|
|
||||||
// check if null pointers are returned correctly
|
// check if null pointers are returned correctly
|
||||||
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
|
||||||
@ -485,21 +471,21 @@ TEST_CASE("pointer access")
|
|||||||
|
|
||||||
SECTION("pointer access to const binary_t")
|
SECTION("pointer access to const binary_t")
|
||||||
{
|
{
|
||||||
using test_type = const json::internal_binary_t;
|
using test_type = const json::binary_t;
|
||||||
const json value = json::binary_array({});
|
const json value = json::binary({});
|
||||||
|
|
||||||
// check if pointers are returned correctly
|
// check if pointers are returned correctly
|
||||||
test_type* p1 = value.get_ptr<test_type*>();
|
test_type* p1 = value.get_ptr<test_type*>();
|
||||||
CHECK(p1 == value.get_ptr<test_type*>());
|
CHECK(p1 == value.get_ptr<test_type*>());
|
||||||
//CHECK(*p1 == value.get<test_type>());
|
CHECK(*p1 == value.get<test_type>());
|
||||||
|
|
||||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||||
//CHECK(*p2 == value.get<test_type>());
|
CHECK(*p2 == value.get<test_type>());
|
||||||
|
|
||||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||||
//CHECK(*p3 == value.get<test_type>());
|
CHECK(*p3 == value.get<test_type>());
|
||||||
|
|
||||||
// check if null pointers are returned correctly
|
// check if null pointers are returned correctly
|
||||||
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
|
||||||
@ -509,6 +495,6 @@ TEST_CASE("pointer access")
|
|||||||
CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||||
CHECK(value.get_ptr<const json::internal_binary_t*>() != nullptr);
|
CHECK(value.get_ptr<const json::binary_t*>() != nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1919,8 +1919,7 @@ TEST_CASE("regression tests")
|
|||||||
j.dump(4, // Indent
|
j.dump(4, // Indent
|
||||||
' ', // Indent char
|
' ', // Indent char
|
||||||
false, // Ensure ascii
|
false, // Ensure ascii
|
||||||
json::error_handler_t::strict, // Error
|
json::error_handler_t::strict // Error
|
||||||
true // Allow binary data
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -209,52 +209,114 @@ TEST_CASE_TEMPLATE("serialization for extreme integer values", T, int32_t, uint3
|
|||||||
|
|
||||||
TEST_CASE("dump with binary values")
|
TEST_CASE("dump with binary values")
|
||||||
{
|
{
|
||||||
SECTION("serialize_binary = false")
|
auto binary = json::binary({1, 2, 3, 4});
|
||||||
{
|
auto binary_empty = json::binary({});
|
||||||
auto binary = json::binary_array({1, 2, 3, 4});
|
auto binary_with_subtype = json::binary({1, 2, 3, 4}, 128);
|
||||||
auto binary_empty = json::binary_array({});
|
auto binary_empty_with_subtype = json::binary({}, 128);
|
||||||
json object = {{"key", binary}};
|
|
||||||
json array = {"value", 1, binary};
|
|
||||||
|
|
||||||
CHECK_THROWS_AS(binary.dump(), json::type_error);
|
json object = {{"key", binary}};
|
||||||
CHECK_THROWS_AS(binary_empty.dump(), json::type_error);
|
json object_empty = {{"key", binary_empty}};
|
||||||
CHECK_THROWS_AS(object.dump(), json::type_error);
|
json object_with_subtype = {{"key", binary_with_subtype}};
|
||||||
CHECK_THROWS_AS(array.dump(), json::type_error);
|
json object_empty_with_subtype = {{"key", binary_empty_with_subtype}};
|
||||||
CHECK_THROWS_WITH(binary.dump(), "[json.exception.type_error.317] cannot serialize binary data to text JSON");
|
|
||||||
CHECK_THROWS_WITH(binary_empty.dump(), "[json.exception.type_error.317] cannot serialize binary data to text JSON");
|
json array = {"value", 1, binary};
|
||||||
CHECK_THROWS_WITH(object.dump(), "[json.exception.type_error.317] cannot serialize binary data to text JSON");
|
json array_empty = {"value", 1, binary_empty};
|
||||||
CHECK_THROWS_WITH(array.dump(), "[json.exception.type_error.317] cannot serialize binary data to text JSON");
|
json array_with_subtype = {"value", 1, binary_with_subtype};
|
||||||
|
json array_empty_with_subtype = {"value", 1, binary_empty_with_subtype};
|
||||||
|
|
||||||
|
SECTION("normal")
|
||||||
|
{
|
||||||
|
CHECK(binary.dump() == "{\"bytes\":[1,2,3,4],\"subtype\":null}");
|
||||||
|
CHECK(binary_empty.dump() == "{\"bytes\":[],\"subtype\":null}");
|
||||||
|
CHECK(binary_with_subtype.dump() == "{\"bytes\":[1,2,3,4],\"subtype\":128}");
|
||||||
|
CHECK(binary_empty_with_subtype.dump() == "{\"bytes\":[],\"subtype\":128}");
|
||||||
|
|
||||||
|
CHECK(object.dump() == "{\"key\":{\"bytes\":[1,2,3,4],\"subtype\":null}}");
|
||||||
|
CHECK(object_empty.dump() == "{\"key\":{\"bytes\":[],\"subtype\":null}}");
|
||||||
|
CHECK(object_with_subtype.dump() == "{\"key\":{\"bytes\":[1,2,3,4],\"subtype\":128}}");
|
||||||
|
CHECK(object_empty_with_subtype.dump() == "{\"key\":{\"bytes\":[],\"subtype\":128}}");
|
||||||
|
|
||||||
|
CHECK(array.dump() == "[\"value\",1,{\"bytes\":[1,2,3,4],\"subtype\":null}]");
|
||||||
|
CHECK(array_empty.dump() == "[\"value\",1,{\"bytes\":[],\"subtype\":null}]");
|
||||||
|
CHECK(array_with_subtype.dump() == "[\"value\",1,{\"bytes\":[1,2,3,4],\"subtype\":128}]");
|
||||||
|
CHECK(array_empty_with_subtype.dump() == "[\"value\",1,{\"bytes\":[],\"subtype\":128}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("serialize_binary = true")
|
SECTION("pretty-printed")
|
||||||
{
|
{
|
||||||
auto binary = json::binary_array({1, 2, 3, 4});
|
CHECK(binary.dump(4) == "{\n"
|
||||||
auto binary_empty = json::binary_array({});
|
" \"bytes\": [1, 2, 3, 4],\n"
|
||||||
json object = {{"key", binary}};
|
" \"subtype\": null\n"
|
||||||
json array = {"value", 1, binary};
|
|
||||||
|
|
||||||
CHECK(binary.dump(-1, ' ', false, json::error_handler_t::strict, true) == "b[1,2,3,4]");
|
|
||||||
CHECK(binary_empty.dump(-1, ' ', false, json::error_handler_t::strict, true) == "b[]");
|
|
||||||
CHECK(object.dump(-1, ' ', false, json::error_handler_t::strict, true) == "{\"key\":b[1,2,3,4]}");
|
|
||||||
CHECK(array.dump(-1, ' ', false, json::error_handler_t::strict, true) == "[\"value\",1,b[1,2,3,4]]");
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("serialize_binary = true, pretty-printed")
|
|
||||||
{
|
|
||||||
auto binary = json::binary_array({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20});
|
|
||||||
auto binary_empty = json::binary_array({});
|
|
||||||
json object = {{"key", binary}};
|
|
||||||
json array = {"value", 1, binary};
|
|
||||||
|
|
||||||
CHECK(binary.dump(4, ' ', false, json::error_handler_t::strict, true) == "b[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]");
|
|
||||||
CHECK(binary_empty.dump(4, ' ', false, json::error_handler_t::strict, true) == "b[]");
|
|
||||||
CHECK(object.dump(4, ' ', false, json::error_handler_t::strict, true) == "{\n"
|
|
||||||
" \"key\": b[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]\n"
|
|
||||||
"}");
|
"}");
|
||||||
CHECK(array.dump(4, ' ', false, json::error_handler_t::strict, true) == "[\n"
|
CHECK(binary_empty.dump(4) == "{\n"
|
||||||
|
" \"bytes\": [],\n"
|
||||||
|
" \"subtype\": null\n"
|
||||||
|
"}");
|
||||||
|
CHECK(binary_with_subtype.dump(4) == "{\n"
|
||||||
|
" \"bytes\": [1, 2, 3, 4],\n"
|
||||||
|
" \"subtype\": 128\n"
|
||||||
|
"}");
|
||||||
|
CHECK(binary_empty_with_subtype.dump(4) == "{\n"
|
||||||
|
" \"bytes\": [],\n"
|
||||||
|
" \"subtype\": 128\n"
|
||||||
|
"}");
|
||||||
|
|
||||||
|
CHECK(object.dump(4) == "{\n"
|
||||||
|
" \"key\": {\n"
|
||||||
|
" \"bytes\": [1, 2, 3, 4],\n"
|
||||||
|
" \"subtype\": null\n"
|
||||||
|
" }\n"
|
||||||
|
"}");
|
||||||
|
CHECK(object_empty.dump(4) == "{\n"
|
||||||
|
" \"key\": {\n"
|
||||||
|
" \"bytes\": [],\n"
|
||||||
|
" \"subtype\": null\n"
|
||||||
|
" }\n"
|
||||||
|
"}");
|
||||||
|
CHECK(object_with_subtype.dump(4) == "{\n"
|
||||||
|
" \"key\": {\n"
|
||||||
|
" \"bytes\": [1, 2, 3, 4],\n"
|
||||||
|
" \"subtype\": 128\n"
|
||||||
|
" }\n"
|
||||||
|
"}");
|
||||||
|
CHECK(object_empty_with_subtype.dump(4) == "{\n"
|
||||||
|
" \"key\": {\n"
|
||||||
|
" \"bytes\": [],\n"
|
||||||
|
" \"subtype\": 128\n"
|
||||||
|
" }\n"
|
||||||
|
"}");
|
||||||
|
|
||||||
|
CHECK(array.dump(4) == "[\n"
|
||||||
" \"value\",\n"
|
" \"value\",\n"
|
||||||
" 1,\n"
|
" 1,\n"
|
||||||
" b[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]\n"
|
" {\n"
|
||||||
|
" \"bytes\": [1, 2, 3, 4],\n"
|
||||||
|
" \"subtype\": null\n"
|
||||||
|
" }\n"
|
||||||
|
"]");
|
||||||
|
CHECK(array_empty.dump(4) == "[\n"
|
||||||
|
" \"value\",\n"
|
||||||
|
" 1,\n"
|
||||||
|
" {\n"
|
||||||
|
" \"bytes\": [],\n"
|
||||||
|
" \"subtype\": null\n"
|
||||||
|
" }\n"
|
||||||
|
"]");
|
||||||
|
CHECK(array_with_subtype.dump(4) == "[\n"
|
||||||
|
" \"value\",\n"
|
||||||
|
" 1,\n"
|
||||||
|
" {\n"
|
||||||
|
" \"bytes\": [1, 2, 3, 4],\n"
|
||||||
|
" \"subtype\": 128\n"
|
||||||
|
" }\n"
|
||||||
|
"]");
|
||||||
|
CHECK(array_empty_with_subtype.dump(4) == "[\n"
|
||||||
|
" \"value\",\n"
|
||||||
|
" 1,\n"
|
||||||
|
" {\n"
|
||||||
|
" \"bytes\": [],\n"
|
||||||
|
" \"subtype\": 128\n"
|
||||||
|
" }\n"
|
||||||
"]");
|
"]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -921,7 +921,7 @@ TEST_CASE("UBJSON")
|
|||||||
|
|
||||||
// create JSON value with byte array containing of N * 'x'
|
// create JSON value with byte array containing of N * 'x'
|
||||||
const auto s = std::vector<std::uint8_t>(N, 'x');
|
const auto s = std::vector<std::uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<std::uint8_t> expected;
|
std::vector<std::uint8_t> expected;
|
||||||
@ -972,7 +972,7 @@ TEST_CASE("UBJSON")
|
|||||||
|
|
||||||
// create JSON value with byte array containing of N * 'x'
|
// create JSON value with byte array containing of N * 'x'
|
||||||
const auto s = std::vector<std::uint8_t>(N, 'x');
|
const auto s = std::vector<std::uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> expected;
|
std::vector<uint8_t> expected;
|
||||||
@ -1012,7 +1012,7 @@ TEST_CASE("UBJSON")
|
|||||||
|
|
||||||
// create JSON value with byte array containing of N * 'x'
|
// create JSON value with byte array containing of N * 'x'
|
||||||
const auto s = std::vector<std::uint8_t>(N, 'x');
|
const auto s = std::vector<std::uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<std::uint8_t> expected(N + 7, 'x');
|
std::vector<std::uint8_t> expected(N + 7, 'x');
|
||||||
@ -1049,7 +1049,7 @@ TEST_CASE("UBJSON")
|
|||||||
|
|
||||||
// create JSON value with byte array containing of N * 'x'
|
// create JSON value with byte array containing of N * 'x'
|
||||||
const auto s = std::vector<std::uint8_t>(N, 'x');
|
const auto s = std::vector<std::uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<std::uint8_t> expected(N + 9, 'x');
|
std::vector<std::uint8_t> expected(N + 9, 'x');
|
||||||
@ -1081,7 +1081,7 @@ TEST_CASE("UBJSON")
|
|||||||
{
|
{
|
||||||
const std::size_t N = 10;
|
const std::size_t N = 10;
|
||||||
const auto s = std::vector<std::uint8_t>(N, 'x');
|
const auto s = std::vector<std::uint8_t>(N, 'x');
|
||||||
json j = json::binary_array(s);
|
json j = json::binary(s);
|
||||||
|
|
||||||
SECTION("No Count No Type")
|
SECTION("No Count No Type")
|
||||||
{
|
{
|
||||||
|
|||||||
@ -120,6 +120,8 @@ static void to_json(BasicJsonType& j, country c)
|
|||||||
case country::russia:
|
case country::russia:
|
||||||
j = u8"Российская Федерация";
|
j = u8"Российская Федерация";
|
||||||
return;
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,6 +763,16 @@ TEST_CASE("different basic_json types conversions")
|
|||||||
CHECK(cj == "forty-two");
|
CHECK(cj == "forty-two");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("binary")
|
||||||
|
{
|
||||||
|
json j = json::binary({1, 2, 3}, 42);
|
||||||
|
custom_json cj = j;
|
||||||
|
CHECK(cj.get_binary().subtype() == 42);
|
||||||
|
std::vector<std::uint8_t> cv = cj.get_binary();
|
||||||
|
std::vector<std::uint8_t> v = j.get_binary();
|
||||||
|
CHECK(cv == v);
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("object")
|
SECTION("object")
|
||||||
{
|
{
|
||||||
json j = {{"forty", "two"}};
|
json j = {{"forty", "two"}};
|
||||||
@ -803,7 +815,9 @@ class Evil
|
|||||||
public:
|
public:
|
||||||
Evil() = default;
|
Evil() = default;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Evil(T) {}
|
Evil(T t) : m_i(sizeof(t)) {}
|
||||||
|
|
||||||
|
int m_i = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void from_json(const json&, Evil&) {}
|
void from_json(const json&, Evil&) {}
|
||||||
@ -816,6 +830,10 @@ TEST_CASE("Issue #924")
|
|||||||
|
|
||||||
CHECK_NOTHROW(j.get<Evil>());
|
CHECK_NOTHROW(j.get<Evil>());
|
||||||
CHECK_NOTHROW(j.get<std::vector<Evil>>());
|
CHECK_NOTHROW(j.get<std::vector<Evil>>());
|
||||||
|
|
||||||
|
// silence Wunused-template warnings
|
||||||
|
Evil e(1);
|
||||||
|
CHECK(e.m_i >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Issue #1237")
|
TEST_CASE("Issue #1237")
|
||||||
|
|||||||
2
test/thirdparty/doctest/doctest.h
vendored
2
test/thirdparty/doctest/doctest.h
vendored
@ -2913,7 +2913,7 @@ typedef timer_large_integer::type ticks_t;
|
|||||||
//unsigned int getElapsedMilliseconds() const {
|
//unsigned int getElapsedMilliseconds() const {
|
||||||
// return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
|
// return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
|
||||||
//}
|
//}
|
||||||
double getElapsedSeconds() const { return (getCurrentTicks() - m_ticks) / 1000000.0; }
|
double getElapsedSeconds() const { return static_cast<double>((getCurrentTicks() - m_ticks)) / 1000000.0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ticks_t m_ticks = 0;
|
ticks_t m_ticks = 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user