Merge branch 'develop' of https://github.com/nlohmann/json into clang_windows
Conflicts: include/nlohmann/detail/input/binary_reader.hpp include/nlohmann/detail/input/input_adapters.hpp include/nlohmann/detail/input/lexer.hpp include/nlohmann/detail/output/binary_writer.hpp include/nlohmann/json.hpp single_include/nlohmann/json.hpp
This commit is contained in:
commit
ac3922c7aa
128 changed files with 7773 additions and 2268 deletions
27
.clang-tidy
27
.clang-tidy
|
@ -1,23 +1,20 @@
|
||||||
Checks: '-*,
|
Checks: '*,
|
||||||
bugprone-*,
|
-cppcoreguidelines-avoid-goto,
|
||||||
cert-*,
|
-cppcoreguidelines-avoid-magic-numbers,
|
||||||
clang-analyzer-*,
|
-cppcoreguidelines-macro-usage,
|
||||||
google-*,
|
-fuchsia-default-arguments-calls,
|
||||||
-google-runtime-references,
|
-fuchsia-default-arguments-declarations,
|
||||||
|
-fuchsia-overloaded-operator,
|
||||||
-google-explicit-constructor,
|
-google-explicit-constructor,
|
||||||
hicpp-*,
|
-google-runtime-references,
|
||||||
|
-hicpp-avoid-goto,
|
||||||
|
-hicpp-explicit-conversions,
|
||||||
-hicpp-no-array-decay,
|
-hicpp-no-array-decay,
|
||||||
-hicpp-uppercase-literal-suffix,
|
-hicpp-uppercase-literal-suffix,
|
||||||
-hicpp-explicit-conversions,
|
|
||||||
misc-*,
|
|
||||||
-misc-non-private-member-variables-in-classes,
|
|
||||||
llvm-*,
|
|
||||||
-llvm-header-guard,
|
-llvm-header-guard,
|
||||||
modernize-*,
|
-llvm-include-order,
|
||||||
|
-misc-non-private-member-variables-in-classes,
|
||||||
-modernize-use-trailing-return-type,
|
-modernize-use-trailing-return-type,
|
||||||
performance-*,
|
|
||||||
portability-*,
|
|
||||||
readability-*,
|
|
||||||
-readability-magic-numbers,
|
-readability-magic-numbers,
|
||||||
-readability-uppercase-literal-suffix'
|
-readability-uppercase-literal-suffix'
|
||||||
|
|
||||||
|
|
16
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
16
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
|
@ -1,16 +0,0 @@
|
||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
title: ''
|
|
||||||
labels: 'kind: enhancement/improvement'
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### 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. -->
|
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Ask a question
|
||||||
|
url: https://github.com/nlohmann/json/discussions
|
||||||
|
about: Ask questions and discuss with other community members
|
40
.github/ISSUE_TEMPLATE/question.md
vendored
40
.github/ISSUE_TEMPLATE/question.md
vendored
|
@ -1,40 +0,0 @@
|
||||||
---
|
|
||||||
name: Question
|
|
||||||
about: Ask a question regarding the library.
|
|
||||||
title: ''
|
|
||||||
labels: 'kind: question'
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- Provide a concise summary of the issue in the title above. -->
|
|
||||||
|
|
||||||
#### What do you want to achieve?
|
|
||||||
|
|
||||||
<!-- Please describe the feature as detailed as possible. -->
|
|
||||||
|
|
||||||
#### What have you tried?
|
|
||||||
|
|
||||||
<!-- 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 -->
|
|
||||||
|
|
||||||
#### Can you provide a small code example?
|
|
||||||
|
|
||||||
<!-- Please understand that we cannot analyze and debug large code bases. -->
|
|
||||||
|
|
||||||
#### 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
|
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -26,3 +26,9 @@ cmake-build-debug
|
||||||
|
|
||||||
test/test-*
|
test/test-*
|
||||||
/.vs
|
/.vs
|
||||||
|
|
||||||
|
doc/mkdocs/venv/
|
||||||
|
doc/mkdocs/docs/images
|
||||||
|
doc/mkdocs/docs/examples
|
||||||
|
doc/mkdocs/site
|
||||||
|
doc/mkdocs/docs/__pycache__/
|
||||||
|
|
|
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.1)
|
||||||
## PROJECT
|
## PROJECT
|
||||||
## name and version
|
## name and version
|
||||||
##
|
##
|
||||||
project(nlohmann_json VERSION 3.7.3 LANGUAGES CXX)
|
project(nlohmann_json VERSION 3.8.0 LANGUAGES CXX)
|
||||||
|
|
||||||
##
|
##
|
||||||
## INCLUDE
|
## INCLUDE
|
||||||
|
@ -15,6 +15,12 @@ include(ExternalProject)
|
||||||
##
|
##
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
##
|
##
|
||||||
|
|
||||||
|
if (POLICY CMP0077)
|
||||||
|
# Allow CMake 3.13+ to override options when using FetchContent / add_subdirectory.
|
||||||
|
cmake_policy(SET CMP0077 NEW)
|
||||||
|
endif ()
|
||||||
|
|
||||||
option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ON)
|
option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ON)
|
||||||
option(JSON_Install "Install CMake targets during install step." ON)
|
option(JSON_Install "Install CMake targets during install step." ON)
|
||||||
option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OFF)
|
option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OFF)
|
||||||
|
|
504
ChangeLog.md
504
ChangeLog.md
|
@ -1,7 +1,338 @@
|
||||||
# Change Log
|
# Changelog
|
||||||
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
|
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
## [v3.8.0](https://github.com/nlohmann/json/releases/tag/v3.8.0) (2020-06-14)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.3...v3.8.0)
|
||||||
|
|
||||||
|
- sorry delete this issue, i'm stupid [\#2187](https://github.com/nlohmann/json/issues/2187)
|
||||||
|
- Append to a std::nlohmann::json type [\#2186](https://github.com/nlohmann/json/issues/2186)
|
||||||
|
- Object properties should not be re-sorted alphabetically [\#2179](https://github.com/nlohmann/json/issues/2179)
|
||||||
|
- Some troubles to compile the last revision [\#2177](https://github.com/nlohmann/json/issues/2177)
|
||||||
|
- \# Top level CMakeLists.txt
|
||||||
|
project\(FOO\)
|
||||||
|
...
|
||||||
|
option\(FOO\_USE\_EXTERNAL\_JSON "Use an external JSON library" OFF\)
|
||||||
|
...
|
||||||
|
add\_subdirectory\(thirdparty\)
|
||||||
|
...
|
||||||
|
add\_library\(foo ...\)
|
||||||
|
...
|
||||||
|
\# Note that the namespaced target will always be available regardless of the
|
||||||
|
\# import method
|
||||||
|
target\_link\_libraries\(foo PRIVATE nlohmann\_json::nlohmann\_json\) [\#2170](https://github.com/nlohmann/json/issues/2170)
|
||||||
|
- https://www.github.com/nlohmann/json/tree/develop/include%2Fnlohmann%2Fjson\_fwd.hpp [\#2169](https://github.com/nlohmann/json/issues/2169)
|
||||||
|
- templated from\_json of non primitive types causes gcc error [\#2168](https://github.com/nlohmann/json/issues/2168)
|
||||||
|
- few warnings/errors in copy assignment [\#2167](https://github.com/nlohmann/json/issues/2167)
|
||||||
|
- Different output when upgrading from clang 9 to clang 10 [\#2166](https://github.com/nlohmann/json/issues/2166)
|
||||||
|
- Cannot build with VS 2019 / C++17 [\#2163](https://github.com/nlohmann/json/issues/2163)
|
||||||
|
- Q: When I received an illegal string,How the program knows? [\#2162](https://github.com/nlohmann/json/issues/2162)
|
||||||
|
- Problem while reading a json file [\#2161](https://github.com/nlohmann/json/issues/2161)
|
||||||
|
- converting std::chrono::system\_clock::time\_point to json. [\#2159](https://github.com/nlohmann/json/issues/2159)
|
||||||
|
- how to parse vector\<struct\> format [\#2157](https://github.com/nlohmann/json/issues/2157)
|
||||||
|
- nlohmann::json and =nullptr [\#2156](https://github.com/nlohmann/json/issues/2156)
|
||||||
|
- test-cbor fails [\#2154](https://github.com/nlohmann/json/issues/2154)
|
||||||
|
- Accessing array inside array syntax? [\#2151](https://github.com/nlohmann/json/issues/2151)
|
||||||
|
- Best way to catch errors when querying json [\#2150](https://github.com/nlohmann/json/issues/2150)
|
||||||
|
- Adding a value to an existing json puts it at the beginning instead of the end [\#2149](https://github.com/nlohmann/json/issues/2149)
|
||||||
|
- JSON Data Mapping Key-Value from other Key-Value [\#2148](https://github.com/nlohmann/json/issues/2148)
|
||||||
|
- Conflicts with std \<any\> compiling with GCC 10 [\#2146](https://github.com/nlohmann/json/issues/2146)
|
||||||
|
- Incorrect CMake FetchContent example [\#2142](https://github.com/nlohmann/json/issues/2142)
|
||||||
|
- Help for a Beginner? [\#2141](https://github.com/nlohmann/json/issues/2141)
|
||||||
|
- Read Json from File [\#2139](https://github.com/nlohmann/json/issues/2139)
|
||||||
|
- How to feed a predefined integer value into json string [\#2138](https://github.com/nlohmann/json/issues/2138)
|
||||||
|
- getting json array inside json object [\#2135](https://github.com/nlohmann/json/issues/2135)
|
||||||
|
- Add .contains example to doc [\#2133](https://github.com/nlohmann/json/issues/2133)
|
||||||
|
- Is it safe to return string.c\_str\(\) received from get\(\)? [\#2130](https://github.com/nlohmann/json/issues/2130)
|
||||||
|
- GCC 10: Compilation error when including any before including json header in C++17 mode [\#2129](https://github.com/nlohmann/json/issues/2129)
|
||||||
|
- Intersection of two json files [\#2127](https://github.com/nlohmann/json/issues/2127)
|
||||||
|
- App crashes when dump method called for non ascii chars. [\#2126](https://github.com/nlohmann/json/issues/2126)
|
||||||
|
- iterator based erase method [\#2122](https://github.com/nlohmann/json/issues/2122)
|
||||||
|
- quick and convenient api to get/set nested json values [\#2120](https://github.com/nlohmann/json/issues/2120)
|
||||||
|
- assigning nullptr to std::string [\#2118](https://github.com/nlohmann/json/issues/2118)
|
||||||
|
- usless\_cast warnings with gcc 9.3 and 10.1 \(C++17\) [\#2114](https://github.com/nlohmann/json/issues/2114)
|
||||||
|
- clang 10 warning [\#2113](https://github.com/nlohmann/json/issues/2113)
|
||||||
|
- Possible incorrect \_MSC\_VER reference [\#2112](https://github.com/nlohmann/json/issues/2112)
|
||||||
|
- warning under gcc 10.1 [\#2110](https://github.com/nlohmann/json/issues/2110)
|
||||||
|
- Wdeprecated-declarations from GCC v10.1.0 [\#2109](https://github.com/nlohmann/json/issues/2109)
|
||||||
|
- Global std::vector from json [\#2108](https://github.com/nlohmann/json/issues/2108)
|
||||||
|
- heap-buffer-overflow when using nlohmann/json, ASAN, and gtest [\#2107](https://github.com/nlohmann/json/issues/2107)
|
||||||
|
- exception 0x770DC5AF when i read an special char in json file [\#2106](https://github.com/nlohmann/json/issues/2106)
|
||||||
|
- json::parse\(\) fails to parse a dump\(2,' '\) output, yet does successfully parse dump\(\) [\#2105](https://github.com/nlohmann/json/issues/2105)
|
||||||
|
- run test-udt error in MSVC 19.16.27034.0 [\#2103](https://github.com/nlohmann/json/issues/2103)
|
||||||
|
- Unable to dump to stringstream [\#2102](https://github.com/nlohmann/json/issues/2102)
|
||||||
|
- Can't ad an object in another objet [\#2101](https://github.com/nlohmann/json/issues/2101)
|
||||||
|
- Implicit conversion causes "cannot use operator\[\] with a string argument with string" [\#2098](https://github.com/nlohmann/json/issues/2098)
|
||||||
|
- C++20: char8\_t [\#2097](https://github.com/nlohmann/json/issues/2097)
|
||||||
|
- UTF8 [\#2095](https://github.com/nlohmann/json/issues/2095)
|
||||||
|
- Compilation issues when included in project [\#2094](https://github.com/nlohmann/json/issues/2094)
|
||||||
|
- string value with null character causes infinite loop [\#2093](https://github.com/nlohmann/json/issues/2093)
|
||||||
|
- corrupted size vs. prev\_size \(aborted\) [\#2092](https://github.com/nlohmann/json/issues/2092)
|
||||||
|
- Get string field content without return std::string copy [\#2091](https://github.com/nlohmann/json/issues/2091)
|
||||||
|
- JSON Comments \(JSON 5\) [\#2090](https://github.com/nlohmann/json/issues/2090)
|
||||||
|
- Remove \#include \<ciso646\> [\#2089](https://github.com/nlohmann/json/issues/2089)
|
||||||
|
- JSON library as a git submodule [\#2088](https://github.com/nlohmann/json/issues/2088)
|
||||||
|
- Apple Clang 11.0.3 on MacOS Catalina 10.15.4 not compiling [\#2087](https://github.com/nlohmann/json/issues/2087)
|
||||||
|
- Value function return empty object even if it exist [\#2086](https://github.com/nlohmann/json/issues/2086)
|
||||||
|
- Cannot debug but Run works [\#2085](https://github.com/nlohmann/json/issues/2085)
|
||||||
|
- Question about serialization. [\#2084](https://github.com/nlohmann/json/issues/2084)
|
||||||
|
- How to include in an external project [\#2083](https://github.com/nlohmann/json/issues/2083)
|
||||||
|
- Missing tests for binary values [\#2082](https://github.com/nlohmann/json/issues/2082)
|
||||||
|
- How to override default string serialization? [\#2079](https://github.com/nlohmann/json/issues/2079)
|
||||||
|
- Can't have a json type as a property in an arbitrary type [\#2078](https://github.com/nlohmann/json/issues/2078)
|
||||||
|
- New release? [\#2075](https://github.com/nlohmann/json/issues/2075)
|
||||||
|
- CMake FetchContent \> Updating the documentation? [\#2073](https://github.com/nlohmann/json/issues/2073)
|
||||||
|
- How to convert STL Vector \(of user defined type\) to Json [\#2072](https://github.com/nlohmann/json/issues/2072)
|
||||||
|
- how to make an array of objects [\#2070](https://github.com/nlohmann/json/issues/2070)
|
||||||
|
- ‘\_\_int64’ was not declared [\#2068](https://github.com/nlohmann/json/issues/2068)
|
||||||
|
- \[json.exception.type\_error.317\] cannot serialize binary data to text JSON [\#2067](https://github.com/nlohmann/json/issues/2067)
|
||||||
|
- Unexpected end of input; expected '\[', '{', or a literal [\#2066](https://github.com/nlohmann/json/issues/2066)
|
||||||
|
- Json structure can be nested? [\#2065](https://github.com/nlohmann/json/issues/2065)
|
||||||
|
- Bug: returning reference to local temporary object [\#2064](https://github.com/nlohmann/json/issues/2064)
|
||||||
|
- Allow to use non strict parsing [\#2063](https://github.com/nlohmann/json/issues/2063)
|
||||||
|
- Crashing on json::at [\#2062](https://github.com/nlohmann/json/issues/2062)
|
||||||
|
- Add support for JSONC [\#2061](https://github.com/nlohmann/json/issues/2061)
|
||||||
|
- How to convert a const std::vector\<char8\_t\> message to a json, to be able to parse it and extract information from it? Can you point to any examples? [\#2058](https://github.com/nlohmann/json/issues/2058)
|
||||||
|
- Nice library [\#2057](https://github.com/nlohmann/json/issues/2057)
|
||||||
|
- json.hpp:15372:22: error: expected unqualified-id if \(not std::isfinite\(x\)\): Started getting this bug after updating my XCode [\#2056](https://github.com/nlohmann/json/issues/2056)
|
||||||
|
- Confused as how I can extract the values from the JSON object. [\#2055](https://github.com/nlohmann/json/issues/2055)
|
||||||
|
- Warnings with GCC 10 [\#2052](https://github.com/nlohmann/json/issues/2052)
|
||||||
|
- Warnings with Clang 10 [\#2049](https://github.com/nlohmann/json/issues/2049)
|
||||||
|
- Update doctest [\#2048](https://github.com/nlohmann/json/issues/2048)
|
||||||
|
- Unclear error message: "cannot use operator\[\] with a string argument with array" [\#2047](https://github.com/nlohmann/json/issues/2047)
|
||||||
|
- Serializing std::variant\<T, std::vector\<T\>\> [\#2045](https://github.com/nlohmann/json/issues/2045)
|
||||||
|
- Crash when parse big jsonfile [\#2042](https://github.com/nlohmann/json/issues/2042)
|
||||||
|
- How to check if a key exists without silently generating null objects on the path [\#2041](https://github.com/nlohmann/json/issues/2041)
|
||||||
|
- Crash when traversing over items\(\) of temporary json objects [\#2040](https://github.com/nlohmann/json/issues/2040)
|
||||||
|
- How to parse multiple line value ? [\#2039](https://github.com/nlohmann/json/issues/2039)
|
||||||
|
- SAX API uses unsigned std::size\_t but -1 if element size is not known; [\#2037](https://github.com/nlohmann/json/issues/2037)
|
||||||
|
- How to parse big decimal data [\#2036](https://github.com/nlohmann/json/issues/2036)
|
||||||
|
- how use template \<typename T\> struct adl\_serializer [\#2035](https://github.com/nlohmann/json/issues/2035)
|
||||||
|
- auto iterator returned by find to handle value depending if is string or numeric. [\#2032](https://github.com/nlohmann/json/issues/2032)
|
||||||
|
- pass find returned iterator to numeric variable. [\#2031](https://github.com/nlohmann/json/issues/2031)
|
||||||
|
- Parse error on valid json file [\#2029](https://github.com/nlohmann/json/issues/2029)
|
||||||
|
- Is here any elegant way to combine serialization and deserialization code? [\#2028](https://github.com/nlohmann/json/issues/2028)
|
||||||
|
- Notes about dump function [\#2027](https://github.com/nlohmann/json/issues/2027)
|
||||||
|
- Different JSON printouts for empty dictionary on Linux and Mac. [\#2026](https://github.com/nlohmann/json/issues/2026)
|
||||||
|
- easier way to get exception reason out of json\_sax\_dom\_callback\_parser without exceptions [\#2024](https://github.com/nlohmann/json/issues/2024)
|
||||||
|
- Using fifo\_map with base class and derived class [\#2023](https://github.com/nlohmann/json/issues/2023)
|
||||||
|
- Error reading JSON File [\#2022](https://github.com/nlohmann/json/issues/2022)
|
||||||
|
- Parse causing crash on android. Cannot catch. [\#2021](https://github.com/nlohmann/json/issues/2021)
|
||||||
|
- Extra backslashes in nested json [\#2020](https://github.com/nlohmann/json/issues/2020)
|
||||||
|
- How to create patch for merge\_patch input ? [\#2018](https://github.com/nlohmann/json/issues/2018)
|
||||||
|
- CppUTest/include/CppUTestExt/MockSupport.h:40: error: default argument for ‘MockFailureReporter\* failureReporterForThisCall’ has type ‘void\*’ [\#2017](https://github.com/nlohmann/json/issues/2017)
|
||||||
|
- including another file [\#2016](https://github.com/nlohmann/json/issues/2016)
|
||||||
|
- GNU PREREQ Error with gcc 9.3.0 [\#2015](https://github.com/nlohmann/json/issues/2015)
|
||||||
|
- Parse error: json.exception.parse\_error.101 - invalid string: ill-formed UTF-8 byte [\#2014](https://github.com/nlohmann/json/issues/2014)
|
||||||
|
- Add more flexibility to basic\_json's ObjectType \(and ArrayType\) [\#2013](https://github.com/nlohmann/json/issues/2013)
|
||||||
|
- afl persistent mode [\#2012](https://github.com/nlohmann/json/issues/2012)
|
||||||
|
- Compiler Errors under VS2019 in Appveyor CI [\#2009](https://github.com/nlohmann/json/issues/2009)
|
||||||
|
- Another compilation failure with Visual Studio [\#2007](https://github.com/nlohmann/json/issues/2007)
|
||||||
|
- Implicit cast to std::string broken again with VS2019 16.5.0 [\#2006](https://github.com/nlohmann/json/issues/2006)
|
||||||
|
- error: no matching member function for call to 'AddRaw' [\#2005](https://github.com/nlohmann/json/issues/2005)
|
||||||
|
- When I re-create an object again after the network request, an error is reported [\#2003](https://github.com/nlohmann/json/issues/2003)
|
||||||
|
- How to merge \(and not replace\) different Json::Value objects in jsoncpp [\#2001](https://github.com/nlohmann/json/issues/2001)
|
||||||
|
- scalar transforms to list [\#2000](https://github.com/nlohmann/json/issues/2000)
|
||||||
|
- Dump JSON containing multibyte characters [\#1999](https://github.com/nlohmann/json/issues/1999)
|
||||||
|
- Build error when modify value [\#1998](https://github.com/nlohmann/json/issues/1998)
|
||||||
|
- How do i include a vector of pointers in my json? [\#1997](https://github.com/nlohmann/json/issues/1997)
|
||||||
|
- Compiler error wrt incomplete types changed in gcc8.3.0-26 [\#1996](https://github.com/nlohmann/json/issues/1996)
|
||||||
|
- NaN-like comparison behavior of discarded is inconvenient [\#1988](https://github.com/nlohmann/json/issues/1988)
|
||||||
|
- Maintaining JSON package in my CMake [\#1987](https://github.com/nlohmann/json/issues/1987)
|
||||||
|
- reading int number and string number [\#1986](https://github.com/nlohmann/json/issues/1986)
|
||||||
|
- Build error: keyword is hidden by macro definition! [\#1985](https://github.com/nlohmann/json/issues/1985)
|
||||||
|
- JSON patch diff for op=add formation is not as per standard \(RFC 6902\) [\#1983](https://github.com/nlohmann/json/issues/1983)
|
||||||
|
- json\_pointer.contains\(\) exception is incorrectly raised [\#1982](https://github.com/nlohmann/json/issues/1982)
|
||||||
|
- Error with non existing key [\#1981](https://github.com/nlohmann/json/issues/1981)
|
||||||
|
- Closed [\#1978](https://github.com/nlohmann/json/issues/1978)
|
||||||
|
- Where is the library built and what is the name? [\#1977](https://github.com/nlohmann/json/issues/1977)
|
||||||
|
- The cmake\_import example does not build [\#1976](https://github.com/nlohmann/json/issues/1976)
|
||||||
|
- Dumping core when reading invalid file [\#1975](https://github.com/nlohmann/json/issues/1975)
|
||||||
|
- Abort in dump\(\) method [\#1973](https://github.com/nlohmann/json/issues/1973)
|
||||||
|
- Unclear docs regarding parser\_callback\_t callbacks [\#1972](https://github.com/nlohmann/json/issues/1972)
|
||||||
|
- Possible memory leak on push\_back [\#1971](https://github.com/nlohmann/json/issues/1971)
|
||||||
|
- Is it possible to get a safe mutable reference/pointer to internal variant used in nlohmann json? [\#1970](https://github.com/nlohmann/json/issues/1970)
|
||||||
|
- Getting a flatten json to map\<string, string\> [\#1957](https://github.com/nlohmann/json/issues/1957)
|
||||||
|
- forced type conversion or lexical cast without exception. [\#1955](https://github.com/nlohmann/json/issues/1955)
|
||||||
|
- Add json\_view type support to avoid excessive copying [\#1954](https://github.com/nlohmann/json/issues/1954)
|
||||||
|
- Adding "examples" section for real-life usages [\#1953](https://github.com/nlohmann/json/issues/1953)
|
||||||
|
- GDB pretty printing support [\#1952](https://github.com/nlohmann/json/issues/1952)
|
||||||
|
- Add nlohmann::json::key\_type [\#1951](https://github.com/nlohmann/json/issues/1951)
|
||||||
|
- cannot use operator\[\] with a string argument with string [\#1949](https://github.com/nlohmann/json/issues/1949)
|
||||||
|
- std::ifstream \>\> json error [\#1948](https://github.com/nlohmann/json/issues/1948)
|
||||||
|
- Cannot update json data in an iterator? [\#1947](https://github.com/nlohmann/json/issues/1947)
|
||||||
|
- How can i build this library in VS 2017? [\#1943](https://github.com/nlohmann/json/issues/1943)
|
||||||
|
- json\_pointer.contains\(\) exceptions when path not found [\#1942](https://github.com/nlohmann/json/issues/1942)
|
||||||
|
- Nested objects serialize/deserialize [\#1941](https://github.com/nlohmann/json/issues/1941)
|
||||||
|
- Compile warning on architectures that are not x86 [\#1939](https://github.com/nlohmann/json/issues/1939)
|
||||||
|
- Version of nlohmann-json-dev in debian packages [\#1938](https://github.com/nlohmann/json/issues/1938)
|
||||||
|
- Create a json object for every cycle [\#1937](https://github.com/nlohmann/json/issues/1937)
|
||||||
|
- How to get the object name? [\#1936](https://github.com/nlohmann/json/issues/1936)
|
||||||
|
- Reserve and resize function for basic json [\#1935](https://github.com/nlohmann/json/issues/1935)
|
||||||
|
- How to use json parse in tsl::ordread\_map? [\#1934](https://github.com/nlohmann/json/issues/1934)
|
||||||
|
- C++14 support is not enabled with msvc2015 [\#1932](https://github.com/nlohmann/json/issues/1932)
|
||||||
|
- Need help with to\_json for derived class, keep getting "cannot use operator" [\#1931](https://github.com/nlohmann/json/issues/1931)
|
||||||
|
- How to handle std::vector\<std::uint8\_t\> [\#1930](https://github.com/nlohmann/json/issues/1930)
|
||||||
|
- Heap corruption issue [\#1929](https://github.com/nlohmann/json/issues/1929)
|
||||||
|
- Add `std::wistream` support. [\#1928](https://github.com/nlohmann/json/issues/1928)
|
||||||
|
- This i can write and read any file thanks [\#1927](https://github.com/nlohmann/json/issues/1927)
|
||||||
|
- How can I get this simple example working? [\#1926](https://github.com/nlohmann/json/issues/1926)
|
||||||
|
- emplace\_back does not seems to work with the int 0 [\#1925](https://github.com/nlohmann/json/issues/1925)
|
||||||
|
- Why nlohmann does not release memory [\#1924](https://github.com/nlohmann/json/issues/1924)
|
||||||
|
- Is it possible to have template `json::parse` with `noexcept` specifier? [\#1922](https://github.com/nlohmann/json/issues/1922)
|
||||||
|
- JSON to wstring? [\#1921](https://github.com/nlohmann/json/issues/1921)
|
||||||
|
- GCC 10 tests build failure [\#1920](https://github.com/nlohmann/json/issues/1920)
|
||||||
|
- Size of binary json representations [\#1919](https://github.com/nlohmann/json/issues/1919)
|
||||||
|
- Accessing strings \(for example in keys or values\) without having the lib create a copy of it. [\#1916](https://github.com/nlohmann/json/issues/1916)
|
||||||
|
- operator== documentation should show how to apply custom comparison function [\#1915](https://github.com/nlohmann/json/issues/1915)
|
||||||
|
- char8\_t and std::u8string support [\#1914](https://github.com/nlohmann/json/issues/1914)
|
||||||
|
- std::is\_pod is deprecated in C++20 [\#1913](https://github.com/nlohmann/json/issues/1913)
|
||||||
|
- Incomplete types reported by \(experimental\) GCC10 [\#1912](https://github.com/nlohmann/json/issues/1912)
|
||||||
|
- Compile warnings on MSVC 14.2 [\#1911](https://github.com/nlohmann/json/issues/1911)
|
||||||
|
- How to parse json file with type composition of std::optional and std::variant [\#1910](https://github.com/nlohmann/json/issues/1910)
|
||||||
|
- why root\_schema be implemented as unique\_ptr in json-validator.cpp,could I use it as shared\_ptr? [\#1908](https://github.com/nlohmann/json/issues/1908)
|
||||||
|
- compile error in gcc-6.3.0 [\#1906](https://github.com/nlohmann/json/issues/1906)
|
||||||
|
- Scalar constexpr is odr-used when used as json initializer [\#1905](https://github.com/nlohmann/json/issues/1905)
|
||||||
|
- install Slack app [\#1904](https://github.com/nlohmann/json/issues/1904)
|
||||||
|
- typo in a comment [\#1903](https://github.com/nlohmann/json/issues/1903)
|
||||||
|
- Watch JSON variables in Debug [\#1902](https://github.com/nlohmann/json/issues/1902)
|
||||||
|
- does Json sdk cares about dfc dfd utf8 issue? [\#1901](https://github.com/nlohmann/json/issues/1901)
|
||||||
|
- Compilation failure using Clang on Windows [\#1898](https://github.com/nlohmann/json/issues/1898)
|
||||||
|
- Allow multiple line string value in JSON [\#1897](https://github.com/nlohmann/json/issues/1897)
|
||||||
|
- Writing map to json file [\#1896](https://github.com/nlohmann/json/issues/1896)
|
||||||
|
- Small documentation mistake [\#1895](https://github.com/nlohmann/json/issues/1895)
|
||||||
|
- why static function `parse` cann't find in visual studio 2019 [\#1894](https://github.com/nlohmann/json/issues/1894)
|
||||||
|
- Best way to handle json files with missing key value pairs. [\#1893](https://github.com/nlohmann/json/issues/1893)
|
||||||
|
- accessing json object as multimap [\#1892](https://github.com/nlohmann/json/issues/1892)
|
||||||
|
- What is the best way to parse vec3s into glm::vec3 [\#1891](https://github.com/nlohmann/json/issues/1891)
|
||||||
|
- Get array of items without using vector [\#1890](https://github.com/nlohmann/json/issues/1890)
|
||||||
|
- Build errors \(clang 11.0.0\) on macOS 10.15.2 [\#1889](https://github.com/nlohmann/json/issues/1889)
|
||||||
|
- Multiple arrays to vectors help [\#1888](https://github.com/nlohmann/json/issues/1888)
|
||||||
|
- json::parse\(begin, end\) parse error on first character using uchar\* [\#1887](https://github.com/nlohmann/json/issues/1887)
|
||||||
|
- issue in free\(\) [\#1886](https://github.com/nlohmann/json/issues/1886)
|
||||||
|
- is\_number\_unsigned\(\) returns false for positive integers \(int or 0 or 1 literals\) [\#1885](https://github.com/nlohmann/json/issues/1885)
|
||||||
|
- MSVC build failure with /Zc:\_\_cplusplus and C++17 [\#1883](https://github.com/nlohmann/json/issues/1883)
|
||||||
|
- RFC 6901 op:replace & arrays [\#1882](https://github.com/nlohmann/json/issues/1882)
|
||||||
|
- Problem with serialization of my custom template doubly-linked list [\#1881](https://github.com/nlohmann/json/issues/1881)
|
||||||
|
- is\_array\(\) is True, but raise 'cannot use operator\[\] for object iterators' [\#1880](https://github.com/nlohmann/json/issues/1880)
|
||||||
|
- Serialize dynamic array [\#1879](https://github.com/nlohmann/json/issues/1879)
|
||||||
|
- Serialization of struct object. [\#1877](https://github.com/nlohmann/json/issues/1877)
|
||||||
|
- warning:c4503 [\#1875](https://github.com/nlohmann/json/issues/1875)
|
||||||
|
- Why are flattened empty objects/arrays not representable? [\#1874](https://github.com/nlohmann/json/issues/1874)
|
||||||
|
- Container Overflow \(ASAN\) when using operator \>\> on an ifs [\#1873](https://github.com/nlohmann/json/issues/1873)
|
||||||
|
- Sub-array to vector or map object? [\#1870](https://github.com/nlohmann/json/issues/1870)
|
||||||
|
- WIP: QT \(cute\) type supports [\#1869](https://github.com/nlohmann/json/issues/1869)
|
||||||
|
- Compiler flags to disable features and shrink code size [\#1868](https://github.com/nlohmann/json/issues/1868)
|
||||||
|
- null strings [\#1867](https://github.com/nlohmann/json/issues/1867)
|
||||||
|
- Struct with array of struct and \_\_attribute\_\_\(\(packed\)\) [\#1866](https://github.com/nlohmann/json/issues/1866)
|
||||||
|
- Best way to extract numbers in the string? [\#1865](https://github.com/nlohmann/json/issues/1865)
|
||||||
|
- Displaying \\?\Volume{guid} from string to json giving error [\#1864](https://github.com/nlohmann/json/issues/1864)
|
||||||
|
- not working when compiling as x86 [\#1863](https://github.com/nlohmann/json/issues/1863)
|
||||||
|
- Skipping evaluation of log line expressions with a macro, is it possible? [\#1862](https://github.com/nlohmann/json/issues/1862)
|
||||||
|
- Suppress warnings [\#1861](https://github.com/nlohmann/json/issues/1861)
|
||||||
|
- conflit with g++ compile option -mwindows [\#1860](https://github.com/nlohmann/json/issues/1860)
|
||||||
|
- How to serialize nested classes to semi-flat JSON object? [\#1859](https://github.com/nlohmann/json/issues/1859)
|
||||||
|
- Memory Requirement for large json file [\#1858](https://github.com/nlohmann/json/issues/1858)
|
||||||
|
- Query a binary format \(BSON, CBOR, MessagePack, UBJSON\) [\#1856](https://github.com/nlohmann/json/issues/1856)
|
||||||
|
- Documentation on operator\[\] behavior with missing keys [\#1855](https://github.com/nlohmann/json/issues/1855)
|
||||||
|
- Problem in converting string into JSON; Can't parse successfully. [\#1854](https://github.com/nlohmann/json/issues/1854)
|
||||||
|
- json.at\_or\_default\(key, defaultval\) [\#1852](https://github.com/nlohmann/json/issues/1852)
|
||||||
|
- please improve the enum conversion documentation \(my example gist provided\) [\#1851](https://github.com/nlohmann/json/issues/1851)
|
||||||
|
- Default value returned on ValueType nlohmann::basic\_json::value \(const typename object\_t::key\_type& key, const ValueType& default\_value\) [\#1850](https://github.com/nlohmann/json/issues/1850)
|
||||||
|
- Accounting for arbitrary precision numerical literals [\#1849](https://github.com/nlohmann/json/issues/1849)
|
||||||
|
- While trying to make a simple array, I get a nested array instead [\#1848](https://github.com/nlohmann/json/issues/1848)
|
||||||
|
- How to reuse the parser and serializer intermediate storage? [\#1847](https://github.com/nlohmann/json/issues/1847)
|
||||||
|
- Too much content in json.hpp leads to slow compilation [\#1845](https://github.com/nlohmann/json/issues/1845)
|
||||||
|
- Cannot read some data in json file [\#1843](https://github.com/nlohmann/json/issues/1843)
|
||||||
|
- Precompiled JSON library? [\#1842](https://github.com/nlohmann/json/issues/1842)
|
||||||
|
- Please change assert into throw\(maybe\) in line 17946 [\#1841](https://github.com/nlohmann/json/issues/1841)
|
||||||
|
- JSON for modern C++ ECCN information [\#1840](https://github.com/nlohmann/json/issues/1840)
|
||||||
|
- CI: reduce build time for Travis valgrind [\#1836](https://github.com/nlohmann/json/issues/1836)
|
||||||
|
- How do I traverse a json object and add new elements into the hierarchy [\#1834](https://github.com/nlohmann/json/issues/1834)
|
||||||
|
- Invalid UTF-8 byte at index 1: 0x65 [\#1831](https://github.com/nlohmann/json/issues/1831)
|
||||||
|
- Serialize big data in json [\#1828](https://github.com/nlohmann/json/issues/1828)
|
||||||
|
- Backslash '\' in value causes exception [\#1827](https://github.com/nlohmann/json/issues/1827)
|
||||||
|
- from\_json for non default constructible class with dependency injection [\#1819](https://github.com/nlohmann/json/issues/1819)
|
||||||
|
- Fail to build when including json.hpp as a system include [\#1818](https://github.com/nlohmann/json/issues/1818)
|
||||||
|
- Semi-frequent timeouts in `test-unicode\_all` with 3.6.1 \(aarch64\) [\#1816](https://github.com/nlohmann/json/issues/1816)
|
||||||
|
- input\_adapter not user extensible [\#1813](https://github.com/nlohmann/json/issues/1813)
|
||||||
|
- crash at json::destroy on android [\#1812](https://github.com/nlohmann/json/issues/1812)
|
||||||
|
- Logs are repeating while cmake [\#1809](https://github.com/nlohmann/json/issues/1809)
|
||||||
|
- Add a the possibility to add dynamic json objects [\#1795](https://github.com/nlohmann/json/issues/1795)
|
||||||
|
- Unnecessary test data file in the release [\#1790](https://github.com/nlohmann/json/issues/1790)
|
||||||
|
- Add support for parse stack limiting [\#1788](https://github.com/nlohmann/json/issues/1788)
|
||||||
|
- GCC -Wuseless-cast warnings [\#1777](https://github.com/nlohmann/json/issues/1777)
|
||||||
|
- compilation issue with NVCC 9.0 [\#1773](https://github.com/nlohmann/json/issues/1773)
|
||||||
|
- Unexpected behavior with fifo\_map json when copy and append [\#1763](https://github.com/nlohmann/json/issues/1763)
|
||||||
|
- Parse error [\#1761](https://github.com/nlohmann/json/issues/1761)
|
||||||
|
- Assignment \(using value\(\)\) to nonexistent element behaves differently on Xcode 8 vs Xcode 10 [\#1758](https://github.com/nlohmann/json/issues/1758)
|
||||||
|
- Readme out of date [\#1756](https://github.com/nlohmann/json/issues/1756)
|
||||||
|
- cmake\_\* tests don't use the build system's compiler [\#1747](https://github.com/nlohmann/json/issues/1747)
|
||||||
|
- Static assertions for template type properties required [\#1729](https://github.com/nlohmann/json/issues/1729)
|
||||||
|
- Use float and possibly half in json::to\_cbor [\#1719](https://github.com/nlohmann/json/issues/1719)
|
||||||
|
- json::from\_cbor does not respect allow\_exceptions = false when input is string literal [\#1715](https://github.com/nlohmann/json/issues/1715)
|
||||||
|
- /Zc:\_\_cplusplus leads to C2416 [\#1695](https://github.com/nlohmann/json/issues/1695)
|
||||||
|
- `unflatten` vs objects with number-ish keys [\#1575](https://github.com/nlohmann/json/issues/1575)
|
||||||
|
- A "thinner" source code tar as part of release? [\#1572](https://github.com/nlohmann/json/issues/1572)
|
||||||
|
- Repository is almost 450MB [\#1497](https://github.com/nlohmann/json/issues/1497)
|
||||||
|
- Substantial performance penalty caused by polymorphic input adapter [\#1457](https://github.com/nlohmann/json/issues/1457)
|
||||||
|
- Move tests to a separate repo [\#1235](https://github.com/nlohmann/json/issues/1235)
|
||||||
|
- reduce repos size [\#1185](https://github.com/nlohmann/json/issues/1185)
|
||||||
|
- CMakeLists.txt in release zips? [\#1184](https://github.com/nlohmann/json/issues/1184)
|
||||||
|
- Minimal branch? [\#1066](https://github.com/nlohmann/json/issues/1066)
|
||||||
|
- Move test blobs to a submodule? [\#732](https://github.com/nlohmann/json/issues/732)
|
||||||
|
- \[Question\] When using this as git submodule, will it clone the whole thing include test data and benchmark? [\#620](https://github.com/nlohmann/json/issues/620)
|
||||||
|
- Need to improve ignores.. [\#567](https://github.com/nlohmann/json/issues/567)
|
||||||
|
- Minimal repository \(current size very large\) [\#556](https://github.com/nlohmann/json/issues/556)
|
||||||
|
- For a header-only library you have to clone 214MB [\#482](https://github.com/nlohmann/json/issues/482)
|
||||||
|
- 17 MB / 90 MB repo size!? [\#96](https://github.com/nlohmann/json/issues/96)
|
||||||
|
|
||||||
|
- Improve parse\_ubjson\_fuzzer [\#2182](https://github.com/nlohmann/json/pull/2182) ([tanuj208](https://github.com/tanuj208))
|
||||||
|
- Add input adapter tests [\#2178](https://github.com/nlohmann/json/pull/2178) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Fix warnings [\#2174](https://github.com/nlohmann/json/pull/2174) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Fix PR\#1006 [\#2158](https://github.com/nlohmann/json/pull/2158) ([dota17](https://github.com/dota17))
|
||||||
|
- Fix issue\#1972 [\#2153](https://github.com/nlohmann/json/pull/2153) ([dota17](https://github.com/dota17))
|
||||||
|
- Update URLs to HTTPS [\#2152](https://github.com/nlohmann/json/pull/2152) ([TotalCaesar659](https://github.com/TotalCaesar659))
|
||||||
|
- Fix Issue\#1813: user defined input adapters [\#2145](https://github.com/nlohmann/json/pull/2145) ([FrancoisChabot](https://github.com/FrancoisChabot))
|
||||||
|
- Fix issue\#1939: Cast character to unsigned for comparison [\#2144](https://github.com/nlohmann/json/pull/2144) ([XyFreak](https://github.com/XyFreak))
|
||||||
|
- Fix issue\#2142: readme: fix typo in CMake FetchContent example [\#2143](https://github.com/nlohmann/json/pull/2143) ([quentin-dev](https://github.com/quentin-dev))
|
||||||
|
- Respect allow\_exceptions=false for binary formats [\#2140](https://github.com/nlohmann/json/pull/2140) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Fix issue 2112 [\#2137](https://github.com/nlohmann/json/pull/2137) ([dota17](https://github.com/dota17))
|
||||||
|
- Add bleeding edge GCC to CI [\#2136](https://github.com/nlohmann/json/pull/2136) ([aokellermann](https://github.com/aokellermann))
|
||||||
|
- Clean up implementation of binary type [\#2125](https://github.com/nlohmann/json/pull/2125) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Fixed a compilation error in MSVC [\#2121](https://github.com/nlohmann/json/pull/2121) ([gistrec](https://github.com/gistrec))
|
||||||
|
- Overwork CI [\#2119](https://github.com/nlohmann/json/pull/2119) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Fix warnings from Clang 10 and GCC 9 [\#2116](https://github.com/nlohmann/json/pull/2116) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Do not include \<ciso646\> when using C++17 [\#2115](https://github.com/nlohmann/json/pull/2115) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Fix issue\#2086: disallow json::value\_t type parameter in value\(\) [\#2104](https://github.com/nlohmann/json/pull/2104) ([dota17](https://github.com/dota17))
|
||||||
|
- Fix Coveralls integration [\#2100](https://github.com/nlohmann/json/pull/2100) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Add tests for binary values [\#2099](https://github.com/nlohmann/json/pull/2099) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Use external test data [\#2081](https://github.com/nlohmann/json/pull/2081) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Remove Doozer CI [\#2080](https://github.com/nlohmann/json/pull/2080) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Fix README.md. Missing ``` [\#2077](https://github.com/nlohmann/json/pull/2077) ([ArthurSonzogni](https://github.com/ArthurSonzogni))
|
||||||
|
- Fix error message about invalid surrogate pairs [\#2076](https://github.com/nlohmann/json/pull/2076) ([rmisev](https://github.com/rmisev))
|
||||||
|
- Add CMake fetchcontent documentation and tests [\#2074](https://github.com/nlohmann/json/pull/2074) ([ArthurSonzogni](https://github.com/ArthurSonzogni))
|
||||||
|
- Properly pass serialize\_binary to dump function [\#2071](https://github.com/nlohmann/json/pull/2071) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Fix returning reference to local temporary object [\#2069](https://github.com/nlohmann/json/pull/2069) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- updated wandbox link [\#2060](https://github.com/nlohmann/json/pull/2060) ([alexandermyasnikov](https://github.com/alexandermyasnikov))
|
||||||
|
- Fix bug in diff function [\#2054](https://github.com/nlohmann/json/pull/2054) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Fix GCC compiler warnings [\#2053](https://github.com/nlohmann/json/pull/2053) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Fix Clang compiler warnings [\#2051](https://github.com/nlohmann/json/pull/2051) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Update doctest to 2.3.7 [\#2050](https://github.com/nlohmann/json/pull/2050) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- Fix issue\#1719 [\#2044](https://github.com/nlohmann/json/pull/2044) ([dota17](https://github.com/dota17))
|
||||||
|
- Add missing testcase about NaN in unit-constructor1.cpp [\#2043](https://github.com/nlohmann/json/pull/2043) ([dota17](https://github.com/dota17))
|
||||||
|
- Templatize basic\_json constructor from json\_ref [\#2034](https://github.com/nlohmann/json/pull/2034) ([ArtemSarmini](https://github.com/ArtemSarmini))
|
||||||
|
- Replace deprecated std::is\_pod [\#2033](https://github.com/nlohmann/json/pull/2033) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
- fix \#1982:json\_pointer.contains\(\) exception is incorrectly raised [\#2019](https://github.com/nlohmann/json/pull/2019) ([dota17](https://github.com/dota17))
|
||||||
|
- catch exceptions for json\_pointer : ..../+99 [\#1990](https://github.com/nlohmann/json/pull/1990) ([dota17](https://github.com/dota17))
|
||||||
|
- fix warnings in serializer.hpp for VS2019 [\#1969](https://github.com/nlohmann/json/pull/1969) ([dota17](https://github.com/dota17))
|
||||||
|
- Fix C26451 warnnings in to\_chars.hpp [\#1967](https://github.com/nlohmann/json/pull/1967) ([dota17](https://github.com/dota17))
|
||||||
|
- templated input adapters [\#1950](https://github.com/nlohmann/json/pull/1950) ([FrancoisChabot](https://github.com/FrancoisChabot))
|
||||||
|
- make CMake's version config file architecture-independent [\#1746](https://github.com/nlohmann/json/pull/1746) ([uhoreg](https://github.com/uhoreg))
|
||||||
|
- Add binary type support to all binary file formats, as well as an internally represented binary type [\#1662](https://github.com/nlohmann/json/pull/1662) ([OmnipotentEntity](https://github.com/OmnipotentEntity))
|
||||||
|
|
||||||
## [v3.7.3](https://github.com/nlohmann/json/releases/tag/v3.7.3) (2019-11-17)
|
## [v3.7.3](https://github.com/nlohmann/json/releases/tag/v3.7.3) (2019-11-17)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.2...v3.7.3)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.2...v3.7.3)
|
||||||
|
|
||||||
- Project branches [\#1839](https://github.com/nlohmann/json/issues/1839)
|
- Project branches [\#1839](https://github.com/nlohmann/json/issues/1839)
|
||||||
|
@ -13,6 +344,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Fix quadratic destruction complexity [\#1838](https://github.com/nlohmann/json/pull/1838) ([nickaein](https://github.com/nickaein))
|
- Fix quadratic destruction complexity [\#1838](https://github.com/nlohmann/json/pull/1838) ([nickaein](https://github.com/nickaein))
|
||||||
|
|
||||||
## [v3.7.2](https://github.com/nlohmann/json/releases/tag/v3.7.2) (2019-11-10)
|
## [v3.7.2](https://github.com/nlohmann/json/releases/tag/v3.7.2) (2019-11-10)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.1...v3.7.2)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.1...v3.7.2)
|
||||||
|
|
||||||
- Segmentation fault in destructor in case of large inputs [\#1835](https://github.com/nlohmann/json/issues/1835)
|
- Segmentation fault in destructor in case of large inputs [\#1835](https://github.com/nlohmann/json/issues/1835)
|
||||||
|
@ -29,6 +361,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Prevent stackoverflow caused by recursive deconstruction [\#1436](https://github.com/nlohmann/json/pull/1436) ([nickaein](https://github.com/nickaein))
|
- Prevent stackoverflow caused by recursive deconstruction [\#1436](https://github.com/nlohmann/json/pull/1436) ([nickaein](https://github.com/nickaein))
|
||||||
|
|
||||||
## [v3.7.1](https://github.com/nlohmann/json/releases/tag/v3.7.1) (2019-11-06)
|
## [v3.7.1](https://github.com/nlohmann/json/releases/tag/v3.7.1) (2019-11-06)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.0...v3.7.1)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.0...v3.7.1)
|
||||||
|
|
||||||
- std::is\_constructible is always true with tuple [\#1825](https://github.com/nlohmann/json/issues/1825)
|
- std::is\_constructible is always true with tuple [\#1825](https://github.com/nlohmann/json/issues/1825)
|
||||||
|
@ -162,6 +495,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- release: add singleinclude and meson.build to include.zip [\#1694](https://github.com/nlohmann/json/pull/1694) ([eli-schwartz](https://github.com/eli-schwartz))
|
- release: add singleinclude and meson.build to include.zip [\#1694](https://github.com/nlohmann/json/pull/1694) ([eli-schwartz](https://github.com/eli-schwartz))
|
||||||
|
|
||||||
## [v3.7.0](https://github.com/nlohmann/json/releases/tag/v3.7.0) (2019-07-28)
|
## [v3.7.0](https://github.com/nlohmann/json/releases/tag/v3.7.0) (2019-07-28)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.6.1...v3.7.0)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.6.1...v3.7.0)
|
||||||
|
|
||||||
- How can I retrieve uknown strings from json file in my C++ program. [\#1684](https://github.com/nlohmann/json/issues/1684)
|
- How can I retrieve uknown strings from json file in my C++ program. [\#1684](https://github.com/nlohmann/json/issues/1684)
|
||||||
|
@ -239,10 +573,8 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Writing an array into a nlohmann::json object [\#1578](https://github.com/nlohmann/json/issues/1578)
|
- Writing an array into a nlohmann::json object [\#1578](https://github.com/nlohmann/json/issues/1578)
|
||||||
- compilation error when using with another library [\#1577](https://github.com/nlohmann/json/issues/1577)
|
- compilation error when using with another library [\#1577](https://github.com/nlohmann/json/issues/1577)
|
||||||
- Homebrew on OSX doesn't install cmake config file [\#1576](https://github.com/nlohmann/json/issues/1576)
|
- Homebrew on OSX doesn't install cmake config file [\#1576](https://github.com/nlohmann/json/issues/1576)
|
||||||
- `unflatten` vs objects with number-ish keys [\#1575](https://github.com/nlohmann/json/issues/1575)
|
|
||||||
- JSON Parse Out of Range Error [\#1574](https://github.com/nlohmann/json/issues/1574)
|
- JSON Parse Out of Range Error [\#1574](https://github.com/nlohmann/json/issues/1574)
|
||||||
- Integrating into existing CMake Project [\#1573](https://github.com/nlohmann/json/issues/1573)
|
- Integrating into existing CMake Project [\#1573](https://github.com/nlohmann/json/issues/1573)
|
||||||
- A "thinner" source code tar as part of release? [\#1572](https://github.com/nlohmann/json/issues/1572)
|
|
||||||
- conversion to std::string failed [\#1571](https://github.com/nlohmann/json/issues/1571)
|
- conversion to std::string failed [\#1571](https://github.com/nlohmann/json/issues/1571)
|
||||||
- jPtr operation does not throw [\#1569](https://github.com/nlohmann/json/issues/1569)
|
- jPtr operation does not throw [\#1569](https://github.com/nlohmann/json/issues/1569)
|
||||||
- How to generate dll file for this project [\#1568](https://github.com/nlohmann/json/issues/1568)
|
- How to generate dll file for this project [\#1568](https://github.com/nlohmann/json/issues/1568)
|
||||||
|
@ -289,11 +621,10 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Intermittent issues with loadJSON [\#1484](https://github.com/nlohmann/json/issues/1484)
|
- Intermittent issues with loadJSON [\#1484](https://github.com/nlohmann/json/issues/1484)
|
||||||
- use json construct std::string [\#1462](https://github.com/nlohmann/json/issues/1462)
|
- use json construct std::string [\#1462](https://github.com/nlohmann/json/issues/1462)
|
||||||
- JSON Creation [\#1461](https://github.com/nlohmann/json/issues/1461)
|
- JSON Creation [\#1461](https://github.com/nlohmann/json/issues/1461)
|
||||||
- Substantial performance penalty caused by polymorphic input adapter [\#1457](https://github.com/nlohmann/json/issues/1457)
|
|
||||||
- Null bytes in files are treated like EOF [\#1095](https://github.com/nlohmann/json/issues/1095)
|
- Null bytes in files are treated like EOF [\#1095](https://github.com/nlohmann/json/issues/1095)
|
||||||
- Feature: to\_string\(const json& j\); [\#916](https://github.com/nlohmann/json/issues/916)
|
- Feature: to\_string\(const json& j\); [\#916](https://github.com/nlohmann/json/issues/916)
|
||||||
|
|
||||||
- Use GNUInstallDirs instead of hard-coded path. [\#1673](https://github.com/nlohmann/json/pull/1673) ([remyabel](https://github.com/remyabel))
|
- Use GNUInstallDirs instead of hard-coded path. [\#1673](https://github.com/nlohmann/json/pull/1673) ([ghost](https://github.com/ghost))
|
||||||
- Package Manager: MSYS2 \(pacman\) [\#1670](https://github.com/nlohmann/json/pull/1670) ([podsvirov](https://github.com/podsvirov))
|
- Package Manager: MSYS2 \(pacman\) [\#1670](https://github.com/nlohmann/json/pull/1670) ([podsvirov](https://github.com/podsvirov))
|
||||||
- Fix json.hpp compilation issue with other typedefs with same name \(Issue \#1642\) [\#1643](https://github.com/nlohmann/json/pull/1643) ([kevinlul](https://github.com/kevinlul))
|
- Fix json.hpp compilation issue with other typedefs with same name \(Issue \#1642\) [\#1643](https://github.com/nlohmann/json/pull/1643) ([kevinlul](https://github.com/kevinlul))
|
||||||
- Add explicit conversion from json to std::string\_view in conversion unit test [\#1639](https://github.com/nlohmann/json/pull/1639) ([taylorhoward92](https://github.com/taylorhoward92))
|
- Add explicit conversion from json to std::string\_view in conversion unit test [\#1639](https://github.com/nlohmann/json/pull/1639) ([taylorhoward92](https://github.com/taylorhoward92))
|
||||||
|
@ -306,7 +637,12 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- moved from Catch to doctest for unit tests [\#1439](https://github.com/nlohmann/json/pull/1439) ([onqtam](https://github.com/onqtam))
|
- moved from Catch to doctest for unit tests [\#1439](https://github.com/nlohmann/json/pull/1439) ([onqtam](https://github.com/onqtam))
|
||||||
|
|
||||||
## [v3.6.1](https://github.com/nlohmann/json/releases/tag/v3.6.1) (2019-03-20)
|
## [v3.6.1](https://github.com/nlohmann/json/releases/tag/v3.6.1) (2019-03-20)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.6.0...v3.6.1)
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/3.6.1...v3.6.1)
|
||||||
|
|
||||||
|
## [3.6.1](https://github.com/nlohmann/json/releases/tag/3.6.1) (2019-03-20)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.6.0...3.6.1)
|
||||||
|
|
||||||
- Failed to build with \<Windows.h\> [\#1531](https://github.com/nlohmann/json/issues/1531)
|
- Failed to build with \<Windows.h\> [\#1531](https://github.com/nlohmann/json/issues/1531)
|
||||||
- Compiling 3.6.0 with GCC \> 7, array vs std::array \#590 is back [\#1530](https://github.com/nlohmann/json/issues/1530)
|
- Compiling 3.6.0 with GCC \> 7, array vs std::array \#590 is back [\#1530](https://github.com/nlohmann/json/issues/1530)
|
||||||
|
@ -314,6 +650,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- unable to parse json [\#1525](https://github.com/nlohmann/json/issues/1525)
|
- unable to parse json [\#1525](https://github.com/nlohmann/json/issues/1525)
|
||||||
|
|
||||||
## [v3.6.0](https://github.com/nlohmann/json/releases/tag/v3.6.0) (2019-03-19)
|
## [v3.6.0](https://github.com/nlohmann/json/releases/tag/v3.6.0) (2019-03-19)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.5.0...v3.6.0)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.5.0...v3.6.0)
|
||||||
|
|
||||||
- How can I turn a string of a json array into a json array? [\#1526](https://github.com/nlohmann/json/issues/1526)
|
- How can I turn a string of a json array into a json array? [\#1526](https://github.com/nlohmann/json/issues/1526)
|
||||||
|
@ -332,7 +669,6 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Error compiling with clang and `JSON\_NOEXCEPTION`: need to include `cstdlib` [\#1500](https://github.com/nlohmann/json/issues/1500)
|
- Error compiling with clang and `JSON\_NOEXCEPTION`: need to include `cstdlib` [\#1500](https://github.com/nlohmann/json/issues/1500)
|
||||||
- The code compiles unsuccessfully with android-ndk-r10e [\#1499](https://github.com/nlohmann/json/issues/1499)
|
- The code compiles unsuccessfully with android-ndk-r10e [\#1499](https://github.com/nlohmann/json/issues/1499)
|
||||||
- Cmake 3.1 in develop, when is it likely to make it into a stable release? [\#1498](https://github.com/nlohmann/json/issues/1498)
|
- Cmake 3.1 in develop, when is it likely to make it into a stable release? [\#1498](https://github.com/nlohmann/json/issues/1498)
|
||||||
- Repository is almost 450MB [\#1497](https://github.com/nlohmann/json/issues/1497)
|
|
||||||
- Some Help please object inside array [\#1494](https://github.com/nlohmann/json/issues/1494)
|
- Some Help please object inside array [\#1494](https://github.com/nlohmann/json/issues/1494)
|
||||||
- How to get data into vector of user-defined type from a Json object [\#1493](https://github.com/nlohmann/json/issues/1493)
|
- How to get data into vector of user-defined type from a Json object [\#1493](https://github.com/nlohmann/json/issues/1493)
|
||||||
- how to find subelement without loop [\#1490](https://github.com/nlohmann/json/issues/1490)
|
- how to find subelement without loop [\#1490](https://github.com/nlohmann/json/issues/1490)
|
||||||
|
@ -420,7 +756,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- :rotating\_light: fixed unused variable warning [\#1435](https://github.com/nlohmann/json/pull/1435) ([pboettch](https://github.com/pboettch))
|
- :rotating\_light: fixed unused variable warning [\#1435](https://github.com/nlohmann/json/pull/1435) ([pboettch](https://github.com/pboettch))
|
||||||
- allow push\_back\(\) and pop\_back\(\) calls on json\_pointer [\#1434](https://github.com/nlohmann/json/pull/1434) ([pboettch](https://github.com/pboettch))
|
- allow push\_back\(\) and pop\_back\(\) calls on json\_pointer [\#1434](https://github.com/nlohmann/json/pull/1434) ([pboettch](https://github.com/pboettch))
|
||||||
- Add instructions about using nlohmann/json with the conda package manager [\#1430](https://github.com/nlohmann/json/pull/1430) ([nicoddemus](https://github.com/nicoddemus))
|
- Add instructions about using nlohmann/json with the conda package manager [\#1430](https://github.com/nlohmann/json/pull/1430) ([nicoddemus](https://github.com/nicoddemus))
|
||||||
- Updated year in README.md [\#1425](https://github.com/nlohmann/json/pull/1425) ([hijxf](https://github.com/hijxf))
|
- Updated year in README.md [\#1425](https://github.com/nlohmann/json/pull/1425) ([jef](https://github.com/jef))
|
||||||
- Fixed broken links in the README file [\#1423](https://github.com/nlohmann/json/pull/1423) ([skypjack](https://github.com/skypjack))
|
- Fixed broken links in the README file [\#1423](https://github.com/nlohmann/json/pull/1423) ([skypjack](https://github.com/skypjack))
|
||||||
- Fixed broken links in the README file [\#1420](https://github.com/nlohmann/json/pull/1420) ([skypjack](https://github.com/skypjack))
|
- Fixed broken links in the README file [\#1420](https://github.com/nlohmann/json/pull/1420) ([skypjack](https://github.com/skypjack))
|
||||||
- docs: typo in README [\#1417](https://github.com/nlohmann/json/pull/1417) ([wythe](https://github.com/wythe))
|
- docs: typo in README [\#1417](https://github.com/nlohmann/json/pull/1417) ([wythe](https://github.com/wythe))
|
||||||
|
@ -430,6 +766,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- CMake: Optional Install if Embedded [\#1330](https://github.com/nlohmann/json/pull/1330) ([ax3l](https://github.com/ax3l))
|
- CMake: Optional Install if Embedded [\#1330](https://github.com/nlohmann/json/pull/1330) ([ax3l](https://github.com/ax3l))
|
||||||
|
|
||||||
## [v3.5.0](https://github.com/nlohmann/json/releases/tag/v3.5.0) (2018-12-21)
|
## [v3.5.0](https://github.com/nlohmann/json/releases/tag/v3.5.0) (2018-12-21)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.4.0...v3.5.0)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.4.0...v3.5.0)
|
||||||
|
|
||||||
- Copyconstructor inserts original into array with single element [\#1397](https://github.com/nlohmann/json/issues/1397)
|
- Copyconstructor inserts original into array with single element [\#1397](https://github.com/nlohmann/json/issues/1397)
|
||||||
|
@ -507,6 +844,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Fix EOL Whitespaces & CMake Spelling [\#1329](https://github.com/nlohmann/json/pull/1329) ([ax3l](https://github.com/ax3l))
|
- Fix EOL Whitespaces & CMake Spelling [\#1329](https://github.com/nlohmann/json/pull/1329) ([ax3l](https://github.com/ax3l))
|
||||||
|
|
||||||
## [v3.4.0](https://github.com/nlohmann/json/releases/tag/v3.4.0) (2018-10-30)
|
## [v3.4.0](https://github.com/nlohmann/json/releases/tag/v3.4.0) (2018-10-30)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.3.0...v3.4.0)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.3.0...v3.4.0)
|
||||||
|
|
||||||
- Big uint64\_t values are serialized wrong [\#1327](https://github.com/nlohmann/json/issues/1327)
|
- Big uint64\_t values are serialized wrong [\#1327](https://github.com/nlohmann/json/issues/1327)
|
||||||
|
@ -541,7 +879,6 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- BSON support [\#1244](https://github.com/nlohmann/json/issues/1244)
|
- BSON support [\#1244](https://github.com/nlohmann/json/issues/1244)
|
||||||
- enum to json mapping [\#1208](https://github.com/nlohmann/json/issues/1208)
|
- enum to json mapping [\#1208](https://github.com/nlohmann/json/issues/1208)
|
||||||
- Soften the landing when dumping non-UTF8 strings \(type\_error.316 exception\) [\#1198](https://github.com/nlohmann/json/issues/1198)
|
- Soften the landing when dumping non-UTF8 strings \(type\_error.316 exception\) [\#1198](https://github.com/nlohmann/json/issues/1198)
|
||||||
- CMakeLists.txt in release zips? [\#1184](https://github.com/nlohmann/json/issues/1184)
|
|
||||||
|
|
||||||
- Add macro to define enum/JSON mapping [\#1323](https://github.com/nlohmann/json/pull/1323) ([nlohmann](https://github.com/nlohmann))
|
- Add macro to define enum/JSON mapping [\#1323](https://github.com/nlohmann/json/pull/1323) ([nlohmann](https://github.com/nlohmann))
|
||||||
- Add BSON support [\#1320](https://github.com/nlohmann/json/pull/1320) ([nlohmann](https://github.com/nlohmann))
|
- Add BSON support [\#1320](https://github.com/nlohmann/json/pull/1320) ([nlohmann](https://github.com/nlohmann))
|
||||||
|
@ -556,7 +893,12 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Thirdparty benchmark: Fix Clang detection. [\#1277](https://github.com/nlohmann/json/pull/1277) ([Lord-Kamina](https://github.com/Lord-Kamina))
|
- Thirdparty benchmark: Fix Clang detection. [\#1277](https://github.com/nlohmann/json/pull/1277) ([Lord-Kamina](https://github.com/Lord-Kamina))
|
||||||
|
|
||||||
## [v3.3.0](https://github.com/nlohmann/json/releases/tag/v3.3.0) (2018-10-05)
|
## [v3.3.0](https://github.com/nlohmann/json/releases/tag/v3.3.0) (2018-10-05)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.2.0...v3.3.0)
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/3.3.0...v3.3.0)
|
||||||
|
|
||||||
|
## [3.3.0](https://github.com/nlohmann/json/releases/tag/3.3.0) (2018-10-05)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.2.0...3.3.0)
|
||||||
|
|
||||||
- When key is not found print the key name into error too [\#1273](https://github.com/nlohmann/json/issues/1273)
|
- When key is not found print the key name into error too [\#1273](https://github.com/nlohmann/json/issues/1273)
|
||||||
- Visual Studio 2017 15.8.5 "conditional expression is constant" warning on Line 1851 in json.hpp [\#1268](https://github.com/nlohmann/json/issues/1268)
|
- Visual Studio 2017 15.8.5 "conditional expression is constant" warning on Line 1851 in json.hpp [\#1268](https://github.com/nlohmann/json/issues/1268)
|
||||||
|
@ -574,7 +916,6 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Doesn't compile under C++17 [\#1239](https://github.com/nlohmann/json/issues/1239)
|
- Doesn't compile under C++17 [\#1239](https://github.com/nlohmann/json/issues/1239)
|
||||||
- Conversion operator for nlohmann::json is not SFINAE friendly [\#1237](https://github.com/nlohmann/json/issues/1237)
|
- Conversion operator for nlohmann::json is not SFINAE friendly [\#1237](https://github.com/nlohmann/json/issues/1237)
|
||||||
- Custom deserialization of number\_float\_t [\#1236](https://github.com/nlohmann/json/issues/1236)
|
- Custom deserialization of number\_float\_t [\#1236](https://github.com/nlohmann/json/issues/1236)
|
||||||
- Move tests to a separate repo [\#1235](https://github.com/nlohmann/json/issues/1235)
|
|
||||||
- deprecated-declarations warnings when compiling tests with GCC 8.2.1. [\#1233](https://github.com/nlohmann/json/issues/1233)
|
- deprecated-declarations warnings when compiling tests with GCC 8.2.1. [\#1233](https://github.com/nlohmann/json/issues/1233)
|
||||||
- Incomplete type with json\_fwd.hpp [\#1232](https://github.com/nlohmann/json/issues/1232)
|
- Incomplete type with json\_fwd.hpp [\#1232](https://github.com/nlohmann/json/issues/1232)
|
||||||
- Parse Error [\#1229](https://github.com/nlohmann/json/issues/1229)
|
- Parse Error [\#1229](https://github.com/nlohmann/json/issues/1229)
|
||||||
|
@ -624,7 +965,12 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Export package to allow builds without installing [\#1202](https://github.com/nlohmann/json/pull/1202) ([dennisfischer](https://github.com/dennisfischer))
|
- Export package to allow builds without installing [\#1202](https://github.com/nlohmann/json/pull/1202) ([dennisfischer](https://github.com/dennisfischer))
|
||||||
|
|
||||||
## [v3.2.0](https://github.com/nlohmann/json/releases/tag/v3.2.0) (2018-08-20)
|
## [v3.2.0](https://github.com/nlohmann/json/releases/tag/v3.2.0) (2018-08-20)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.2...v3.2.0)
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/3.2.0...v3.2.0)
|
||||||
|
|
||||||
|
## [3.2.0](https://github.com/nlohmann/json/releases/tag/3.2.0) (2018-08-20)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.2...3.2.0)
|
||||||
|
|
||||||
- Am I doing this wrong? Getting an empty string [\#1199](https://github.com/nlohmann/json/issues/1199)
|
- Am I doing this wrong? Getting an empty string [\#1199](https://github.com/nlohmann/json/issues/1199)
|
||||||
- Incompatible Pointer Type [\#1196](https://github.com/nlohmann/json/issues/1196)
|
- Incompatible Pointer Type [\#1196](https://github.com/nlohmann/json/issues/1196)
|
||||||
|
@ -634,7 +980,6 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Add key name when throwing type error [\#1189](https://github.com/nlohmann/json/issues/1189)
|
- Add key name when throwing type error [\#1189](https://github.com/nlohmann/json/issues/1189)
|
||||||
- Not able to include in visual studio code? [\#1188](https://github.com/nlohmann/json/issues/1188)
|
- Not able to include in visual studio code? [\#1188](https://github.com/nlohmann/json/issues/1188)
|
||||||
- Get an Index or row number of an element [\#1186](https://github.com/nlohmann/json/issues/1186)
|
- Get an Index or row number of an element [\#1186](https://github.com/nlohmann/json/issues/1186)
|
||||||
- reduce repos size [\#1185](https://github.com/nlohmann/json/issues/1185)
|
|
||||||
- Difference between `merge\_patch` and `update` [\#1183](https://github.com/nlohmann/json/issues/1183)
|
- Difference between `merge\_patch` and `update` [\#1183](https://github.com/nlohmann/json/issues/1183)
|
||||||
- Is there a way to get an element from a JSON without throwing an exception on failure? [\#1182](https://github.com/nlohmann/json/issues/1182)
|
- Is there a way to get an element from a JSON without throwing an exception on failure? [\#1182](https://github.com/nlohmann/json/issues/1182)
|
||||||
- to\_string? [\#1181](https://github.com/nlohmann/json/issues/1181)
|
- to\_string? [\#1181](https://github.com/nlohmann/json/issues/1181)
|
||||||
|
@ -723,7 +1068,6 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Deserializing std::array doesn't compiler \(no insert\(\)\) [\#1071](https://github.com/nlohmann/json/issues/1071)
|
- Deserializing std::array doesn't compiler \(no insert\(\)\) [\#1071](https://github.com/nlohmann/json/issues/1071)
|
||||||
- Serializing OpenCV Mat problem [\#1070](https://github.com/nlohmann/json/issues/1070)
|
- Serializing OpenCV Mat problem [\#1070](https://github.com/nlohmann/json/issues/1070)
|
||||||
- Compilation error with ICPC compiler [\#1068](https://github.com/nlohmann/json/issues/1068)
|
- Compilation error with ICPC compiler [\#1068](https://github.com/nlohmann/json/issues/1068)
|
||||||
- Minimal branch? [\#1066](https://github.com/nlohmann/json/issues/1066)
|
|
||||||
- Not existing value, crash [\#1065](https://github.com/nlohmann/json/issues/1065)
|
- Not existing value, crash [\#1065](https://github.com/nlohmann/json/issues/1065)
|
||||||
- cyryllic symbols [\#1064](https://github.com/nlohmann/json/issues/1064)
|
- cyryllic symbols [\#1064](https://github.com/nlohmann/json/issues/1064)
|
||||||
- newbie usage question [\#1063](https://github.com/nlohmann/json/issues/1063)
|
- newbie usage question [\#1063](https://github.com/nlohmann/json/issues/1063)
|
||||||
|
@ -802,7 +1146,12 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Added public target\_compile\_features for auto and constexpr [\#1026](https://github.com/nlohmann/json/pull/1026) ([ktonon](https://github.com/ktonon))
|
- Added public target\_compile\_features for auto and constexpr [\#1026](https://github.com/nlohmann/json/pull/1026) ([ktonon](https://github.com/ktonon))
|
||||||
|
|
||||||
## [v3.1.2](https://github.com/nlohmann/json/releases/tag/v3.1.2) (2018-03-14)
|
## [v3.1.2](https://github.com/nlohmann/json/releases/tag/v3.1.2) (2018-03-14)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.1...v3.1.2)
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/3.1.2...v3.1.2)
|
||||||
|
|
||||||
|
## [3.1.2](https://github.com/nlohmann/json/releases/tag/3.1.2) (2018-03-14)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.1...3.1.2)
|
||||||
|
|
||||||
- STL containers are always serialized to a nested array like \[\[1,2,3\]\] [\#1013](https://github.com/nlohmann/json/issues/1013)
|
- STL containers are always serialized to a nested array like \[\[1,2,3\]\] [\#1013](https://github.com/nlohmann/json/issues/1013)
|
||||||
- The library doesn't want to insert an unordered\_map [\#1010](https://github.com/nlohmann/json/issues/1010)
|
- The library doesn't want to insert an unordered\_map [\#1010](https://github.com/nlohmann/json/issues/1010)
|
||||||
|
@ -833,12 +1182,12 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
|
|
||||||
- Allowing for user-defined string type in lexer/parser [\#1009](https://github.com/nlohmann/json/pull/1009) ([nlohmann](https://github.com/nlohmann))
|
- Allowing for user-defined string type in lexer/parser [\#1009](https://github.com/nlohmann/json/pull/1009) ([nlohmann](https://github.com/nlohmann))
|
||||||
- dump to alternative string type, as defined in basic\_json template [\#1006](https://github.com/nlohmann/json/pull/1006) ([agrianius](https://github.com/agrianius))
|
- dump to alternative string type, as defined in basic\_json template [\#1006](https://github.com/nlohmann/json/pull/1006) ([agrianius](https://github.com/agrianius))
|
||||||
- Fix memory leak during parser callback [\#1001](https://github.com/nlohmann/json/pull/1001) ([nlohmann](https://github.com/nlohmann))
|
|
||||||
- fixed misprinted condition detected by PVS Studio. [\#992](https://github.com/nlohmann/json/pull/992) ([bogemic](https://github.com/bogemic))
|
- fixed misprinted condition detected by PVS Studio. [\#992](https://github.com/nlohmann/json/pull/992) ([bogemic](https://github.com/bogemic))
|
||||||
- Fix/basic json conversion [\#986](https://github.com/nlohmann/json/pull/986) ([theodelrieu](https://github.com/theodelrieu))
|
- Fix/basic json conversion [\#986](https://github.com/nlohmann/json/pull/986) ([theodelrieu](https://github.com/theodelrieu))
|
||||||
- Make integration section concise [\#981](https://github.com/nlohmann/json/pull/981) ([wla80](https://github.com/wla80))
|
- Make integration section concise [\#981](https://github.com/nlohmann/json/pull/981) ([wla80](https://github.com/wla80))
|
||||||
|
|
||||||
## [v3.1.1](https://github.com/nlohmann/json/releases/tag/v3.1.1) (2018-02-13)
|
## [v3.1.1](https://github.com/nlohmann/json/releases/tag/v3.1.1) (2018-02-13)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.0...v3.1.1)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.0...v3.1.1)
|
||||||
|
|
||||||
- Updation of child object isn't reflected in parent Object [\#968](https://github.com/nlohmann/json/issues/968)
|
- Updation of child object isn't reflected in parent Object [\#968](https://github.com/nlohmann/json/issues/968)
|
||||||
|
@ -856,13 +1205,19 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- \[Request\] Macro generating from\_json\(\) and to\_json\(\) [\#895](https://github.com/nlohmann/json/issues/895)
|
- \[Request\] Macro generating from\_json\(\) and to\_json\(\) [\#895](https://github.com/nlohmann/json/issues/895)
|
||||||
- basic\_json::value throws exception instead of returning default value [\#871](https://github.com/nlohmann/json/issues/871)
|
- basic\_json::value throws exception instead of returning default value [\#871](https://github.com/nlohmann/json/issues/871)
|
||||||
|
|
||||||
|
- Fix memory leak during parser callback [\#1001](https://github.com/nlohmann/json/pull/1001) ([nlohmann](https://github.com/nlohmann))
|
||||||
- Fix constraints on from\_json\(CompatibleArrayType\) [\#969](https://github.com/nlohmann/json/pull/969) ([theodelrieu](https://github.com/theodelrieu))
|
- Fix constraints on from\_json\(CompatibleArrayType\) [\#969](https://github.com/nlohmann/json/pull/969) ([theodelrieu](https://github.com/theodelrieu))
|
||||||
- Make coveralls watch the include folder [\#957](https://github.com/nlohmann/json/pull/957) ([theodelrieu](https://github.com/theodelrieu))
|
- Make coveralls watch the include folder [\#957](https://github.com/nlohmann/json/pull/957) ([theodelrieu](https://github.com/theodelrieu))
|
||||||
- Fix links in README.md [\#955](https://github.com/nlohmann/json/pull/955) ([patrikhuber](https://github.com/patrikhuber))
|
- Fix links in README.md [\#955](https://github.com/nlohmann/json/pull/955) ([patrikhuber](https://github.com/patrikhuber))
|
||||||
- Add a note about installing the library with cget [\#954](https://github.com/nlohmann/json/pull/954) ([pfultz2](https://github.com/pfultz2))
|
- Add a note about installing the library with cget [\#954](https://github.com/nlohmann/json/pull/954) ([pfultz2](https://github.com/pfultz2))
|
||||||
|
|
||||||
## [v3.1.0](https://github.com/nlohmann/json/releases/tag/v3.1.0) (2018-02-01)
|
## [v3.1.0](https://github.com/nlohmann/json/releases/tag/v3.1.0) (2018-02-01)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.0.1...v3.1.0)
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/3.1.0...v3.1.0)
|
||||||
|
|
||||||
|
## [3.1.0](https://github.com/nlohmann/json/releases/tag/3.1.0) (2018-02-01)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.0.1...3.1.0)
|
||||||
|
|
||||||
- Order of the elements in JSON object [\#952](https://github.com/nlohmann/json/issues/952)
|
- Order of the elements in JSON object [\#952](https://github.com/nlohmann/json/issues/952)
|
||||||
- I have a proposal [\#949](https://github.com/nlohmann/json/issues/949)
|
- I have a proposal [\#949](https://github.com/nlohmann/json/issues/949)
|
||||||
|
@ -925,7 +1280,12 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Refactor/split it [\#700](https://github.com/nlohmann/json/pull/700) ([theodelrieu](https://github.com/theodelrieu))
|
- Refactor/split it [\#700](https://github.com/nlohmann/json/pull/700) ([theodelrieu](https://github.com/theodelrieu))
|
||||||
|
|
||||||
## [v3.0.1](https://github.com/nlohmann/json/releases/tag/v3.0.1) (2017-12-29)
|
## [v3.0.1](https://github.com/nlohmann/json/releases/tag/v3.0.1) (2017-12-29)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.0.0...v3.0.1)
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/3.0.1...v3.0.1)
|
||||||
|
|
||||||
|
## [3.0.1](https://github.com/nlohmann/json/releases/tag/3.0.1) (2017-12-29)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.0.0...3.0.1)
|
||||||
|
|
||||||
- Problem parsing array to global vector [\#896](https://github.com/nlohmann/json/issues/896)
|
- Problem parsing array to global vector [\#896](https://github.com/nlohmann/json/issues/896)
|
||||||
- Invalid RFC6902 copy operation succeeds [\#894](https://github.com/nlohmann/json/issues/894)
|
- Invalid RFC6902 copy operation succeeds [\#894](https://github.com/nlohmann/json/issues/894)
|
||||||
|
@ -948,7 +1308,12 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- :wrench: Fix up a few more effc++ items [\#858](https://github.com/nlohmann/json/pull/858) ([mattismyname](https://github.com/mattismyname))
|
- :wrench: Fix up a few more effc++ items [\#858](https://github.com/nlohmann/json/pull/858) ([mattismyname](https://github.com/mattismyname))
|
||||||
|
|
||||||
## [v3.0.0](https://github.com/nlohmann/json/releases/tag/v3.0.0) (2017-12-17)
|
## [v3.0.0](https://github.com/nlohmann/json/releases/tag/v3.0.0) (2017-12-17)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.1.1...v3.0.0)
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/3.0.0...v3.0.0)
|
||||||
|
|
||||||
|
## [3.0.0](https://github.com/nlohmann/json/releases/tag/3.0.0) (2017-12-17)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.1.1...3.0.0)
|
||||||
|
|
||||||
- unicode strings [\#878](https://github.com/nlohmann/json/issues/878)
|
- unicode strings [\#878](https://github.com/nlohmann/json/issues/878)
|
||||||
- Visual Studio 2017 15.5 C++17 std::allocator deprecations [\#872](https://github.com/nlohmann/json/issues/872)
|
- Visual Studio 2017 15.5 C++17 std::allocator deprecations [\#872](https://github.com/nlohmann/json/issues/872)
|
||||||
|
@ -1052,7 +1417,6 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Compilation Error on Clang 5.0 Upgrade [\#735](https://github.com/nlohmann/json/issues/735)
|
- Compilation Error on Clang 5.0 Upgrade [\#735](https://github.com/nlohmann/json/issues/735)
|
||||||
- Compilation error with std::map\<std::string, std::string\> on vs 2015 [\#734](https://github.com/nlohmann/json/issues/734)
|
- Compilation error with std::map\<std::string, std::string\> on vs 2015 [\#734](https://github.com/nlohmann/json/issues/734)
|
||||||
- Benchmarks for Binary formats [\#733](https://github.com/nlohmann/json/issues/733)
|
- Benchmarks for Binary formats [\#733](https://github.com/nlohmann/json/issues/733)
|
||||||
- Move test blobs to a submodule? [\#732](https://github.com/nlohmann/json/issues/732)
|
|
||||||
- Support \n symbols in json string. [\#731](https://github.com/nlohmann/json/issues/731)
|
- Support \n symbols in json string. [\#731](https://github.com/nlohmann/json/issues/731)
|
||||||
- Project's name is too generic and hard to search for [\#730](https://github.com/nlohmann/json/issues/730)
|
- Project's name is too generic and hard to search for [\#730](https://github.com/nlohmann/json/issues/730)
|
||||||
- Visual Studio 2015 IntelliTrace problems [\#729](https://github.com/nlohmann/json/issues/729)
|
- Visual Studio 2015 IntelliTrace problems [\#729](https://github.com/nlohmann/json/issues/729)
|
||||||
|
@ -1137,7 +1501,6 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Discussion: How to structure the parsing function families [\#623](https://github.com/nlohmann/json/issues/623)
|
- Discussion: How to structure the parsing function families [\#623](https://github.com/nlohmann/json/issues/623)
|
||||||
- Question: How to erase subtree [\#622](https://github.com/nlohmann/json/issues/622)
|
- Question: How to erase subtree [\#622](https://github.com/nlohmann/json/issues/622)
|
||||||
- Insertion into nested json field [\#621](https://github.com/nlohmann/json/issues/621)
|
- Insertion into nested json field [\#621](https://github.com/nlohmann/json/issues/621)
|
||||||
- \[Question\] When using this as git submodule, will it clone the whole thing include test data and benchmark? [\#620](https://github.com/nlohmann/json/issues/620)
|
|
||||||
- Question: return static json object from function [\#618](https://github.com/nlohmann/json/issues/618)
|
- Question: return static json object from function [\#618](https://github.com/nlohmann/json/issues/618)
|
||||||
- icc16 error [\#617](https://github.com/nlohmann/json/issues/617)
|
- icc16 error [\#617](https://github.com/nlohmann/json/issues/617)
|
||||||
- \[-Wdeprecated-declarations\] in row `j \>\> ss;` in file `json.hpp:7405:26` and FAILED unit tests with MinGWx64! [\#616](https://github.com/nlohmann/json/issues/616)
|
- \[-Wdeprecated-declarations\] in row `j \>\> ss;` in file `json.hpp:7405:26` and FAILED unit tests with MinGWx64! [\#616](https://github.com/nlohmann/json/issues/616)
|
||||||
|
@ -1179,7 +1542,6 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Request: Object.at\(\) with default return value [\#570](https://github.com/nlohmann/json/issues/570)
|
- Request: Object.at\(\) with default return value [\#570](https://github.com/nlohmann/json/issues/570)
|
||||||
- Internal structure gets corrupted while parsing [\#569](https://github.com/nlohmann/json/issues/569)
|
- Internal structure gets corrupted while parsing [\#569](https://github.com/nlohmann/json/issues/569)
|
||||||
- create template \<typename Iter\> basic\_json from\_cbor\(Iter begin, Iter end\) [\#568](https://github.com/nlohmann/json/issues/568)
|
- create template \<typename Iter\> basic\_json from\_cbor\(Iter begin, Iter end\) [\#568](https://github.com/nlohmann/json/issues/568)
|
||||||
- Need to improve ignores.. [\#567](https://github.com/nlohmann/json/issues/567)
|
|
||||||
- Conan.io [\#566](https://github.com/nlohmann/json/issues/566)
|
- Conan.io [\#566](https://github.com/nlohmann/json/issues/566)
|
||||||
- contradictory documentation regarding json::find [\#565](https://github.com/nlohmann/json/issues/565)
|
- contradictory documentation regarding json::find [\#565](https://github.com/nlohmann/json/issues/565)
|
||||||
- Unexpected '\"' in middle of array [\#564](https://github.com/nlohmann/json/issues/564)
|
- Unexpected '\"' in middle of array [\#564](https://github.com/nlohmann/json/issues/564)
|
||||||
|
@ -1189,7 +1551,6 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Tip: Don't upgrade to VS2017 if using json initializer list constructs [\#559](https://github.com/nlohmann/json/issues/559)
|
- Tip: Don't upgrade to VS2017 if using json initializer list constructs [\#559](https://github.com/nlohmann/json/issues/559)
|
||||||
- parse error - unexpected end of input [\#558](https://github.com/nlohmann/json/issues/558)
|
- parse error - unexpected end of input [\#558](https://github.com/nlohmann/json/issues/558)
|
||||||
- Cant modify existing numbers inside a json object [\#557](https://github.com/nlohmann/json/issues/557)
|
- Cant modify existing numbers inside a json object [\#557](https://github.com/nlohmann/json/issues/557)
|
||||||
- Minimal repository \(current size very large\) [\#556](https://github.com/nlohmann/json/issues/556)
|
|
||||||
- Better support for SAX style serialize and deserialize in new version? [\#554](https://github.com/nlohmann/json/issues/554)
|
- Better support for SAX style serialize and deserialize in new version? [\#554](https://github.com/nlohmann/json/issues/554)
|
||||||
- Cannot convert from json array to std::array [\#553](https://github.com/nlohmann/json/issues/553)
|
- Cannot convert from json array to std::array [\#553](https://github.com/nlohmann/json/issues/553)
|
||||||
- Do not define an unnamed namespace in a header file \(DCL59-CPP\) [\#552](https://github.com/nlohmann/json/issues/552)
|
- Do not define an unnamed namespace in a header file \(DCL59-CPP\) [\#552](https://github.com/nlohmann/json/issues/552)
|
||||||
|
@ -1250,7 +1611,6 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Using fifo\_map [\#485](https://github.com/nlohmann/json/issues/485)
|
- Using fifo\_map [\#485](https://github.com/nlohmann/json/issues/485)
|
||||||
- Cannot get float pointer for value stored as `0` [\#484](https://github.com/nlohmann/json/issues/484)
|
- Cannot get float pointer for value stored as `0` [\#484](https://github.com/nlohmann/json/issues/484)
|
||||||
- byte string support [\#483](https://github.com/nlohmann/json/issues/483)
|
- byte string support [\#483](https://github.com/nlohmann/json/issues/483)
|
||||||
- For a header-only library you have to clone 214MB [\#482](https://github.com/nlohmann/json/issues/482)
|
|
||||||
- https://github.com/nlohmann/json\#execute-unit-tests [\#481](https://github.com/nlohmann/json/issues/481)
|
- https://github.com/nlohmann/json\#execute-unit-tests [\#481](https://github.com/nlohmann/json/issues/481)
|
||||||
- Remove deprecated constructor basic\_json\(std::istream&\) [\#480](https://github.com/nlohmann/json/issues/480)
|
- Remove deprecated constructor basic\_json\(std::istream&\) [\#480](https://github.com/nlohmann/json/issues/480)
|
||||||
- writing the binary json file? [\#479](https://github.com/nlohmann/json/issues/479)
|
- writing the binary json file? [\#479](https://github.com/nlohmann/json/issues/479)
|
||||||
|
@ -1311,38 +1671,14 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Digraph warning [\#679](https://github.com/nlohmann/json/pull/679) ([traits](https://github.com/traits))
|
- Digraph warning [\#679](https://github.com/nlohmann/json/pull/679) ([traits](https://github.com/traits))
|
||||||
- massage -\> message [\#678](https://github.com/nlohmann/json/pull/678) ([DmitryKuk](https://github.com/DmitryKuk))
|
- massage -\> message [\#678](https://github.com/nlohmann/json/pull/678) ([DmitryKuk](https://github.com/DmitryKuk))
|
||||||
- Fix "not constraint" grammar in docs [\#674](https://github.com/nlohmann/json/pull/674) ([wincent](https://github.com/wincent))
|
- Fix "not constraint" grammar in docs [\#674](https://github.com/nlohmann/json/pull/674) ([wincent](https://github.com/wincent))
|
||||||
- Add documentation for integration with CMake and hunter [\#671](https://github.com/nlohmann/json/pull/671) ([dan-42](https://github.com/dan-42))
|
|
||||||
- REFACTOR: rewrite CMakeLists.txt for better inlcude and reuse [\#669](https://github.com/nlohmann/json/pull/669) ([dan-42](https://github.com/dan-42))
|
|
||||||
- enable\_testing only if the JSON\_BuildTests is ON [\#666](https://github.com/nlohmann/json/pull/666) ([effolkronium](https://github.com/effolkronium))
|
|
||||||
- Support moving from rvalues in std::initializer\_list [\#663](https://github.com/nlohmann/json/pull/663) ([himikof](https://github.com/himikof))
|
|
||||||
- add ensure\_ascii parameter to dump. \#330 [\#654](https://github.com/nlohmann/json/pull/654) ([ryanjmulder](https://github.com/ryanjmulder))
|
|
||||||
- Rename BuildTests to JSON\_BuildTests [\#652](https://github.com/nlohmann/json/pull/652) ([olegendo](https://github.com/olegendo))
|
|
||||||
- Don't include \<iostream\>, use std::make\_shared [\#650](https://github.com/nlohmann/json/pull/650) ([olegendo](https://github.com/olegendo))
|
|
||||||
- Refacto/split basic json [\#643](https://github.com/nlohmann/json/pull/643) ([theodelrieu](https://github.com/theodelrieu))
|
|
||||||
- fix typo in operator\_\_notequal example [\#630](https://github.com/nlohmann/json/pull/630) ([Chocobo1](https://github.com/Chocobo1))
|
|
||||||
- Fix MSVC warning C4819 [\#629](https://github.com/nlohmann/json/pull/629) ([Chocobo1](https://github.com/Chocobo1))
|
|
||||||
- \[BugFix\] Add parentheses around std::min [\#626](https://github.com/nlohmann/json/pull/626) ([koemeet](https://github.com/koemeet))
|
|
||||||
- add pair/tuple conversions [\#624](https://github.com/nlohmann/json/pull/624) ([theodelrieu](https://github.com/theodelrieu))
|
|
||||||
- remove std::pair support [\#615](https://github.com/nlohmann/json/pull/615) ([theodelrieu](https://github.com/theodelrieu))
|
|
||||||
- Add pair support, fix CompatibleObject conversions \(fixes \#600\) [\#609](https://github.com/nlohmann/json/pull/609) ([theodelrieu](https://github.com/theodelrieu))
|
|
||||||
- \#550 Fix iterator related compiling issues for Intel icc [\#598](https://github.com/nlohmann/json/pull/598) ([HenryRLee](https://github.com/HenryRLee))
|
|
||||||
- Issue \#593 Fix the arithmetic operators in the iterator and reverse iterator [\#595](https://github.com/nlohmann/json/pull/595) ([HenryRLee](https://github.com/HenryRLee))
|
|
||||||
- fix doxygen error of basic\_json::get\(\) [\#583](https://github.com/nlohmann/json/pull/583) ([zhaohuaxishi](https://github.com/zhaohuaxishi))
|
|
||||||
- Fixing assignement for iterator wrapper second, and adding unit test [\#579](https://github.com/nlohmann/json/pull/579) ([Type1J](https://github.com/Type1J))
|
|
||||||
- Adding first and second properties to iteration\_proxy\_internal [\#578](https://github.com/nlohmann/json/pull/578) ([Type1J](https://github.com/Type1J))
|
|
||||||
- Adding support for Meson. [\#576](https://github.com/nlohmann/json/pull/576) ([Type1J](https://github.com/Type1J))
|
|
||||||
- add enum class default conversions [\#545](https://github.com/nlohmann/json/pull/545) ([theodelrieu](https://github.com/theodelrieu))
|
|
||||||
- Properly pop diagnostics [\#540](https://github.com/nlohmann/json/pull/540) ([tinloaf](https://github.com/tinloaf))
|
|
||||||
- Add Visual Studio 17 image to appveyor build matrix [\#536](https://github.com/nlohmann/json/pull/536) ([vpetrigo](https://github.com/vpetrigo))
|
|
||||||
- UTF8 encoding enhancement [\#534](https://github.com/nlohmann/json/pull/534) ([TedLyngmo](https://github.com/TedLyngmo))
|
|
||||||
- Fix typo [\#530](https://github.com/nlohmann/json/pull/530) ([berkus](https://github.com/berkus))
|
|
||||||
- Make exception base class visible in basic\_json [\#526](https://github.com/nlohmann/json/pull/526) ([krzysztofwos](https://github.com/krzysztofwos))
|
|
||||||
- :art: Namespace `uint8\_t` from the C++ stdlib [\#510](https://github.com/nlohmann/json/pull/510) ([alex-weej](https://github.com/alex-weej))
|
|
||||||
- add to\_json method for C arrays [\#508](https://github.com/nlohmann/json/pull/508) ([theodelrieu](https://github.com/theodelrieu))
|
|
||||||
- Fix -Weffc++ warnings \(GNU 6.3.1\) [\#496](https://github.com/nlohmann/json/pull/496) ([TedLyngmo](https://github.com/TedLyngmo))
|
|
||||||
|
|
||||||
## [v2.1.1](https://github.com/nlohmann/json/releases/tag/v2.1.1) (2017-02-25)
|
## [v2.1.1](https://github.com/nlohmann/json/releases/tag/v2.1.1) (2017-02-25)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.1.0...v2.1.1)
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/2.1.1...v2.1.1)
|
||||||
|
|
||||||
|
## [2.1.1](https://github.com/nlohmann/json/releases/tag/2.1.1) (2017-02-25)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.1.0...2.1.1)
|
||||||
|
|
||||||
- warning in the library [\#472](https://github.com/nlohmann/json/issues/472)
|
- warning in the library [\#472](https://github.com/nlohmann/json/issues/472)
|
||||||
- How to create an array of Objects? [\#470](https://github.com/nlohmann/json/issues/470)
|
- How to create an array of Objects? [\#470](https://github.com/nlohmann/json/issues/470)
|
||||||
|
@ -1374,9 +1710,15 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- TurpentineDistillery feature/locale independent str to num [\#450](https://github.com/nlohmann/json/pull/450) ([nlohmann](https://github.com/nlohmann))
|
- TurpentineDistillery feature/locale independent str to num [\#450](https://github.com/nlohmann/json/pull/450) ([nlohmann](https://github.com/nlohmann))
|
||||||
- README: adjust boost::optional example [\#439](https://github.com/nlohmann/json/pull/439) ([jaredgrubb](https://github.com/jaredgrubb))
|
- README: adjust boost::optional example [\#439](https://github.com/nlohmann/json/pull/439) ([jaredgrubb](https://github.com/jaredgrubb))
|
||||||
- fix \#414 - comparing to 0 literal [\#415](https://github.com/nlohmann/json/pull/415) ([stanmihai4](https://github.com/stanmihai4))
|
- fix \#414 - comparing to 0 literal [\#415](https://github.com/nlohmann/json/pull/415) ([stanmihai4](https://github.com/stanmihai4))
|
||||||
|
- locale-independent num-to-str [\#378](https://github.com/nlohmann/json/pull/378) ([TurpentineDistillery](https://github.com/TurpentineDistillery))
|
||||||
|
|
||||||
## [v2.1.0](https://github.com/nlohmann/json/releases/tag/v2.1.0) (2017-01-28)
|
## [v2.1.0](https://github.com/nlohmann/json/releases/tag/v2.1.0) (2017-01-28)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.10...v2.1.0)
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/2.1.0...v2.1.0)
|
||||||
|
|
||||||
|
## [2.1.0](https://github.com/nlohmann/json/releases/tag/2.1.0) (2017-01-28)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.10...2.1.0)
|
||||||
|
|
||||||
- Parsing multiple JSON objects from a string or stream [\#438](https://github.com/nlohmann/json/issues/438)
|
- Parsing multiple JSON objects from a string or stream [\#438](https://github.com/nlohmann/json/issues/438)
|
||||||
- Use-of-uninitialized-value \(OSS-Fuzz issue 477\) [\#437](https://github.com/nlohmann/json/issues/437)
|
- Use-of-uninitialized-value \(OSS-Fuzz issue 477\) [\#437](https://github.com/nlohmann/json/issues/437)
|
||||||
|
@ -1397,6 +1739,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- comparing to 0 literal [\#414](https://github.com/nlohmann/json/issues/414)
|
- comparing to 0 literal [\#414](https://github.com/nlohmann/json/issues/414)
|
||||||
- Single char converted to ASCII code instead of string [\#413](https://github.com/nlohmann/json/issues/413)
|
- Single char converted to ASCII code instead of string [\#413](https://github.com/nlohmann/json/issues/413)
|
||||||
- How to know if a string was parsed as utf-8? [\#406](https://github.com/nlohmann/json/issues/406)
|
- How to know if a string was parsed as utf-8? [\#406](https://github.com/nlohmann/json/issues/406)
|
||||||
|
- Heap-buffer-overflow \(OSS-Fuzz issue 342\) [\#405](https://github.com/nlohmann/json/issues/405)
|
||||||
- Overloaded += to add objects to an array makes no sense? [\#404](https://github.com/nlohmann/json/issues/404)
|
- Overloaded += to add objects to an array makes no sense? [\#404](https://github.com/nlohmann/json/issues/404)
|
||||||
- Finding a value in an array [\#399](https://github.com/nlohmann/json/issues/399)
|
- Finding a value in an array [\#399](https://github.com/nlohmann/json/issues/399)
|
||||||
- add release information in static function [\#397](https://github.com/nlohmann/json/issues/397)
|
- add release information in static function [\#397](https://github.com/nlohmann/json/issues/397)
|
||||||
|
@ -1412,17 +1755,20 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
|
|
||||||
- conversion from/to user-defined types [\#435](https://github.com/nlohmann/json/pull/435) ([nlohmann](https://github.com/nlohmann))
|
- conversion from/to user-defined types [\#435](https://github.com/nlohmann/json/pull/435) ([nlohmann](https://github.com/nlohmann))
|
||||||
- Fix documentation error [\#430](https://github.com/nlohmann/json/pull/430) ([vjon](https://github.com/vjon))
|
- Fix documentation error [\#430](https://github.com/nlohmann/json/pull/430) ([vjon](https://github.com/vjon))
|
||||||
- locale-independent num-to-str [\#378](https://github.com/nlohmann/json/pull/378) ([TurpentineDistillery](https://github.com/TurpentineDistillery))
|
|
||||||
|
|
||||||
## [v2.0.10](https://github.com/nlohmann/json/releases/tag/v2.0.10) (2017-01-02)
|
## [v2.0.10](https://github.com/nlohmann/json/releases/tag/v2.0.10) (2017-01-02)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.9...v2.0.10)
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/2.0.10...v2.0.10)
|
||||||
|
|
||||||
|
## [2.0.10](https://github.com/nlohmann/json/releases/tag/2.0.10) (2017-01-02)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.9...2.0.10)
|
||||||
|
|
||||||
- Heap-buffer-overflow \(OSS-Fuzz issue 367\) [\#412](https://github.com/nlohmann/json/issues/412)
|
- Heap-buffer-overflow \(OSS-Fuzz issue 367\) [\#412](https://github.com/nlohmann/json/issues/412)
|
||||||
- Heap-buffer-overflow \(OSS-Fuzz issue 366\) [\#411](https://github.com/nlohmann/json/issues/411)
|
- Heap-buffer-overflow \(OSS-Fuzz issue 366\) [\#411](https://github.com/nlohmann/json/issues/411)
|
||||||
- Use-of-uninitialized-value \(OSS-Fuzz issue 347\) [\#409](https://github.com/nlohmann/json/issues/409)
|
- Use-of-uninitialized-value \(OSS-Fuzz issue 347\) [\#409](https://github.com/nlohmann/json/issues/409)
|
||||||
- Heap-buffer-overflow \(OSS-Fuzz issue 344\) [\#408](https://github.com/nlohmann/json/issues/408)
|
- Heap-buffer-overflow \(OSS-Fuzz issue 344\) [\#408](https://github.com/nlohmann/json/issues/408)
|
||||||
- Heap-buffer-overflow \(OSS-Fuzz issue 343\) [\#407](https://github.com/nlohmann/json/issues/407)
|
- Heap-buffer-overflow \(OSS-Fuzz issue 343\) [\#407](https://github.com/nlohmann/json/issues/407)
|
||||||
- Heap-buffer-overflow \(OSS-Fuzz issue 342\) [\#405](https://github.com/nlohmann/json/issues/405)
|
|
||||||
- strerror throwing error in compiler VS2015 [\#403](https://github.com/nlohmann/json/issues/403)
|
- strerror throwing error in compiler VS2015 [\#403](https://github.com/nlohmann/json/issues/403)
|
||||||
- json::parse of std::string being underlined by Visual Studio [\#402](https://github.com/nlohmann/json/issues/402)
|
- json::parse of std::string being underlined by Visual Studio [\#402](https://github.com/nlohmann/json/issues/402)
|
||||||
- Explicitly getting string without .dump\(\) [\#401](https://github.com/nlohmann/json/issues/401)
|
- Explicitly getting string without .dump\(\) [\#401](https://github.com/nlohmann/json/issues/401)
|
||||||
|
@ -1435,7 +1781,12 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Add Doozer build badge [\#400](https://github.com/nlohmann/json/pull/400) ([andoma](https://github.com/andoma))
|
- Add Doozer build badge [\#400](https://github.com/nlohmann/json/pull/400) ([andoma](https://github.com/andoma))
|
||||||
|
|
||||||
## [v2.0.9](https://github.com/nlohmann/json/releases/tag/v2.0.9) (2016-12-16)
|
## [v2.0.9](https://github.com/nlohmann/json/releases/tag/v2.0.9) (2016-12-16)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.8...v2.0.9)
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/2.0.9...v2.0.9)
|
||||||
|
|
||||||
|
## [2.0.9](https://github.com/nlohmann/json/releases/tag/2.0.9) (2016-12-16)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.8...2.0.9)
|
||||||
|
|
||||||
- \#pragma GCC diagnostic ignored "-Wdocumentation" [\#393](https://github.com/nlohmann/json/issues/393)
|
- \#pragma GCC diagnostic ignored "-Wdocumentation" [\#393](https://github.com/nlohmann/json/issues/393)
|
||||||
- How to parse this json file and write separate sub object as json files? [\#392](https://github.com/nlohmann/json/issues/392)
|
- How to parse this json file and write separate sub object as json files? [\#392](https://github.com/nlohmann/json/issues/392)
|
||||||
|
@ -1458,7 +1809,12 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Fix issue \#380: Signed integer overflow check [\#390](https://github.com/nlohmann/json/pull/390) ([qwename](https://github.com/qwename))
|
- Fix issue \#380: Signed integer overflow check [\#390](https://github.com/nlohmann/json/pull/390) ([qwename](https://github.com/qwename))
|
||||||
|
|
||||||
## [v2.0.8](https://github.com/nlohmann/json/releases/tag/v2.0.8) (2016-12-02)
|
## [v2.0.8](https://github.com/nlohmann/json/releases/tag/v2.0.8) (2016-12-02)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.7...v2.0.8)
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/2.0.8...v2.0.8)
|
||||||
|
|
||||||
|
## [2.0.8](https://github.com/nlohmann/json/releases/tag/2.0.8) (2016-12-02)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.7...2.0.8)
|
||||||
|
|
||||||
- Reading from file [\#374](https://github.com/nlohmann/json/issues/374)
|
- Reading from file [\#374](https://github.com/nlohmann/json/issues/374)
|
||||||
- Compiler warnings? [\#372](https://github.com/nlohmann/json/issues/372)
|
- Compiler warnings? [\#372](https://github.com/nlohmann/json/issues/372)
|
||||||
|
@ -1485,6 +1841,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Using QString as string type [\#274](https://github.com/nlohmann/json/issues/274)
|
- Using QString as string type [\#274](https://github.com/nlohmann/json/issues/274)
|
||||||
|
|
||||||
## [v2.0.7](https://github.com/nlohmann/json/releases/tag/v2.0.7) (2016-11-02)
|
## [v2.0.7](https://github.com/nlohmann/json/releases/tag/v2.0.7) (2016-11-02)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.6...v2.0.7)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.6...v2.0.7)
|
||||||
|
|
||||||
- JSON5 [\#348](https://github.com/nlohmann/json/issues/348)
|
- JSON5 [\#348](https://github.com/nlohmann/json/issues/348)
|
||||||
|
@ -1504,6 +1861,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- fix minor grammar/style issue in README.md [\#336](https://github.com/nlohmann/json/pull/336) ([seeekr](https://github.com/seeekr))
|
- fix minor grammar/style issue in README.md [\#336](https://github.com/nlohmann/json/pull/336) ([seeekr](https://github.com/seeekr))
|
||||||
|
|
||||||
## [v2.0.6](https://github.com/nlohmann/json/releases/tag/v2.0.6) (2016-10-15)
|
## [v2.0.6](https://github.com/nlohmann/json/releases/tag/v2.0.6) (2016-10-15)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.5...v2.0.6)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.5...v2.0.6)
|
||||||
|
|
||||||
- How to handle json files? [\#333](https://github.com/nlohmann/json/issues/333)
|
- How to handle json files? [\#333](https://github.com/nlohmann/json/issues/333)
|
||||||
|
@ -1523,6 +1881,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- trivial documentation fix [\#313](https://github.com/nlohmann/json/pull/313) ([5tefan](https://github.com/5tefan))
|
- trivial documentation fix [\#313](https://github.com/nlohmann/json/pull/313) ([5tefan](https://github.com/5tefan))
|
||||||
|
|
||||||
## [v2.0.5](https://github.com/nlohmann/json/releases/tag/v2.0.5) (2016-09-14)
|
## [v2.0.5](https://github.com/nlohmann/json/releases/tag/v2.0.5) (2016-09-14)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.4...v2.0.5)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.4...v2.0.5)
|
||||||
|
|
||||||
- \[feature request\]: schema validator and comments [\#311](https://github.com/nlohmann/json/issues/311)
|
- \[feature request\]: schema validator and comments [\#311](https://github.com/nlohmann/json/issues/311)
|
||||||
|
@ -1531,6 +1890,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- No matching member function for call to 'get\_impl' [\#308](https://github.com/nlohmann/json/issues/308)
|
- No matching member function for call to 'get\_impl' [\#308](https://github.com/nlohmann/json/issues/308)
|
||||||
|
|
||||||
## [v2.0.4](https://github.com/nlohmann/json/releases/tag/v2.0.4) (2016-09-11)
|
## [v2.0.4](https://github.com/nlohmann/json/releases/tag/v2.0.4) (2016-09-11)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.3...v2.0.4)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.3...v2.0.4)
|
||||||
|
|
||||||
- Parsing fails without space at end of file [\#306](https://github.com/nlohmann/json/issues/306)
|
- Parsing fails without space at end of file [\#306](https://github.com/nlohmann/json/issues/306)
|
||||||
|
@ -1538,6 +1898,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Unused variable warning [\#304](https://github.com/nlohmann/json/issues/304)
|
- Unused variable warning [\#304](https://github.com/nlohmann/json/issues/304)
|
||||||
|
|
||||||
## [v2.0.3](https://github.com/nlohmann/json/releases/tag/v2.0.3) (2016-08-31)
|
## [v2.0.3](https://github.com/nlohmann/json/releases/tag/v2.0.3) (2016-08-31)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.2...v2.0.3)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.2...v2.0.3)
|
||||||
|
|
||||||
- warning C4706: assignment within conditional expression [\#295](https://github.com/nlohmann/json/issues/295)
|
- warning C4706: assignment within conditional expression [\#295](https://github.com/nlohmann/json/issues/295)
|
||||||
|
@ -1554,6 +1915,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- unit-constructor1.cpp: Fix floating point truncation warning [\#300](https://github.com/nlohmann/json/pull/300) ([t-b](https://github.com/t-b))
|
- unit-constructor1.cpp: Fix floating point truncation warning [\#300](https://github.com/nlohmann/json/pull/300) ([t-b](https://github.com/t-b))
|
||||||
|
|
||||||
## [v2.0.2](https://github.com/nlohmann/json/releases/tag/v2.0.2) (2016-07-31)
|
## [v2.0.2](https://github.com/nlohmann/json/releases/tag/v2.0.2) (2016-07-31)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.1...v2.0.2)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.1...v2.0.2)
|
||||||
|
|
||||||
- can function dump\(\) return string in the order I push in the json object ? [\#286](https://github.com/nlohmann/json/issues/286)
|
- can function dump\(\) return string in the order I push in the json object ? [\#286](https://github.com/nlohmann/json/issues/286)
|
||||||
|
@ -1569,6 +1931,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Update hexify to use array lookup instead of ternary \(\#270\) [\#275](https://github.com/nlohmann/json/pull/275) ([dtoma](https://github.com/dtoma))
|
- Update hexify to use array lookup instead of ternary \(\#270\) [\#275](https://github.com/nlohmann/json/pull/275) ([dtoma](https://github.com/dtoma))
|
||||||
|
|
||||||
## [v2.0.1](https://github.com/nlohmann/json/releases/tag/v2.0.1) (2016-06-28)
|
## [v2.0.1](https://github.com/nlohmann/json/releases/tag/v2.0.1) (2016-06-28)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.0...v2.0.1)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.0...v2.0.1)
|
||||||
|
|
||||||
- Compilation error. [\#273](https://github.com/nlohmann/json/issues/273)
|
- Compilation error. [\#273](https://github.com/nlohmann/json/issues/273)
|
||||||
|
@ -1577,6 +1940,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- fixed a tiny typo [\#271](https://github.com/nlohmann/json/pull/271) ([feroldi](https://github.com/feroldi))
|
- fixed a tiny typo [\#271](https://github.com/nlohmann/json/pull/271) ([feroldi](https://github.com/feroldi))
|
||||||
|
|
||||||
## [v2.0.0](https://github.com/nlohmann/json/releases/tag/v2.0.0) (2016-06-23)
|
## [v2.0.0](https://github.com/nlohmann/json/releases/tag/v2.0.0) (2016-06-23)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v1.1.0...v2.0.0)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v1.1.0...v2.0.0)
|
||||||
|
|
||||||
- json::diff generates incorrect patch when removing multiple array elements. [\#269](https://github.com/nlohmann/json/issues/269)
|
- json::diff generates incorrect patch when removing multiple array elements. [\#269](https://github.com/nlohmann/json/issues/269)
|
||||||
|
@ -1651,6 +2015,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Issue \#178 - Extending support to full uint64\_t/int64\_t range and unsigned type \(updated\) [\#193](https://github.com/nlohmann/json/pull/193) ([twelsby](https://github.com/twelsby))
|
- Issue \#178 - Extending support to full uint64\_t/int64\_t range and unsigned type \(updated\) [\#193](https://github.com/nlohmann/json/pull/193) ([twelsby](https://github.com/twelsby))
|
||||||
|
|
||||||
## [v1.1.0](https://github.com/nlohmann/json/releases/tag/v1.1.0) (2016-01-24)
|
## [v1.1.0](https://github.com/nlohmann/json/releases/tag/v1.1.0) (2016-01-24)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0...v1.1.0)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0...v1.1.0)
|
||||||
|
|
||||||
- Small error in pull \#185 [\#194](https://github.com/nlohmann/json/issues/194)
|
- Small error in pull \#185 [\#194](https://github.com/nlohmann/json/issues/194)
|
||||||
|
@ -1679,6 +2044,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Fixed some typos in CONTRIBUTING.md [\#182](https://github.com/nlohmann/json/pull/182) ([nibroc](https://github.com/nibroc))
|
- Fixed some typos in CONTRIBUTING.md [\#182](https://github.com/nlohmann/json/pull/182) ([nibroc](https://github.com/nibroc))
|
||||||
|
|
||||||
## [v1.0.0](https://github.com/nlohmann/json/releases/tag/v1.0.0) (2015-12-27)
|
## [v1.0.0](https://github.com/nlohmann/json/releases/tag/v1.0.0) (2015-12-27)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0-rc1...v1.0.0)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0-rc1...v1.0.0)
|
||||||
|
|
||||||
- add key name to exception [\#160](https://github.com/nlohmann/json/issues/160)
|
- add key name to exception [\#160](https://github.com/nlohmann/json/issues/160)
|
||||||
|
@ -1731,13 +2097,15 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Use the right variable name in doc string [\#115](https://github.com/nlohmann/json/pull/115) ([whoshuu](https://github.com/whoshuu))
|
- Use the right variable name in doc string [\#115](https://github.com/nlohmann/json/pull/115) ([whoshuu](https://github.com/whoshuu))
|
||||||
|
|
||||||
## [v1.0.0-rc1](https://github.com/nlohmann/json/releases/tag/v1.0.0-rc1) (2015-07-26)
|
## [v1.0.0-rc1](https://github.com/nlohmann/json/releases/tag/v1.0.0-rc1) (2015-07-26)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/4502e7e51c0569419c26e75fbdd5748170603e54...v1.0.0-rc1)
|
||||||
|
|
||||||
- Finish documenting the public interface in Doxygen [\#102](https://github.com/nlohmann/json/issues/102)
|
- Finish documenting the public interface in Doxygen [\#102](https://github.com/nlohmann/json/issues/102)
|
||||||
- Binary string causes numbers to be dumped as hex [\#101](https://github.com/nlohmann/json/issues/101)
|
- Binary string causes numbers to be dumped as hex [\#101](https://github.com/nlohmann/json/issues/101)
|
||||||
- failed to iterator json object with reverse\_iterator [\#100](https://github.com/nlohmann/json/issues/100)
|
- failed to iterator json object with reverse\_iterator [\#100](https://github.com/nlohmann/json/issues/100)
|
||||||
- 'noexcept' : unknown override specifier [\#99](https://github.com/nlohmann/json/issues/99)
|
- 'noexcept' : unknown override specifier [\#99](https://github.com/nlohmann/json/issues/99)
|
||||||
- json float parsing problem [\#98](https://github.com/nlohmann/json/issues/98)
|
- json float parsing problem [\#98](https://github.com/nlohmann/json/issues/98)
|
||||||
- Adjust wording to JSON RFC [\#97](https://github.com/nlohmann/json/issues/97)
|
- Adjust wording to JSON RFC [\#97](https://github.com/nlohmann/json/issues/97)
|
||||||
- 17 MB / 90 MB repo size!? [\#96](https://github.com/nlohmann/json/issues/96)
|
|
||||||
- static analysis warnings [\#94](https://github.com/nlohmann/json/issues/94)
|
- static analysis warnings [\#94](https://github.com/nlohmann/json/issues/94)
|
||||||
- reverse\_iterator operator inheritance problem [\#93](https://github.com/nlohmann/json/issues/93)
|
- reverse\_iterator operator inheritance problem [\#93](https://github.com/nlohmann/json/issues/93)
|
||||||
- init error [\#92](https://github.com/nlohmann/json/issues/92)
|
- init error [\#92](https://github.com/nlohmann/json/issues/92)
|
||||||
|
@ -1808,19 +2176,7 @@ All notable changes to this project will be documented in this file. This projec
|
||||||
- Fix compilation of json\_unit with GCC 5 [\#59](https://github.com/nlohmann/json/pull/59) ([dkopecek](https://github.com/dkopecek))
|
- Fix compilation of json\_unit with GCC 5 [\#59](https://github.com/nlohmann/json/pull/59) ([dkopecek](https://github.com/dkopecek))
|
||||||
- Parse streams incrementally. [\#40](https://github.com/nlohmann/json/pull/40) ([aburgh](https://github.com/aburgh))
|
- Parse streams incrementally. [\#40](https://github.com/nlohmann/json/pull/40) ([aburgh](https://github.com/aburgh))
|
||||||
- Feature/small float serialization [\#38](https://github.com/nlohmann/json/pull/38) ([jrandall](https://github.com/jrandall))
|
- Feature/small float serialization [\#38](https://github.com/nlohmann/json/pull/38) ([jrandall](https://github.com/jrandall))
|
||||||
- template version with re2c scanner [\#36](https://github.com/nlohmann/json/pull/36) ([nlohmann](https://github.com/nlohmann))
|
|
||||||
- more descriptive documentation in example [\#33](https://github.com/nlohmann/json/pull/33) ([luxe](https://github.com/luxe))
|
|
||||||
- Fix string conversion under Clang [\#26](https://github.com/nlohmann/json/pull/26) ([wancw](https://github.com/wancw))
|
|
||||||
- Fixed dumping of strings [\#24](https://github.com/nlohmann/json/pull/24) ([Teemperor](https://github.com/Teemperor))
|
|
||||||
- Added a remark to the readme that coverage is GCC only for now [\#23](https://github.com/nlohmann/json/pull/23) ([Teemperor](https://github.com/Teemperor))
|
|
||||||
- Unicode escaping [\#22](https://github.com/nlohmann/json/pull/22) ([Teemperor](https://github.com/Teemperor))
|
|
||||||
- Implemented the JSON spec for string parsing for everything but the \uXXXX escaping [\#21](https://github.com/nlohmann/json/pull/21) ([Teemperor](https://github.com/Teemperor))
|
|
||||||
- add the std iterator typedefs to iterator and const\_iterator [\#19](https://github.com/nlohmann/json/pull/19) ([kirkshoop](https://github.com/kirkshoop))
|
|
||||||
- Fixed escaped quotes [\#18](https://github.com/nlohmann/json/pull/18) ([Teemperor](https://github.com/Teemperor))
|
|
||||||
- Fix double delete on std::bad\_alloc exception [\#14](https://github.com/nlohmann/json/pull/14) ([elliotgoodrich](https://github.com/elliotgoodrich))
|
|
||||||
- Added CMake and lcov [\#6](https://github.com/nlohmann/json/pull/6) ([Teemperor](https://github.com/Teemperor))
|
|
||||||
- Version 2.0 [\#5](https://github.com/nlohmann/json/pull/5) ([nlohmann](https://github.com/nlohmann))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -361,7 +361,7 @@ pedantic_gcc:
|
||||||
-Wunused-const-variable=2 \
|
-Wunused-const-variable=2 \
|
||||||
-Wunused-function \
|
-Wunused-function \
|
||||||
-Wunused-label \
|
-Wunused-label \
|
||||||
-Wunused-local-typedefs \
|
-Wno-unused-local-typedefs \
|
||||||
-Wunused-macros \
|
-Wunused-macros \
|
||||||
-Wunused-parameter \
|
-Wunused-parameter \
|
||||||
-Wunused-result \
|
-Wunused-result \
|
||||||
|
|
62
README.md
62
README.md
|
@ -416,7 +416,7 @@ Please note that setting the exception bit for `failbit` is inappropriate for th
|
||||||
|
|
||||||
#### Read from iterator range
|
#### Read from iterator range
|
||||||
|
|
||||||
You can also parse JSON from an iterator range; that is, from any container accessible by iterators whose content is stored as contiguous byte sequence, for instance a `std::vector<std::uint8_t>`:
|
You can also parse JSON from an iterator range; that is, from any container accessible by iterators whose `value_type` is an integral type of 1, 2 or 4 bytes, which will be interpreted as UTF-8, UTF-16 and UTF-32 respectively. For instance, a `std::vector<std::uint8_t>`, or a `std::list<std::uint16_t>`:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
|
std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
|
||||||
|
@ -430,6 +430,53 @@ std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
|
||||||
json j = json::parse(v);
|
json j = json::parse(v);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Custom data source
|
||||||
|
|
||||||
|
Since the parse function accepts arbitrary iterator ranges, you can provide your own data sources by implementing the `LegacyInputIterator` concept.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct MyContainer {
|
||||||
|
void advance();
|
||||||
|
const char& get_current();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MyIterator {
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using value_type = char;
|
||||||
|
using pointer = const char*;
|
||||||
|
using reference = const char&;
|
||||||
|
using iterator_category = std::input_iterator_tag;
|
||||||
|
|
||||||
|
MyIterator& operator++() {
|
||||||
|
MyContainer.advance();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const MyIterator& rhs) const {
|
||||||
|
return rhs.target != target;
|
||||||
|
}
|
||||||
|
|
||||||
|
reference operator*() const {
|
||||||
|
return target.get_current();
|
||||||
|
}
|
||||||
|
|
||||||
|
MyContainer* target = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
MyIterator begin(MyContainer& tgt) {
|
||||||
|
return MyIterator{&tgt};
|
||||||
|
}
|
||||||
|
|
||||||
|
MyIterator end(const MyContainer&) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void foo() {
|
||||||
|
MyContainer c;
|
||||||
|
json j = json::parse(c);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### SAX interface
|
#### SAX interface
|
||||||
|
|
||||||
The library uses a SAX-like interface with the following functions:
|
The library uses a SAX-like interface with the following functions:
|
||||||
|
@ -1404,6 +1451,7 @@ I deeply appreciate the help of the following people.
|
||||||
- [Quentin Barbarat](https://github.com/quentin-dev) fixed an example in the documentation.
|
- [Quentin Barbarat](https://github.com/quentin-dev) fixed an example in the documentation.
|
||||||
- [XyFreak](https://github.com/XyFreak) fixed a compiler warning.
|
- [XyFreak](https://github.com/XyFreak) fixed a compiler warning.
|
||||||
- [TotalCaesar659](https://github.com/TotalCaesar659) fixed links in the README.
|
- [TotalCaesar659](https://github.com/TotalCaesar659) fixed links in the README.
|
||||||
|
- [Tanuj Garg](https://github.com/tanuj208) improved the fuzzer coverage for UBSAN input.
|
||||||
|
|
||||||
Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone.
|
Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone.
|
||||||
|
|
||||||
|
@ -1460,7 +1508,7 @@ The library supports **Unicode input** as follows:
|
||||||
|
|
||||||
### Comments in JSON
|
### Comments in JSON
|
||||||
|
|
||||||
This library does not support comments. It does so for three reasons:
|
This library does not support comments by default. It does so for three reasons:
|
||||||
|
|
||||||
1. Comments are not part of the [JSON specification](https://tools.ietf.org/html/rfc8259). You may argue that `//` or `/* */` are allowed in JavaScript, but JSON is not JavaScript.
|
1. Comments are not part of the [JSON specification](https://tools.ietf.org/html/rfc8259). You may argue that `//` or `/* */` are allowed in JavaScript, but JSON is not JavaScript.
|
||||||
2. This was not an oversight: Douglas Crockford [wrote on this](https://plus.google.com/118095276221607585885/posts/RK8qyGVaGSr) in May 2012:
|
2. This was not an oversight: Douglas Crockford [wrote on this](https://plus.google.com/118095276221607585885/posts/RK8qyGVaGSr) in May 2012:
|
||||||
|
@ -1471,11 +1519,7 @@ This library does not support comments. It does so for three reasons:
|
||||||
|
|
||||||
3. It is dangerous for interoperability if some libraries would add comment support while others don't. Please check [The Harmful Consequences of the Robustness Principle](https://tools.ietf.org/html/draft-iab-protocol-maintenance-01) on this.
|
3. It is dangerous for interoperability if some libraries would add comment support while others don't. Please check [The Harmful Consequences of the Robustness Principle](https://tools.ietf.org/html/draft-iab-protocol-maintenance-01) on this.
|
||||||
|
|
||||||
This library will not support comments in the future. If you wish to use comments, I see three options:
|
However, you can pass set parameter `ignore_comments` to true in the `parse` function to ignore `//` or `/* */` comments. Comments will then be treated as whitespace.
|
||||||
|
|
||||||
1. Strip comments before using this library.
|
|
||||||
2. Use a different JSON library with comment support.
|
|
||||||
3. Use a format that natively supports comments (e.g., YAML or JSON5).
|
|
||||||
|
|
||||||
### Order of object keys
|
### Order of object keys
|
||||||
|
|
||||||
|
@ -1509,4 +1553,6 @@ $ cmake --build .
|
||||||
$ ctest --output-on-failure
|
$ ctest --output-on-failure
|
||||||
```
|
```
|
||||||
|
|
||||||
For more information, have a look at the file [.travis.yml](https://github.com/nlohmann/json/blob/master/.travis.yml).
|
Note that during the `ctest` stage, several JSON test files are downloaded from an [external repository](https://github.com/nlohmann/json_test_data). If policies forbid downloading artifacts during testing, you can download the files yourself and pass the directory with the test files via `-DJSON_TestDataDirectory=path` to CMake. Then, no Internet connectivity is required. See [issue #2189](https://github.com/nlohmann/json/issues/2189) for more information.
|
||||||
|
|
||||||
|
In case you have downloaded the library rather than checked out the code via Git, test `cmake_fetch_content_configure`. Please execute `ctest -LE git_required` to skip these tests. See [issue #2189](https://github.com/nlohmann/json/issues/2189) for more information.
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
find_package(Git)
|
|
||||||
|
|
||||||
set(JSON_TEST_DATA_URL https://github.com/nlohmann/json_test_data)
|
set(JSON_TEST_DATA_URL https://github.com/nlohmann/json_test_data)
|
||||||
set(JSON_TEST_DATA_VERSION 2.0.0)
|
set(JSON_TEST_DATA_VERSION 3.0.0)
|
||||||
|
|
||||||
# target to download test data
|
# if variable is set, use test data from given directory rather than downloading them
|
||||||
add_custom_target(download_test_data
|
if(JSON_TestDataDirectory)
|
||||||
|
message(STATUS "Using test data in ${JSON_TestDataDirectory}.")
|
||||||
|
add_custom_target(download_test_data)
|
||||||
|
file(WRITE ${CMAKE_BINARY_DIR}/include/test_data.hpp "#define TEST_DATA_DIRECTORY \"${JSON_TestDataDirectory}\"\n")
|
||||||
|
else()
|
||||||
|
find_package(Git)
|
||||||
|
# target to download test data
|
||||||
|
add_custom_target(download_test_data
|
||||||
COMMAND test -d json_test_data || ${GIT_EXECUTABLE} clone -c advice.detachedHead=false --branch v${JSON_TEST_DATA_VERSION} ${JSON_TEST_DATA_URL}.git --quiet --depth 1
|
COMMAND test -d json_test_data || ${GIT_EXECUTABLE} clone -c advice.detachedHead=false --branch v${JSON_TEST_DATA_VERSION} ${JSON_TEST_DATA_URL}.git --quiet --depth 1
|
||||||
COMMENT "Downloading test data from ${JSON_TEST_DATA_URL} (v${JSON_TEST_DATA_VERSION})"
|
COMMENT "Downloading test data from ${JSON_TEST_DATA_URL} (v${JSON_TEST_DATA_VERSION})"
|
||||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||||
)
|
)
|
||||||
|
# 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")
|
endif()
|
||||||
|
|
||||||
# determine the operating system (for debug and support purposes)
|
# determine the operating system (for debug and support purposes)
|
||||||
find_program(UNAME_COMMAND uname)
|
find_program(UNAME_COMMAND uname)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
DOXYFILE_ENCODING = UTF-8
|
DOXYFILE_ENCODING = UTF-8
|
||||||
PROJECT_NAME = "JSON for Modern C++"
|
PROJECT_NAME = "JSON for Modern C++"
|
||||||
PROJECT_NUMBER = 3.7.3
|
PROJECT_NUMBER = 3.8.0
|
||||||
PROJECT_BRIEF =
|
PROJECT_BRIEF =
|
||||||
PROJECT_LOGO =
|
PROJECT_LOGO =
|
||||||
OUTPUT_DIRECTORY = .
|
OUTPUT_DIRECTORY = .
|
||||||
|
@ -110,9 +110,7 @@ WARN_LOGFILE =
|
||||||
# Configuration options related to the input files
|
# Configuration options related to the input files
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
INPUT = ../single_include/nlohmann/json.hpp \
|
INPUT = ../single_include/nlohmann/json.hpp \
|
||||||
index.md \
|
index.md
|
||||||
faq.md \
|
|
||||||
binary_formats.md
|
|
||||||
INPUT_ENCODING = UTF-8
|
INPUT_ENCODING = UTF-8
|
||||||
FILE_PATTERNS =
|
FILE_PATTERNS =
|
||||||
RECURSIVE = NO
|
RECURSIVE = NO
|
||||||
|
|
BIN
doc/avatars.png
BIN
doc/avatars.png
Binary file not shown.
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
@ -1,171 +0,0 @@
|
||||||
# Binary formats
|
|
||||||
|
|
||||||
![conversion between JSON and binary formats](images/binary.png)
|
|
||||||
|
|
||||||
Several formats exist that encode JSON values in a binary format to reduce the size of the encoded value as well as the required effort to parse encoded value. The library implements three formats, namely
|
|
||||||
|
|
||||||
- [CBOR](https://tools.ietf.org/html/rfc7049) (Concise Binary Object Representation)
|
|
||||||
- [MessagePack](https://msgpack.org)
|
|
||||||
- [UBJSON](http://ubjson.org) (Universal Binary JSON)
|
|
||||||
|
|
||||||
## Interface
|
|
||||||
|
|
||||||
### JSON to binary format
|
|
||||||
|
|
||||||
For each format, the `to_*` functions (i.e., `to_cbor`, `to_msgpack`, and `to_ubjson`) convert a JSON value into the respective binary format. Taking CBOR as example, the concrete prototypes are:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
static std::vector<uint8_t> to_cbor(const basic_json& j); // 1
|
|
||||||
static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o); // 2
|
|
||||||
static void to_cbor(const basic_json& j, detail::output_adapter<char> o); // 3
|
|
||||||
```
|
|
||||||
|
|
||||||
The first function creates a byte vector from the given JSON value. The second and third function writes to an output adapter of `uint8_t` and `char`, respectively. Output adapters are implemented for strings, output streams, and vectors.
|
|
||||||
|
|
||||||
Given a JSON value `j`, the following calls are possible:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
std::vector<uint8_t> v;
|
|
||||||
v = json::to_cbor(j); // 1
|
|
||||||
|
|
||||||
json::to_cbor(j, v); // 2
|
|
||||||
|
|
||||||
std::string s;
|
|
||||||
json::to_cbor(j, s); // 3
|
|
||||||
|
|
||||||
std::ostringstream oss;
|
|
||||||
json::to_cbor(j, oss); // 3
|
|
||||||
```
|
|
||||||
|
|
||||||
### Binary format to JSON
|
|
||||||
|
|
||||||
Likewise, the `from_*` functions (i.e, `from_cbor`, `from_msgpack`, and `from_ubjson`) convert a binary encoded value into a JSON value. Taking CBOR as example, the concrete prototypes are:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
static basic_json from_cbor(detail::input_adapter i, const bool strict = true); // 1
|
|
||||||
static basic_json from_cbor(A1 && a1, A2 && a2, const bool strict = true); // 2
|
|
||||||
```
|
|
||||||
|
|
||||||
Both functions read from an input adapter: the first function takes it directly form argument `i`, whereas the second function creates it from the provided arguments `a1` and `a2`. If the optional parameter `strict` is true, the input must be read completely (or a parse error exception is thrown). If it is false, parsing succeeds even if the input is not completely read.
|
|
||||||
|
|
||||||
Input adapters are implemented for input streams, character buffers, string literals, and iterator ranges.
|
|
||||||
|
|
||||||
Given several inputs (which we assume to be filled with a CBOR value), the following calls are possible:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
std::string s;
|
|
||||||
json j1 = json::from_cbor(s); // 1
|
|
||||||
|
|
||||||
std::ifstream is("somefile.cbor", std::ios::binary);
|
|
||||||
json j2 = json::from_cbor(is); // 1
|
|
||||||
|
|
||||||
std::vector<uint8_t> v;
|
|
||||||
json j3 = json::from_cbor(v); // 1
|
|
||||||
|
|
||||||
const char* buff;
|
|
||||||
std::size_t buff_size;
|
|
||||||
json j4 = json::from_cbor(buff, buff_size); // 2
|
|
||||||
```
|
|
||||||
|
|
||||||
## Details
|
|
||||||
|
|
||||||
### CBOR
|
|
||||||
|
|
||||||
The mapping from CBOR to JSON is **incomplete** in the sense that not all CBOR types can be converted to a JSON value. The following CBOR types are not supported and will yield parse errors (parse_error.112):
|
|
||||||
|
|
||||||
- byte strings (0x40..0x5F)
|
|
||||||
- date/time (0xC0..0xC1)
|
|
||||||
- bignum (0xC2..0xC3)
|
|
||||||
- decimal fraction (0xC4)
|
|
||||||
- bigfloat (0xC5)
|
|
||||||
- tagged items (0xC6..0xD4, 0xD8..0xDB)
|
|
||||||
- expected conversions (0xD5..0xD7)
|
|
||||||
- simple values (0xE0..0xF3, 0xF8)
|
|
||||||
- undefined (0xF7)
|
|
||||||
|
|
||||||
CBOR further allows map keys of any type, whereas JSON only allows strings as keys in object values. Therefore, CBOR maps with keys other than UTF-8 strings are rejected (parse_error.113).
|
|
||||||
|
|
||||||
The mapping from JSON to CBOR is **complete** in the sense that any JSON value type can be converted to a CBOR value.
|
|
||||||
|
|
||||||
If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the dump() function which serializes NaN or Infinity to null.
|
|
||||||
|
|
||||||
The following CBOR types are not used in the conversion:
|
|
||||||
|
|
||||||
- byte strings (0x40..0x5F)
|
|
||||||
- UTF-8 strings terminated by "break" (0x7F)
|
|
||||||
- arrays terminated by "break" (0x9F)
|
|
||||||
- maps terminated by "break" (0xBF)
|
|
||||||
- date/time (0xC0..0xC1)
|
|
||||||
- bignum (0xC2..0xC3)
|
|
||||||
- decimal fraction (0xC4)
|
|
||||||
- bigfloat (0xC5)
|
|
||||||
- tagged items (0xC6..0xD4, 0xD8..0xDB)
|
|
||||||
- expected conversions (0xD5..0xD7)
|
|
||||||
- simple values (0xE0..0xF3, 0xF8)
|
|
||||||
- undefined (0xF7)
|
|
||||||
- half and single-precision floats (0xF9-0xFA)
|
|
||||||
- break (0xFF)
|
|
||||||
|
|
||||||
### MessagePack
|
|
||||||
|
|
||||||
The mapping from MessagePack to JSON is **incomplete** in the sense that not all MessagePack types can be converted to a JSON value. The following MessagePack types are not supported and will yield parse errors:
|
|
||||||
|
|
||||||
- bin 8 - bin 32 (0xC4..0xC6)
|
|
||||||
- ext 8 - ext 32 (0xC7..0xC9)
|
|
||||||
- fixext 1 - fixext 16 (0xD4..0xD8)
|
|
||||||
|
|
||||||
The mapping from JSON to MessagePack is **complete** in the sense that any JSON value type can be converted to a MessagePack value.
|
|
||||||
|
|
||||||
The following values can not be converted to a MessagePack value:
|
|
||||||
|
|
||||||
- strings with more than 4294967295 bytes
|
|
||||||
- arrays with more than 4294967295 elements
|
|
||||||
- objects with more than 4294967295 elements
|
|
||||||
|
|
||||||
The following MessagePack types are not used in the conversion:
|
|
||||||
|
|
||||||
- bin 8 - bin 32 (0xC4..0xC6)
|
|
||||||
- ext 8 - ext 32 (0xC7..0xC9)
|
|
||||||
- float 32 (0xCA)
|
|
||||||
- fixext 1 - fixext 16 (0xD4..0xD8)
|
|
||||||
|
|
||||||
Any MessagePack output created `to_msgpack` can be successfully parsed by `from_msgpack`.
|
|
||||||
|
|
||||||
If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the `dump()` function which serializes NaN or Infinity to `null`.
|
|
||||||
|
|
||||||
### UBJSON
|
|
||||||
|
|
||||||
The mapping from UBJSON to JSON is **complete** in the sense that any UBJSON value can be converted to a JSON value.
|
|
||||||
|
|
||||||
The mapping from JSON to UBJSON is **complete** in the sense that any JSON value type can be converted to a UBJSON value.
|
|
||||||
|
|
||||||
The following values can not be converted to a UBJSON value:
|
|
||||||
|
|
||||||
- strings with more than 9223372036854775807 bytes (theoretical)
|
|
||||||
- unsigned integer numbers above 9223372036854775807
|
|
||||||
|
|
||||||
The following markers are not used in the conversion:
|
|
||||||
|
|
||||||
- `Z`: no-op values are not created.
|
|
||||||
- `C`: single-byte strings are serialized with S markers.
|
|
||||||
|
|
||||||
Any UBJSON output created to_ubjson can be successfully parsed by from_ubjson.
|
|
||||||
|
|
||||||
If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the `dump()` function which serializes NaN or Infinity to null.
|
|
||||||
|
|
||||||
The optimized formats for containers are supported: Parameter `use_size` adds size information to the beginning of a container and removes the closing marker. Parameter `use_type` further checks whether all elements of a container have the same type and adds the type marker to the beginning of the container. The `use_type` parameter must only be used together with `use_size = true`. Note that `use_size = true` alone may result in larger representations - the benefit of this parameter is that the receiving side is immediately informed on the number of elements of the container.
|
|
||||||
|
|
||||||
## Size comparison examples
|
|
||||||
|
|
||||||
The following table shows the size compared to the original JSON value for different files from the repository for the different formats.
|
|
||||||
|
|
||||||
| format | sample.json | all_unicode.json | floats.json | signed_ints.json | jeopardy.json | canada.json |
|
|
||||||
| ----------------------- | -----------:| ----------------:| -----------:| ----------------:| -------------:| -----------:|
|
|
||||||
| JSON | 100.00 % | 100.00 % | 100.00 % | 100.00 % | 100.00 % | 100.00 % |
|
|
||||||
| CBOR | 87.21 % | 71.18 % | 48.20 % | 44.16 % | 87.96 % | 50.53 % |
|
|
||||||
| MessagePack | 87.16 % | 71.18 % | 48.20 % | 44.16 % | 87.91 % | 50.56 % |
|
|
||||||
| UBJSON unoptimized | 88.15 % | 100.00 % | 48.20 % | 44.16 % | 96.58 % | 53.20 % |
|
|
||||||
| UBJSON size-optimized | 89.26 % | 100.00 % | 48.20 % | 44.16 % | 97.40 % | 58.56 % |
|
|
||||||
| UBJSON format-optimized | 89.45 % | 100.00 % | 42.85 % | 39.26 % | 94.96 % | 55.93 % |
|
|
||||||
|
|
||||||
The results show that there does not exist a "best" encoding. Furthermore, it is not always worthwhile to use UBJSON's optimizations.
|
|
|
@ -1 +1 @@
|
||||||
<a target="_blank" href="https://wandbox.org/permlink/uDkr2VTjsrssiXq3"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/EezQxM0Nzi8tTUEe"><b>online</b></a>
|
26
doc/examples/accept__string.cpp
Normal file
26
doc/examples/accept__string.cpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a valid JSON text
|
||||||
|
auto valid_text = R"(
|
||||||
|
{
|
||||||
|
"numbers": [1, 2, 3]
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
// an invalid JSON text
|
||||||
|
auto invalid_text = R"(
|
||||||
|
{
|
||||||
|
"strings": ["extra", "comma", ]
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
std::cout << std::boolalpha
|
||||||
|
<< json::accept(valid_text) << ' '
|
||||||
|
<< json::accept(invalid_text) << '\n';
|
||||||
|
}
|
1
doc/examples/accept__string.link
Normal file
1
doc/examples/accept__string.link
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<a target="_blank" href="https://wandbox.org/permlink/r5Tai1spihWHTdFA"><b>online</b></a>
|
1
doc/examples/accept__string.output
Normal file
1
doc/examples/accept__string.output
Normal file
|
@ -0,0 +1 @@
|
||||||
|
true false
|
|
@ -10,8 +10,8 @@
|
||||||
"url": "https://github.com/nlohmann/json",
|
"url": "https://github.com/nlohmann/json",
|
||||||
"version": {
|
"version": {
|
||||||
"major": 3,
|
"major": 3,
|
||||||
"minor": 7,
|
"minor": 8,
|
||||||
"patch": 3,
|
"patch": 0,
|
||||||
"string": "3.7.3"
|
"string": "3.8.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
doc/examples/swap__binary_t.link
Normal file
1
doc/examples/swap__binary_t.link
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<a target="_blank" href="https://wandbox.org/permlink/OD1Yaew9vlzMYxmX"><b>online</b></a>
|
87
doc/faq.md
87
doc/faq.md
|
@ -1,87 +0,0 @@
|
||||||
# FAQ
|
|
||||||
|
|
||||||
## Parsing
|
|
||||||
|
|
||||||
### How can I parse from a string?
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
json j = json::parse("[1,2,3,4]");
|
|
||||||
```
|
|
||||||
|
|
||||||
You can pass string literals (as above), `std::string`, `const char*` or byte containers such as `std::vector<uint8_t>`.
|
|
||||||
|
|
||||||
### How can I parse from a file?
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
std::ifstream i("your_file.json");
|
|
||||||
json j = json::parse(i);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Serialization
|
|
||||||
|
|
||||||
### How can I serialize a JSON value
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
std::cout << j << std::endl;
|
|
||||||
```
|
|
||||||
|
|
||||||
This is equivalent to
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
std::string s = j.dump();
|
|
||||||
std::cout << s << std::endl;
|
|
||||||
```
|
|
||||||
|
|
||||||
### How can I pretty-print a JSON value
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
std::cout << std::setw(4) << j << std::endl;
|
|
||||||
```
|
|
||||||
|
|
||||||
This is equivalent to
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
std::string s = j.dump(4);
|
|
||||||
std::cout << s << std::endl;
|
|
||||||
```
|
|
||||||
|
|
||||||
The number `4` denotes the number of spaces used for indentation.
|
|
||||||
|
|
||||||
## Iterating
|
|
||||||
|
|
||||||
### How can I iterate over a JSON value?
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
for (json& val : j)
|
|
||||||
{
|
|
||||||
// val is a reference for the current value
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This works with any JSON value, also primitive values like numbers.
|
|
||||||
|
|
||||||
### How can I access the keys when iterating over a JSON object?
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
for (auto it = j.begin(); it != j.end(); ++it)
|
|
||||||
{
|
|
||||||
// the value
|
|
||||||
json &val = it.value();
|
|
||||||
|
|
||||||
// the key (for objects)
|
|
||||||
const std::string &key = it.key();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also use an iteration wrapper and use range for:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
for (auto it : json::iteration_wrapper(j))
|
|
||||||
{
|
|
||||||
// the value
|
|
||||||
json &val = it.value();
|
|
||||||
|
|
||||||
// the key (for objects)
|
|
||||||
const std::string &key = it.key();
|
|
||||||
}
|
|
||||||
```
|
|
Binary file not shown.
Before Width: | Height: | Size: 64 KiB |
|
@ -332,4 +332,4 @@ Note that this table only lists those exceptions thrown due to the type. For ins
|
||||||
@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
|
||||||
|
|
||||||
@version 3.7.3
|
@version 3.8.0
|
||||||
|
|
BIN
doc/json.gif
BIN
doc/json.gif
Binary file not shown.
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.6 MiB |
31
doc/mkdocs/Makefile
Normal file
31
doc/mkdocs/Makefile
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# serve the site locally
|
||||||
|
serve: prepare_files
|
||||||
|
venv/bin/mkdocs serve
|
||||||
|
|
||||||
|
# create files that are not versioned inside the mkdocs folder
|
||||||
|
prepare_files: clean
|
||||||
|
# build Doxygen
|
||||||
|
$(MAKE) -C ..
|
||||||
|
# create subfolders
|
||||||
|
mkdir docs/images docs/examples
|
||||||
|
# copy images
|
||||||
|
cp -vr ../json.gif ../images/range-begin-end.svg ../images/range-rbegin-rend.svg docs/images
|
||||||
|
# copy examples
|
||||||
|
cp -vr ../examples/*.cpp ../examples/*.output docs/examples
|
||||||
|
|
||||||
|
# clean subfolders
|
||||||
|
clean:
|
||||||
|
rm -fr docs/images docs/examples
|
||||||
|
|
||||||
|
# publish site to GitHub pages
|
||||||
|
publish: prepare_files
|
||||||
|
venv/bin/mkdocs gh-deploy --clean --force
|
||||||
|
|
||||||
|
# install a Python virtual environment
|
||||||
|
install_venv: requirements.txt
|
||||||
|
python3 -mvenv venv
|
||||||
|
venv/bin/pip install -r requirements.txt
|
||||||
|
|
||||||
|
# uninstall the virtual environment
|
||||||
|
uninstall_venv: clean
|
||||||
|
rm -fr venv
|
223
doc/mkdocs/docs/features/arbitrary_types.md
Normal file
223
doc/mkdocs/docs/features/arbitrary_types.md
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
# Arbitrary Types Conversions
|
||||||
|
|
||||||
|
Every type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace ns {
|
||||||
|
// a simple struct to model a person
|
||||||
|
struct person {
|
||||||
|
std::string name;
|
||||||
|
std::string address;
|
||||||
|
int age;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};
|
||||||
|
|
||||||
|
// convert to JSON: copy each value into the JSON object
|
||||||
|
json j;
|
||||||
|
j["name"] = p.name;
|
||||||
|
j["address"] = p.address;
|
||||||
|
j["age"] = p.age;
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// convert from JSON: copy each value from the JSON object
|
||||||
|
ns::person p {
|
||||||
|
j["name"].get<std::string>(),
|
||||||
|
j["address"].get<std::string>(),
|
||||||
|
j["age"].get<int>()
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
It works, but that's quite a lot of boilerplate... Fortunately, there's a better way:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// create a person
|
||||||
|
ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60};
|
||||||
|
|
||||||
|
// conversion: person -> json
|
||||||
|
json j = p;
|
||||||
|
|
||||||
|
std::cout << j << std::endl;
|
||||||
|
// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}
|
||||||
|
|
||||||
|
// conversion: json -> person
|
||||||
|
auto p2 = j.get<ns::person>();
|
||||||
|
|
||||||
|
// that's it
|
||||||
|
assert(p == p2);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Basic usage
|
||||||
|
|
||||||
|
To make this work with one of your types, you only need to provide two functions:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
using nlohmann::json;
|
||||||
|
|
||||||
|
namespace ns {
|
||||||
|
void to_json(json& j, const person& p) {
|
||||||
|
j = json{ {"name", p.name}, {"address", p.address}, {"age", p.age} };
|
||||||
|
}
|
||||||
|
|
||||||
|
void from_json(const json& j, person& p) {
|
||||||
|
j.at("name").get_to(p.name);
|
||||||
|
j.at("address").get_to(p.address);
|
||||||
|
j.at("age").get_to(p.age);
|
||||||
|
}
|
||||||
|
} // namespace ns
|
||||||
|
```
|
||||||
|
|
||||||
|
That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called.
|
||||||
|
Likewise, when calling `get<your_type>()` or `get_to(your_type&)`, the `from_json` method will be called.
|
||||||
|
|
||||||
|
Some important things:
|
||||||
|
|
||||||
|
* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).
|
||||||
|
* Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.
|
||||||
|
* When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)
|
||||||
|
* In function `from_json`, use function [`at()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a93403e803947b86f4da2d1fb3345cf2c.html#a93403e803947b86f4da2d1fb3345cf2c) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.
|
||||||
|
* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.
|
||||||
|
|
||||||
|
|
||||||
|
## How do I convert third-party types?
|
||||||
|
|
||||||
|
This requires a bit more advanced technique. But first, let's see how this conversion mechanism works:
|
||||||
|
|
||||||
|
The library uses **JSON Serializers** to convert types to json.
|
||||||
|
The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)).
|
||||||
|
|
||||||
|
It is implemented like this (simplified):
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct adl_serializer {
|
||||||
|
static void to_json(json& j, const T& value) {
|
||||||
|
// calls the "to_json" method in T's namespace
|
||||||
|
}
|
||||||
|
|
||||||
|
static void from_json(const json& j, T& value) {
|
||||||
|
// same thing, but with the "from_json" method
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
This serializer works fine when you have control over the type's namespace. However, what about `boost::optional` or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`...
|
||||||
|
|
||||||
|
To solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// partial specialization (full specialization works too)
|
||||||
|
namespace nlohmann {
|
||||||
|
template <typename T>
|
||||||
|
struct adl_serializer<boost::optional<T>> {
|
||||||
|
static void to_json(json& j, const boost::optional<T>& opt) {
|
||||||
|
if (opt == boost::none) {
|
||||||
|
j = nullptr;
|
||||||
|
} else {
|
||||||
|
j = *opt; // this will call adl_serializer<T>::to_json which will
|
||||||
|
// find the free function to_json in T's namespace!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void from_json(const json& j, boost::optional<T>& opt) {
|
||||||
|
if (j.is_null()) {
|
||||||
|
opt = boost::none;
|
||||||
|
} else {
|
||||||
|
opt = j.get<T>(); // same as above, but with
|
||||||
|
// adl_serializer<T>::from_json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## How can I use `get()` for non-default constructible/non-copyable types?
|
||||||
|
|
||||||
|
There is a way, if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct move_only_type {
|
||||||
|
move_only_type() = delete;
|
||||||
|
move_only_type(int ii): i(ii) {}
|
||||||
|
move_only_type(const move_only_type&) = delete;
|
||||||
|
move_only_type(move_only_type&&) = default;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace nlohmann {
|
||||||
|
template <>
|
||||||
|
struct adl_serializer<move_only_type> {
|
||||||
|
// note: the return type is no longer 'void', and the method only takes
|
||||||
|
// one argument
|
||||||
|
static move_only_type from_json(const json& j) {
|
||||||
|
return {j.get<int>()};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here's the catch! You must provide a to_json method! Otherwise you
|
||||||
|
// will not be able to convert move_only_type to json, since you fully
|
||||||
|
// specialized adl_serializer on that type
|
||||||
|
static void to_json(json& j, move_only_type t) {
|
||||||
|
j = t.i;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Can I write my own serializer? (Advanced use)
|
||||||
|
|
||||||
|
Yes. You might want to take a look at [`unit-udt.cpp`](https://github.com/nlohmann/json/blob/develop/test/src/unit-udt.cpp) in the test suite, to see a few examples.
|
||||||
|
|
||||||
|
If you write your own serializer, you'll need to do a few things:
|
||||||
|
|
||||||
|
- use a different `basic_json` alias than `nlohmann::json` (the last template parameter of `basic_json` is the `JSONSerializer`)
|
||||||
|
- use your `basic_json` alias (or a template parameter) in all your `to_json`/`from_json` methods
|
||||||
|
- use `nlohmann::to_json` and `nlohmann::from_json` when you need ADL
|
||||||
|
|
||||||
|
Here is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// You should use void as a second template argument
|
||||||
|
// if you don't need compile-time checks on T
|
||||||
|
template<typename T, typename SFINAE = typename std::enable_if<sizeof(T) <= 32>::type>
|
||||||
|
struct less_than_32_serializer {
|
||||||
|
template <typename BasicJsonType>
|
||||||
|
static void to_json(BasicJsonType& j, T value) {
|
||||||
|
// we want to use ADL, and call the correct to_json overload
|
||||||
|
using nlohmann::to_json; // this method is called by adl_serializer,
|
||||||
|
// this is where the magic happens
|
||||||
|
to_json(j, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename BasicJsonType>
|
||||||
|
static void from_json(const BasicJsonType& j, T& value) {
|
||||||
|
// same thing here
|
||||||
|
using nlohmann::from_json;
|
||||||
|
from_json(j, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Be **very** careful when reimplementing your serializer, you can stack overflow if you don't pay attention:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T, void>
|
||||||
|
struct bad_serializer
|
||||||
|
{
|
||||||
|
template <typename BasicJsonType>
|
||||||
|
static void to_json(BasicJsonType& j, const T& value) {
|
||||||
|
// this calls BasicJsonType::json_serializer<T>::to_json(j, value);
|
||||||
|
// if BasicJsonType::json_serializer == bad_serializer ... oops!
|
||||||
|
j = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename BasicJsonType>
|
||||||
|
static void to_json(const BasicJsonType& j, T& value) {
|
||||||
|
// this calls BasicJsonType::json_serializer<T>::from_json(j, value);
|
||||||
|
// if BasicJsonType::json_serializer == bad_serializer ... oops!
|
||||||
|
value = j.template get<T>(); // oops!
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
94
doc/mkdocs/docs/features/binary_formats/bson.md
Normal file
94
doc/mkdocs/docs/features/binary_formats/bson.md
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
# BSON
|
||||||
|
|
||||||
|
BSON, short for Binary JSON, is a binary-encoded serialization of JSON-like documents. Like JSON, BSON supports the embedding of documents and arrays within other documents and arrays. BSON also contains extensions that allow representation of data types that are not part of the JSON spec. For example, BSON has a Date type and a BinData type.
|
||||||
|
|
||||||
|
!!! abstract "References"
|
||||||
|
|
||||||
|
- [BSON Website](http://bsonspec.org) - the main source on BSON
|
||||||
|
- [BSON Specification](http://bsonspec.org/spec.html) - the specification
|
||||||
|
|
||||||
|
|
||||||
|
## Serialization
|
||||||
|
|
||||||
|
The library uses the following mapping from JSON values types to BSON types:
|
||||||
|
|
||||||
|
JSON value type | value/range | BSON type | marker
|
||||||
|
--------------- | --------------------------------- | ----------- | ------
|
||||||
|
null | `null` | null | 0x0A
|
||||||
|
boolean | `true`, `false` | boolean | 0x08
|
||||||
|
number_integer | -9223372036854775808..-2147483649 | int64 | 0x12
|
||||||
|
number_integer | -2147483648..2147483647 | int32 | 0x10
|
||||||
|
number_integer | 2147483648..9223372036854775807 | int64 | 0x12
|
||||||
|
number_unsigned | 0..2147483647 | int32 | 0x10
|
||||||
|
number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12
|
||||||
|
number_unsigned | 9223372036854775808..18446744073709551615| -- | --
|
||||||
|
number_float | *any value* | double | 0x01
|
||||||
|
string | *any value* | string | 0x02
|
||||||
|
array | *any value* | document | 0x04
|
||||||
|
object | *any value* | document | 0x03
|
||||||
|
binary | *any value* | binary | 0x05
|
||||||
|
|
||||||
|
!!! warning "Incomplete mapping"
|
||||||
|
|
||||||
|
The mapping is **incomplete**, since only JSON-objects (and things
|
||||||
|
contained therein) can be serialized to BSON.
|
||||||
|
Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
|
||||||
|
and the keys may not contain U+0000, since they are serialized a
|
||||||
|
zero-terminated c-strings.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/to_bson.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```c
|
||||||
|
--8<-- "examples/to_bson.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Deserialization
|
||||||
|
|
||||||
|
The library maps BSON record types to JSON value types as follows:
|
||||||
|
|
||||||
|
BSON type | BSON marker byte | JSON value type
|
||||||
|
--------------- | ---------------- | ---------------------------
|
||||||
|
double | 0x01 | number_float
|
||||||
|
string | 0x02 | string
|
||||||
|
document | 0x03 | object
|
||||||
|
array | 0x04 | array
|
||||||
|
binary | 0x05 | binary
|
||||||
|
undefined | 0x06 | *unsupported*
|
||||||
|
ObjectId | 0x07 | *unsupported*
|
||||||
|
boolean | 0x08 | boolean
|
||||||
|
UTC Date-Time | 0x09 | *unsupported*
|
||||||
|
null | 0x0A | null
|
||||||
|
Regular Expr. | 0x0B | *unsupported*
|
||||||
|
DB Pointer | 0x0C | *unsupported*
|
||||||
|
JavaScript Code | 0x0D | *unsupported*
|
||||||
|
Symbol | 0x0E | *unsupported*
|
||||||
|
JavaScript Code | 0x0F | *unsupported*
|
||||||
|
int32 | 0x10 | number_integer
|
||||||
|
Timestamp | 0x11 | *unsupported*
|
||||||
|
128-bit decimal float | 0x13 | *unsupported*
|
||||||
|
Max Key | 0x7F | *unsupported*
|
||||||
|
Min Key | 0xFF | *unsupported*
|
||||||
|
|
||||||
|
!!! warning "Incomplete mapping"
|
||||||
|
|
||||||
|
The mapping is **incomplete**. The unsupported mappings are indicated in the table above.
|
||||||
|
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/from_bson.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/from_bson.output"
|
||||||
|
```
|
172
doc/mkdocs/docs/features/binary_formats/cbor.md
Normal file
172
doc/mkdocs/docs/features/binary_formats/cbor.md
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
# CBOR
|
||||||
|
|
||||||
|
The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code size, fairly small message size, and extensibility without the need for version negotiation.
|
||||||
|
|
||||||
|
!!! abstract "References"
|
||||||
|
|
||||||
|
- [CBOR Website](http://cbor.io) - the main source on CBOR
|
||||||
|
- [CBOR Playground](http://cbor.me) - an interactive webpage to translate between JSON and CBOR
|
||||||
|
- [RFC 7049](https://tools.ietf.org/html/rfc7049) - the CBOR specification
|
||||||
|
|
||||||
|
## Serialization
|
||||||
|
|
||||||
|
The library uses the following mapping from JSON values types to CBOR types according to the CBOR specification (RFC 7049):
|
||||||
|
|
||||||
|
JSON value type | value/range | CBOR type | first byte
|
||||||
|
--------------- | ------------------------------------------ | ---------------------------------- | ---------------
|
||||||
|
null | `null` | Null | 0xF6
|
||||||
|
boolean | `true` | True | 0xF5
|
||||||
|
boolean | `false` | False | 0xF4
|
||||||
|
number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
|
||||||
|
number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
|
||||||
|
number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
|
||||||
|
number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
|
||||||
|
number_integer | -24..-1 | Negative integer | 0x20..0x37
|
||||||
|
number_integer | 0..23 | Integer | 0x00..0x17
|
||||||
|
number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
|
||||||
|
number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
|
||||||
|
number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
|
||||||
|
number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
|
||||||
|
number_unsigned | 0..23 | Integer | 0x00..0x17
|
||||||
|
number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
|
||||||
|
number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
|
||||||
|
number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
|
||||||
|
number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
|
||||||
|
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*: 23..255 | UTF-8 string (1 byte follow) | 0x78
|
||||||
|
string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
|
||||||
|
string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
|
||||||
|
string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
|
||||||
|
array | *size*: 0..23 | array | 0x80..0x97
|
||||||
|
array | *size*: 23..255 | array (1 byte follow) | 0x98
|
||||||
|
array | *size*: 256..65535 | array (2 bytes follow) | 0x99
|
||||||
|
array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
|
||||||
|
array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
|
||||||
|
object | *size*: 0..23 | map | 0xA0..0xB7
|
||||||
|
object | *size*: 23..255 | map (1 byte follow) | 0xB8
|
||||||
|
object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
|
||||||
|
object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
|
||||||
|
object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
|
||||||
|
binary | *size*: 0..23 | byte string | 0x40..0x57
|
||||||
|
binary | *size*: 23..255 | byte string (1 byte follow) | 0x58
|
||||||
|
binary | *size*: 256..65535 | byte string (2 bytes follow) | 0x59
|
||||||
|
binary | *size*: 65536..4294967295 | byte string (4 bytes follow) | 0x5A
|
||||||
|
binary | *size*: 4294967296..18446744073709551615 | byte string (8 bytes follow) | 0x5B
|
||||||
|
|
||||||
|
|
||||||
|
!!! success "Complete mapping"
|
||||||
|
|
||||||
|
The mapping is **complete** in the sense that any JSON value type can be converted to a CBOR value.
|
||||||
|
|
||||||
|
!!! info "NaN/infinity handling"
|
||||||
|
|
||||||
|
If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the normal JSON serialization which serializes NaN or Infinity to `null`.
|
||||||
|
|
||||||
|
|
||||||
|
!!! info "Unused CBOR types"
|
||||||
|
|
||||||
|
The following CBOR types are not used in the conversion:
|
||||||
|
|
||||||
|
- UTF-8 strings terminated by "break" (0x7F)
|
||||||
|
- arrays terminated by "break" (0x9F)
|
||||||
|
- maps terminated by "break" (0xBF)
|
||||||
|
- byte strings terminated by "break" (0x5F)
|
||||||
|
- date/time (0xC0..0xC1)
|
||||||
|
- bignum (0xC2..0xC3)
|
||||||
|
- decimal fraction (0xC4)
|
||||||
|
- bigfloat (0xC5)
|
||||||
|
- tagged items (0xC6..0xD4, 0xD8..0xDB)
|
||||||
|
- expected conversions (0xD5..0xD7)
|
||||||
|
- simple values (0xE0..0xF3, 0xF8)
|
||||||
|
- undefined (0xF7)
|
||||||
|
- half-precision floats (0xF9)
|
||||||
|
- break (0xFF)
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/to_cbor.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```c
|
||||||
|
--8<-- "examples/to_cbor.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deserialization
|
||||||
|
|
||||||
|
The library maps CBOR types to JSON value types as follows:
|
||||||
|
|
||||||
|
CBOR type | JSON value type | first byte
|
||||||
|
---------------------- | --------------- | ----------
|
||||||
|
Integer | number_unsigned | 0x00..0x17
|
||||||
|
Unsigned integer | number_unsigned | 0x18
|
||||||
|
Unsigned integer | number_unsigned | 0x19
|
||||||
|
Unsigned integer | number_unsigned | 0x1A
|
||||||
|
Unsigned integer | number_unsigned | 0x1B
|
||||||
|
Negative integer | number_integer | 0x20..0x37
|
||||||
|
Negative integer | number_integer | 0x38
|
||||||
|
Negative integer | number_integer | 0x39
|
||||||
|
Negative integer | number_integer | 0x3A
|
||||||
|
Negative integer | number_integer | 0x3B
|
||||||
|
Byte string | binary | 0x40..0x57
|
||||||
|
Byte string | binary | 0x58
|
||||||
|
Byte string | binary | 0x59
|
||||||
|
Byte string | binary | 0x5A
|
||||||
|
Byte string | binary | 0x5B
|
||||||
|
UTF-8 string | string | 0x60..0x77
|
||||||
|
UTF-8 string | string | 0x78
|
||||||
|
UTF-8 string | string | 0x79
|
||||||
|
UTF-8 string | string | 0x7A
|
||||||
|
UTF-8 string | string | 0x7B
|
||||||
|
UTF-8 string | string | 0x7F
|
||||||
|
array | array | 0x80..0x97
|
||||||
|
array | array | 0x98
|
||||||
|
array | array | 0x99
|
||||||
|
array | array | 0x9A
|
||||||
|
array | array | 0x9B
|
||||||
|
array | array | 0x9F
|
||||||
|
map | object | 0xA0..0xB7
|
||||||
|
map | object | 0xB8
|
||||||
|
map | object | 0xB9
|
||||||
|
map | object | 0xBA
|
||||||
|
map | object | 0xBB
|
||||||
|
map | object | 0xBF
|
||||||
|
False | `false` | 0xF4
|
||||||
|
True | `true` | 0xF5
|
||||||
|
Null | `null` | 0xF6
|
||||||
|
Half-Precision Float | number_float | 0xF9
|
||||||
|
Single-Precision Float | number_float | 0xFA
|
||||||
|
Double-Precision Float | number_float | 0xFB
|
||||||
|
|
||||||
|
!!! warning "Incomplete mapping"
|
||||||
|
|
||||||
|
The mapping is **incomplete** in the sense that not all CBOR types can be converted to a JSON value. The following CBOR types are not supported and will yield parse errors:
|
||||||
|
|
||||||
|
- date/time (0xC0..0xC1)
|
||||||
|
- bignum (0xC2..0xC3)
|
||||||
|
- decimal fraction (0xC4)
|
||||||
|
- bigfloat (0xC5)
|
||||||
|
- tagged items (0xC6..0xD4, 0xD8..0xDB)
|
||||||
|
- expected conversions (0xD5..0xD7)
|
||||||
|
- simple values (0xE0..0xF3, 0xF8)
|
||||||
|
- undefined (0xF7)
|
||||||
|
|
||||||
|
!!! warning "Object keys"
|
||||||
|
|
||||||
|
CBOR allows map keys of any type, whereas JSON only allows strings as keys in object values. Therefore, CBOR maps with keys other than UTF-8 strings are rejected.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/from_cbor.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/from_cbor.output"
|
||||||
|
```
|
45
doc/mkdocs/docs/features/binary_formats/index.md
Normal file
45
doc/mkdocs/docs/features/binary_formats/index.md
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# Overview
|
||||||
|
|
||||||
|
Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports
|
||||||
|
|
||||||
|
- [BSON](bson.md) (Binary JSON),
|
||||||
|
- [CBOR](cbor.md) (Concise Binary Object Representation),
|
||||||
|
- [MessagePack](messagepack.md), and
|
||||||
|
- [UBJSON](ubjson.md) (Universal Binary JSON)
|
||||||
|
|
||||||
|
to efficiently encode JSON values to byte vectors and to decode such vectors.
|
||||||
|
|
||||||
|
## Comparison
|
||||||
|
|
||||||
|
### Completeness
|
||||||
|
|
||||||
|
| Format | Serialization | Deserialization |
|
||||||
|
| ----------- |---------------------------------------------- | -------------------------------------------- |
|
||||||
|
| BSON | incomplete: top-level value must be an object | incomplete, but all JSON types are supported |
|
||||||
|
| CBOR | complete | incomplete, but all JSON types are supported |
|
||||||
|
| MessagePack | complete | complete |
|
||||||
|
| UBJSON | complete | complete |
|
||||||
|
|
||||||
|
### Binary values
|
||||||
|
|
||||||
|
| Format | Binary values | Binary subtypes |
|
||||||
|
| ----------- | ------------- | --------------- |
|
||||||
|
| BSON | supported | supported |
|
||||||
|
| CBOR | supported | not supported |
|
||||||
|
| MessagePack | supported | supported |
|
||||||
|
| UBJSON | not supported | not supported |
|
||||||
|
|
||||||
|
See [binary values](../binary_values.md) for more information.
|
||||||
|
|
||||||
|
### Sizes
|
||||||
|
|
||||||
|
| Format | canada.json | twitter.json | citm_catalog.json | jeopardy.json |
|
||||||
|
| ------------------ | ----------- | ------------ | ----------------- | ------------- |
|
||||||
|
| BSON | 85,8 % | 95,2 % | 95,8 % | 106,7 % |
|
||||||
|
| CBOR | 50,5 % | 86,3 % | 68,4 % | 88,0 % |
|
||||||
|
| MessagePack | 50,6 % | 86,0 % | 68,5 % | 87,9 % |
|
||||||
|
| UBJSON | 53,2 % | 91,3 % | 78,2 % | 96,6 % |
|
||||||
|
| UBJSON (size) | 58,6 % | 92,3 % | 86,8 % | 97,4 % |
|
||||||
|
| UBJSON (size+type) | 55,9 % | 92,3 % | 85,0 % | 95,0 % |
|
||||||
|
|
||||||
|
Sizes compared to minified JSON value.
|
139
doc/mkdocs/docs/features/binary_formats/messagepack.md
Normal file
139
doc/mkdocs/docs/features/binary_formats/messagepack.md
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
# MessagePack
|
||||||
|
|
||||||
|
MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves.
|
||||||
|
|
||||||
|
!!! abstract "References"
|
||||||
|
|
||||||
|
- [MessagePack website](https://msgpack.org)
|
||||||
|
- [MessagePack specification](https://github.com/msgpack/msgpack/blob/master/spec.md)
|
||||||
|
|
||||||
|
## Serialization
|
||||||
|
|
||||||
|
The library uses the following mapping from JSON values types to MessagePack types according to the MessagePack specification:
|
||||||
|
|
||||||
|
JSON value type | value/range | MessagePack type | first byte
|
||||||
|
--------------- | --------------------------------- | ---------------- | ----------
|
||||||
|
null | `null` | nil | 0xC0
|
||||||
|
boolean | `true` | true | 0xC3
|
||||||
|
boolean | `false` | false | 0xC2
|
||||||
|
number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
|
||||||
|
number_integer | -2147483648..-32769 | int32 | 0xD2
|
||||||
|
number_integer | -32768..-129 | int16 | 0xD1
|
||||||
|
number_integer | -128..-33 | int8 | 0xD0
|
||||||
|
number_integer | -32..-1 | negative fixint | 0xE0..0xFF
|
||||||
|
number_integer | 0..127 | positive fixint | 0x00..0x7F
|
||||||
|
number_integer | 128..255 | uint 8 | 0xCC
|
||||||
|
number_integer | 256..65535 | uint 16 | 0xCD
|
||||||
|
number_integer | 65536..4294967295 | uint 32 | 0xCE
|
||||||
|
number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
|
||||||
|
number_unsigned | 0..127 | positive fixint | 0x00..0x7F
|
||||||
|
number_unsigned | 128..255 | uint 8 | 0xCC
|
||||||
|
number_unsigned | 256..65535 | uint 16 | 0xCD
|
||||||
|
number_unsigned | 65536..4294967295 | uint 32 | 0xCE
|
||||||
|
number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
|
||||||
|
number_float | *any value representable by a float* | float 32 | 0xCA
|
||||||
|
number_float | *any value NOT representable by a float* | float 64 | 0xCB
|
||||||
|
string | *length*: 0..31 | fixstr | 0xA0..0xBF
|
||||||
|
string | *length*: 32..255 | str 8 | 0xD9
|
||||||
|
string | *length*: 256..65535 | str 16 | 0xDA
|
||||||
|
string | *length*: 65536..4294967295 | str 32 | 0xDB
|
||||||
|
array | *size*: 0..15 | fixarray | 0x90..0x9F
|
||||||
|
array | *size*: 16..65535 | array 16 | 0xDC
|
||||||
|
array | *size*: 65536..4294967295 | array 32 | 0xDD
|
||||||
|
object | *size*: 0..15 | fix map | 0x80..0x8F
|
||||||
|
object | *size*: 16..65535 | map 16 | 0xDE
|
||||||
|
object | *size*: 65536..4294967295 | map 32 | 0xDF
|
||||||
|
binary | *size*: 0..255 | bin 8 | 0xC4
|
||||||
|
binary | *size*: 256..65535 | bin 16 | 0xC5
|
||||||
|
binary | *size*: 65536..4294967295 | bin 32 | 0xC6
|
||||||
|
|
||||||
|
!!! success "Complete mapping"
|
||||||
|
|
||||||
|
The mapping is **complete** in the sense that any JSON value type can be converted to a MessagePack value.
|
||||||
|
|
||||||
|
Any MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`.
|
||||||
|
|
||||||
|
!!! warning "Size constraints"
|
||||||
|
|
||||||
|
The following values can **not** be converted to a MessagePack value:
|
||||||
|
|
||||||
|
- strings with more than 4294967295 bytes
|
||||||
|
- byte strings with more than 4294967295 bytes
|
||||||
|
- arrays with more than 4294967295 elements
|
||||||
|
- objects with more than 4294967295 elements
|
||||||
|
|
||||||
|
!!! info "NaN/infinity handling"
|
||||||
|
|
||||||
|
If NaN or Infinity are stored inside a JSON number, they are serialized properly. function which serializes NaN or Infinity to `null`.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/to_msgpack.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```c
|
||||||
|
--8<-- "examples/to_msgpack.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deserialization
|
||||||
|
|
||||||
|
The library maps MessagePack types to JSON value types as follows:
|
||||||
|
|
||||||
|
MessagePack type | JSON value type | first byte
|
||||||
|
---------------- | --------------- | ----------
|
||||||
|
positive fixint | number_unsigned | 0x00..0x7F
|
||||||
|
fixmap | object | 0x80..0x8F
|
||||||
|
fixarray | array | 0x90..0x9F
|
||||||
|
fixstr | string | 0xA0..0xBF
|
||||||
|
nil | `null` | 0xC0
|
||||||
|
false | `false` | 0xC2
|
||||||
|
true | `true` | 0xC3
|
||||||
|
float 32 | number_float | 0xCA
|
||||||
|
float 64 | number_float | 0xCB
|
||||||
|
uint 8 | number_unsigned | 0xCC
|
||||||
|
uint 16 | number_unsigned | 0xCD
|
||||||
|
uint 32 | number_unsigned | 0xCE
|
||||||
|
uint 64 | number_unsigned | 0xCF
|
||||||
|
int 8 | number_integer | 0xD0
|
||||||
|
int 16 | number_integer | 0xD1
|
||||||
|
int 32 | number_integer | 0xD2
|
||||||
|
int 64 | number_integer | 0xD3
|
||||||
|
str 8 | string | 0xD9
|
||||||
|
str 16 | string | 0xDA
|
||||||
|
str 32 | string | 0xDB
|
||||||
|
array 16 | array | 0xDC
|
||||||
|
array 32 | array | 0xDD
|
||||||
|
map 16 | object | 0xDE
|
||||||
|
map 32 | object | 0xDF
|
||||||
|
bin 8 | binary | 0xC4
|
||||||
|
bin 16 | binary | 0xC5
|
||||||
|
bin 32 | binary | 0xC6
|
||||||
|
ext 8 | binary | 0xC7
|
||||||
|
ext 16 | binary | 0xC8
|
||||||
|
ext 32 | binary | 0xC9
|
||||||
|
fixext 1 | binary | 0xD4
|
||||||
|
fixext 2 | binary | 0xD5
|
||||||
|
fixext 4 | binary | 0xD6
|
||||||
|
fixext 8 | binary | 0xD7
|
||||||
|
fixext 16 | binary | 0xD8
|
||||||
|
negative fixint | number_integer | 0xE0-0xFF
|
||||||
|
|
||||||
|
!!! info
|
||||||
|
|
||||||
|
Any MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`.
|
||||||
|
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/from_msgpack.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/from_msgpack.output"
|
||||||
|
```
|
133
doc/mkdocs/docs/features/binary_formats/ubjson.md
Normal file
133
doc/mkdocs/docs/features/binary_formats/ubjson.md
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
# UBJSON
|
||||||
|
|
||||||
|
Universal Binary JSON (UBJSON) is a binary form directly imitating JSON, but requiring fewer bytes of data. It aims to achieve the generality of JSON, combined with being much easier to process than JSON.
|
||||||
|
|
||||||
|
!!! abstract "References"
|
||||||
|
|
||||||
|
- [UBJSON Website](http://ubjson.org)
|
||||||
|
|
||||||
|
## Serialization
|
||||||
|
|
||||||
|
The library uses the following mapping from JSON values types to UBJSON types according to the UBJSON specification:
|
||||||
|
|
||||||
|
JSON value type | value/range | UBJSON type | marker
|
||||||
|
--------------- | --------------------------------- | ----------- | ------
|
||||||
|
null | `null` | null | `Z`
|
||||||
|
boolean | `true` | true | `T`
|
||||||
|
boolean | `false` | false | `F`
|
||||||
|
number_integer | -9223372036854775808..-2147483649 | int64 | `L`
|
||||||
|
number_integer | -2147483648..-32769 | int32 | `l`
|
||||||
|
number_integer | -32768..-129 | int16 | `I`
|
||||||
|
number_integer | -128..127 | int8 | `i`
|
||||||
|
number_integer | 128..255 | uint8 | `U`
|
||||||
|
number_integer | 256..32767 | int16 | `I`
|
||||||
|
number_integer | 32768..2147483647 | int32 | `l`
|
||||||
|
number_integer | 2147483648..9223372036854775807 | int64 | `L`
|
||||||
|
number_unsigned | 0..127 | int8 | `i`
|
||||||
|
number_unsigned | 128..255 | uint8 | `U`
|
||||||
|
number_unsigned | 256..32767 | int16 | `I`
|
||||||
|
number_unsigned | 32768..2147483647 | int32 | `l`
|
||||||
|
number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
|
||||||
|
number_float | *any value* | float64 | `D`
|
||||||
|
string | *with shortest length indicator* | string | `S`
|
||||||
|
array | *see notes on optimized format* | array | `[`
|
||||||
|
object | *see notes on optimized format* | map | `{`
|
||||||
|
|
||||||
|
!!! success "Complete mapping"
|
||||||
|
|
||||||
|
The mapping is **complete** in the sense that any JSON value type can be converted to a UBJSON value.
|
||||||
|
|
||||||
|
Any UBJSON output created by `to_ubjson` can be successfully parsed by `from_ubjson`.
|
||||||
|
|
||||||
|
!!! warning "Size constraints"
|
||||||
|
|
||||||
|
The following values can **not** be converted to a UBJSON value:
|
||||||
|
|
||||||
|
- strings with more than 9223372036854775807 bytes (theoretical)
|
||||||
|
- unsigned integer numbers above 9223372036854775807
|
||||||
|
|
||||||
|
!!! info "Unused UBJSON markers"
|
||||||
|
|
||||||
|
The following markers are not used in the conversion:
|
||||||
|
|
||||||
|
- `Z`: no-op values are not created.
|
||||||
|
- `C`: single-byte strings are serialized with `S` markers.
|
||||||
|
|
||||||
|
!!! info "NaN/infinity handling"
|
||||||
|
|
||||||
|
If NaN or Infinity are stored inside a JSON number, they are
|
||||||
|
serialized properly. This behavior differs from the `dump()`
|
||||||
|
function which serializes NaN or Infinity to `null`.
|
||||||
|
|
||||||
|
!!! info "Optimized formats"
|
||||||
|
|
||||||
|
The optimized formats for containers are supported: Parameter
|
||||||
|
`use_size` adds size information to the beginning of a container and
|
||||||
|
removes the closing marker. Parameter `use_type` further checks
|
||||||
|
whether all elements of a container have the same type and adds the
|
||||||
|
type marker to the beginning of the container. The `use_type`
|
||||||
|
parameter must only be used together with `use_size = true`.
|
||||||
|
|
||||||
|
Note that `use_size = true` alone may result in larger representations -
|
||||||
|
the benefit of this parameter is that the receiving side is
|
||||||
|
immediately informed on the number of elements of the container.
|
||||||
|
|
||||||
|
!!! info "Binary values"
|
||||||
|
|
||||||
|
If the JSON data contains the binary type, the value stored is a list
|
||||||
|
of integers, as suggested by the UBJSON documentation. In particular,
|
||||||
|
this means that serialization and the deserialization of a JSON
|
||||||
|
containing binary values into UBJSON and back will result in a
|
||||||
|
different JSON object.
|
||||||
|
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/to_ubjson.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```c
|
||||||
|
--8<-- "examples/to_ubjson.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deserialization
|
||||||
|
|
||||||
|
The library maps UBJSON types to JSON value types as follows:
|
||||||
|
|
||||||
|
UBJSON type | JSON value type | marker
|
||||||
|
----------- | --------------------------------------- | ------
|
||||||
|
no-op | *no value, next value is read* | `N`
|
||||||
|
null | `null` | `Z`
|
||||||
|
false | `false` | `F`
|
||||||
|
true | `true` | `T`
|
||||||
|
float32 | number_float | `d`
|
||||||
|
float64 | number_float | `D`
|
||||||
|
uint8 | number_unsigned | `U`
|
||||||
|
int8 | number_integer | `i`
|
||||||
|
int16 | number_integer | `I`
|
||||||
|
int32 | number_integer | `l`
|
||||||
|
int64 | number_integer | `L`
|
||||||
|
string | string | `S`
|
||||||
|
char | string | `C`
|
||||||
|
array | array (optimized values are supported) | `[`
|
||||||
|
object | object (optimized values are supported) | `{`
|
||||||
|
|
||||||
|
!!! success "Complete mapping"
|
||||||
|
|
||||||
|
The mapping is **complete** in the sense that any UBJSON value can be converted to a JSON value.
|
||||||
|
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/from_ubjson.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/from_ubjson.output"
|
||||||
|
```
|
294
doc/mkdocs/docs/features/binary_values.md
Normal file
294
doc/mkdocs/docs/features/binary_values.md
Normal file
|
@ -0,0 +1,294 @@
|
||||||
|
# Binary Values
|
||||||
|
|
||||||
|
The library implements several [binary formats](binary_formats/index.md) that encode JSON in an efficient way. Most of these formats support binary values; that is, values that have semantics define outside the library and only define a sequence of bytes to be stored.
|
||||||
|
|
||||||
|
JSON itself does not have a binary value. As such, binary values are an extension that this library implements to store values received by a binary format. Binary values are never created by the JSON parser, and are only part of a serialized JSON text if they have been created manually or via a binary format.
|
||||||
|
|
||||||
|
## API for binary values
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
class json::binary_t {
|
||||||
|
-- setters --
|
||||||
|
+void set_subtype(std::uint8_t subtype)
|
||||||
|
+void clear_subtype()
|
||||||
|
-- getters --
|
||||||
|
+std::uint8_t subtype() const
|
||||||
|
+bool has_subtype() const
|
||||||
|
}
|
||||||
|
|
||||||
|
"std::vector<uint8_t>" <|-- json::binary_t
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, binary values are stored as `std::vector<std::uint8_t>`. This type can be changed by providing a template parameter to the `basic_json` type. To store binary subtypes, the storage type is extended and exposed as `json::binary_t`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
auto binary = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE});
|
||||||
|
auto binary_with_subtype = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE}, 42);
|
||||||
|
```
|
||||||
|
|
||||||
|
There are several convenience functions to check and set the subtype:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
binary.has_subtype(); // returns false
|
||||||
|
binary_with_subtype.has_subtype(); // returns true
|
||||||
|
|
||||||
|
binary_with_subtype.clear_subtype();
|
||||||
|
binary_with_subtype.has_subtype(); // returns true
|
||||||
|
|
||||||
|
binary_with_subtype.set_subtype(42);
|
||||||
|
binary.set_subtype(23);
|
||||||
|
|
||||||
|
binary.subtype(); // returns 23
|
||||||
|
```
|
||||||
|
|
||||||
|
As `json::binary_t` is subclassing `std::vector<std::uint8_t>`, all member functions are available:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
binary.size(); // returns 4
|
||||||
|
binary[1]; // returns 0xFE
|
||||||
|
```
|
||||||
|
|
||||||
|
JSON values can be constructed from `json::binary_t`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
json j = binary;
|
||||||
|
```
|
||||||
|
|
||||||
|
Binary values are primitive values just like numbers or strings:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
j.is_binary(); // returns true
|
||||||
|
j.is_primitive(); // returns true
|
||||||
|
```
|
||||||
|
|
||||||
|
Given a binary JSON value, the `binary_t` can be accessed by reference as via `get_binary()`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
j.get_binary().has_subtype(); // returns true
|
||||||
|
j.get_binary().size(); // returns 4
|
||||||
|
```
|
||||||
|
|
||||||
|
For convencience, binary JSON values can be constructed via `json::binary`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
auto j2 = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 23);
|
||||||
|
auto j3 = json::binary({0xCA, 0xFE, 0xBA, 0xBE});
|
||||||
|
|
||||||
|
j2 == j; // returns true
|
||||||
|
j3.get_binary().has_subtype(); // returns false
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Serialization
|
||||||
|
|
||||||
|
Binary values are serialized differently according to the formats.
|
||||||
|
|
||||||
|
### JSON
|
||||||
|
|
||||||
|
JSON does not have a binary type, and this library does not introduce a new type as this would break conformance. Instead, binary values are serialized as an object with two keys: `bytes` holds an array of integers, and `subtype` is an integer or `null`.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// create a binary value of subtype 42
|
||||||
|
json j;
|
||||||
|
j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);
|
||||||
|
|
||||||
|
// serialize to standard output
|
||||||
|
std::cout << j.dump(2) << std::endl;
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"binary": {
|
||||||
|
"bytes": [202, 254, 186, 190],
|
||||||
|
"subtype": 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! warning "No roundtrip for binary values"
|
||||||
|
|
||||||
|
The JSON parser will not parse the objects generated by binary values back to binary values. This is by design to remain standards compliant. Serializing binary values to JSON is only implemented for debugging purposes.
|
||||||
|
|
||||||
|
### BSON
|
||||||
|
|
||||||
|
[BSON](binary_formats/bson.md) supports binary values and subtypes. 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.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// create a binary value of subtype 42
|
||||||
|
json j;
|
||||||
|
j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);
|
||||||
|
|
||||||
|
// convert to BSON
|
||||||
|
auto v = json::to_bson(j);
|
||||||
|
```
|
||||||
|
|
||||||
|
`v` is a `std::vector<std::uint8t>` with the following 22 elements:
|
||||||
|
|
||||||
|
```c
|
||||||
|
0x16 0x00 0x00 0x00 // number of bytes in the document
|
||||||
|
0x05 // binary value
|
||||||
|
0x62 0x69 0x6E 0x61 0x72 0x79 0x00 // key "binary" + null byte
|
||||||
|
0x04 0x00 0x00 0x00 // number of bytes
|
||||||
|
0x2a // subtype
|
||||||
|
0xCA 0xFE 0xBA 0xBE // content
|
||||||
|
0x00 // end of the document
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the serialization preserves the subtype, and deserializing `v` would yield the following value:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"binary": {
|
||||||
|
"bytes": [202, 254, 186, 190],
|
||||||
|
"subtype": 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### CBOR
|
||||||
|
|
||||||
|
[CBOR](binary_formats/cbor.md) supports binary values, but no subtypes. Any binary value will be serialized as byte strings. The library will choose the smallest representation using the length of the byte array.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// create a binary value of subtype 42 (will be ignored by CBOR)
|
||||||
|
json j;
|
||||||
|
j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);
|
||||||
|
|
||||||
|
// convert to CBOR
|
||||||
|
auto v = json::to_cbor(j);
|
||||||
|
```
|
||||||
|
|
||||||
|
`v` is a `std::vector<std::uint8t>` with the following 13 elements:
|
||||||
|
|
||||||
|
```c
|
||||||
|
0xA1 // map(1)
|
||||||
|
0x66 // text(6)
|
||||||
|
0x62 0x69 0x6E 0x61 0x72 0x79 // "binary"
|
||||||
|
0x44 // bytes(4)
|
||||||
|
0xCA 0xFE 0xBA 0xBE // content
|
||||||
|
```
|
||||||
|
|
||||||
|
Note the subtype (42) is **not** serialized, and deserializing `v` would yield the following value:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"binary": {
|
||||||
|
"bytes": [202, 254, 186, 190],
|
||||||
|
"subtype": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### MessagePack
|
||||||
|
|
||||||
|
[MessagePack](binary_formats/messagepack.md) supports binary values and subtypes. If a subtype is given, the ext family is used. The library will choose the smallest representation among fixext1, fixext2, fixext4, fixext8, ext8, ext16, and ext32. The subtype is then added as singed 8-bit integer.
|
||||||
|
|
||||||
|
If no subtype is given, the bin family (bin8, bin16, bin32) is used.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// create a binary value of subtype 42
|
||||||
|
json j;
|
||||||
|
j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);
|
||||||
|
|
||||||
|
// convert to MessagePack
|
||||||
|
auto v = json::to_msgpack(j);
|
||||||
|
```
|
||||||
|
|
||||||
|
`v` is a `std::vector<std::uint8t>` with the following 14 elements:
|
||||||
|
|
||||||
|
```c
|
||||||
|
0x81 // fixmap1
|
||||||
|
0xA6 // fixstr6
|
||||||
|
0x62 0x69 0x6E 0x61 0x72 0x79 // "binary"
|
||||||
|
0xD6 // fixext4
|
||||||
|
0x2A // subtype
|
||||||
|
0xCA 0xFE 0xBA 0xBE // content
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the serialization preserves the subtype, and deserializing `v` would yield the following value:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"binary": {
|
||||||
|
"bytes": [202, 254, 186, 190],
|
||||||
|
"subtype": 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### UBJSON
|
||||||
|
|
||||||
|
[UBJSON](binary_formats/ubjson.md) neither supports binary values nor subtypes, and proposes to serialize binary values as array of uint8 values. This translation is implemented by the library.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// create a binary value of subtype 42 (will be ignored in UBJSON)
|
||||||
|
json j;
|
||||||
|
j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);
|
||||||
|
|
||||||
|
// convert to UBJSON
|
||||||
|
auto v = json::to_msgpack(j);
|
||||||
|
```
|
||||||
|
|
||||||
|
`v` is a `std::vector<std::uint8t>` with the following 20 elements:
|
||||||
|
|
||||||
|
```c
|
||||||
|
0x7B // '{'
|
||||||
|
0x69 0x06 // i 6 (length of the key)
|
||||||
|
0x62 0x69 0x6E 0x61 0x72 0x79 // "binary"
|
||||||
|
0x5B // '['
|
||||||
|
0x55 0xCA 0x55 0xFE 0x55 0xBA 0x55 0xBE // content (each byte prefixed with 'U')
|
||||||
|
0x5D // ']'
|
||||||
|
0x7D // '}'
|
||||||
|
```
|
||||||
|
|
||||||
|
The following code uses the type and size optimization for UBJSON:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// convert to UBJSON using the size and type optimization
|
||||||
|
auto v = json::to_ubjson(j, true, true);
|
||||||
|
```
|
||||||
|
|
||||||
|
The resulting vector has 23 elements; the optimization is not effective for examples with few values:
|
||||||
|
|
||||||
|
```c
|
||||||
|
0x7B // '{'
|
||||||
|
0x24 // '$' type of the object elements
|
||||||
|
0x5B // '[' array
|
||||||
|
0x23 0x69 0x01 // '#' i 1 number of object elements
|
||||||
|
0x69 0x06 // i 6 (length of the key)
|
||||||
|
0x62 0x69 0x6E 0x61 0x72 0x79 // "binary"
|
||||||
|
0x24 0x55 // '$' 'U' type of the array elements: unsinged integers
|
||||||
|
0x23 0x69 0x04 // '#' i 4 number of array elements
|
||||||
|
0xCA 0xFE 0xBA 0xBE // content
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that subtype (42) is **not** serialized and that UBJSON has **no binary type**, and deserializing `v` would yield the following value:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"binary": [202, 254, 186, 190]
|
||||||
|
}
|
||||||
|
```
|
53
doc/mkdocs/docs/features/enum_conversion.md
Normal file
53
doc/mkdocs/docs/features/enum_conversion.md
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# Specializing enum conversion
|
||||||
|
|
||||||
|
By default, enum values are serialized to JSON as integers. In some cases this could result in undesired behavior. If an enum is modified or re-ordered after data has been serialized to JSON, the later de-serialized JSON data may be undefined or a different enum value than was originally intended.
|
||||||
|
|
||||||
|
It is possible to more precisely specify how a given enum is mapped to and from JSON as shown below:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// example enum type declaration
|
||||||
|
enum TaskState {
|
||||||
|
TS_STOPPED,
|
||||||
|
TS_RUNNING,
|
||||||
|
TS_COMPLETED,
|
||||||
|
TS_INVALID=-1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// map TaskState values to JSON as strings
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM( TaskState, {
|
||||||
|
{TS_INVALID, nullptr},
|
||||||
|
{TS_STOPPED, "stopped"},
|
||||||
|
{TS_RUNNING, "running"},
|
||||||
|
{TS_COMPLETED, "completed"},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
The `NLOHMANN_JSON_SERIALIZE_ENUM()` macro declares a set of `to_json()` / `from_json()` functions for type `TaskState` while avoiding repetition and boilerplate serialization code.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// enum to JSON as string
|
||||||
|
json j = TS_STOPPED;
|
||||||
|
assert(j == "stopped");
|
||||||
|
|
||||||
|
// json string to enum
|
||||||
|
json j3 = "running";
|
||||||
|
assert(j3.get<TaskState>() == TS_RUNNING);
|
||||||
|
|
||||||
|
// undefined json value to enum (where the first map entry above is the default)
|
||||||
|
json jPi = 3.14;
|
||||||
|
assert(jPi.get<TaskState>() == TS_INVALID );
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Just as in [Arbitrary Type Conversions](#arbitrary-types-conversions) above,
|
||||||
|
|
||||||
|
- `NLOHMANN_JSON_SERIALIZE_ENUM()` MUST be declared in your enum type's namespace (which can be the global namespace), or the library will not be able to locate it and it will default to integer serialization.
|
||||||
|
- It MUST be available (e.g., proper headers must be included) everywhere you use the conversions.
|
||||||
|
|
||||||
|
Other Important points:
|
||||||
|
|
||||||
|
- When using `get<ENUM_TYPE>()`, undefined JSON values will default to the first pair specified in your map. Select this default pair carefully.
|
||||||
|
- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.
|
155
doc/mkdocs/docs/features/iterators.md
Normal file
155
doc/mkdocs/docs/features/iterators.md
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
# Iterators
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
A `basic_json` value is a container and allows access via iterators. Depending on the value type, `basic_json` stores zero or more values.
|
||||||
|
|
||||||
|
As for other containers, `begin()` returns an iterator to the first value and `end()` returns an iterator to the value following the last value. The latter iterator is a placeholder and cannot be dereferenced. In case of null values, empty arrays, or empty objects, `begin()` will return `end()`.
|
||||||
|
|
||||||
|
![Illustration from cppreference.com](../images/range-begin-end.svg)
|
||||||
|
|
||||||
|
### Iteration order for objects
|
||||||
|
|
||||||
|
When iterating over objects, values are ordered with respect to the `object_comparator_t` type which defaults to `std::less`. See the [types documentation](types.md#key-order) for more information.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// create JSON object {"one": 1, "two": 2, "three": 3}
|
||||||
|
json j;
|
||||||
|
j["one"] = 1;
|
||||||
|
j["two"] = 2;
|
||||||
|
j["three"] = 3;
|
||||||
|
|
||||||
|
for (auto it = j.begin(); it != j.end(); ++it)
|
||||||
|
{
|
||||||
|
std::cout << *it << std::endl;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
1
|
||||||
|
3
|
||||||
|
2
|
||||||
|
```
|
||||||
|
|
||||||
|
The reason for the order is the lexicographic ordering of the object keys "one", "three", "two".
|
||||||
|
|
||||||
|
### Access object key during iteration
|
||||||
|
|
||||||
|
The JSON iterators have two member functions, `key()` and `value()` to access the object key and stored value, respectively. When calling `key()` on a non-object iterator, an [invalid_iterator.207](../home/exceptions.md#jsonexceptioninvalid_iterator207) exception is thrown.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// create JSON object {"one": 1, "two": 2, "three": 3}
|
||||||
|
json j;
|
||||||
|
j["one"] = 1;
|
||||||
|
j["two"] = 2;
|
||||||
|
j["three"] = 3;
|
||||||
|
|
||||||
|
for (auto it = j.begin(); it != j.end(); ++it)
|
||||||
|
{
|
||||||
|
std::cout << it.key() << " : " << it.value() << std::endl;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
one : 1
|
||||||
|
three : 3
|
||||||
|
two : 2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Range-based for loops
|
||||||
|
|
||||||
|
C++11 allows to use range-based for loops to iterate over a container.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
for (auto it : j_object)
|
||||||
|
{
|
||||||
|
// "it" is of type json::reference and has no key() member
|
||||||
|
std::cout << "value: " << it << '\n';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For this reason, the `items()` function allows to access `iterator::key()` and `iterator::value()` during range-based for loops. In these loops, a reference to the JSON values is returned, so there is no access to the underlying iterator.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
for (auto& el : j_object.items())
|
||||||
|
{
|
||||||
|
std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The items() function also allows to use structured bindings (C++17):
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
for (auto& [key, val] : j_object.items())
|
||||||
|
{
|
||||||
|
std::cout << "key: " << key << ", value:" << val << '\n';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
When iterating over an array, `key()` will return the index of the element as string. For primitive types (e.g., numbers), `key()` returns an empty string.
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
|
||||||
|
Using `items()` on temporary objects is dangerous. Make sure the object's lifetime exeeds the iteration. See <https://github.com/nlohmann/json/issues/2040> for more information.
|
||||||
|
|
||||||
|
### Reverse iteration order
|
||||||
|
|
||||||
|
`rbegin()` and `rend()` return iterators in the reverse sequence.
|
||||||
|
|
||||||
|
![Illustration from cppreference.com](../images/range-rbegin-rend.svg)
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
json j = {1, 2, 3, 4};
|
||||||
|
|
||||||
|
for (auto it = j.begin(); it != j.end(); ++it)
|
||||||
|
{
|
||||||
|
std::cout << *it << std::endl;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
4
|
||||||
|
3
|
||||||
|
2
|
||||||
|
1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Iterating strings and binary values
|
||||||
|
|
||||||
|
Note that "value" means a JSON value in this setting, not values stored in the underlying containers. That is, `*begin()` returns the complete string or binary array and is also safe the underlying string or binary array is empty.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
json j = "Hello, world";
|
||||||
|
for (auto it = j.begin(); it != j.end(); ++it)
|
||||||
|
{
|
||||||
|
std::cout << *it << std::endl;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"Hello, world"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Iterator invalidation
|
||||||
|
|
||||||
|
| Operations | invalidated iterators |
|
||||||
|
| ---------- | --------------------- |
|
||||||
|
| `clear` | all |
|
45
doc/mkdocs/docs/features/json_patch.md
Normal file
45
doc/mkdocs/docs/features/json_patch.md
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# JSON Patch and Diff
|
||||||
|
|
||||||
|
## Patches
|
||||||
|
|
||||||
|
JSON Patch ([RFC 6902](https://tools.ietf.org/html/rfc6902)) defines a JSON document structure for expressing a sequence of operations to apply to a JSON) document. With the `patch` function, a JSON Patch is applied to the current JSON value by executing all operations from the patch.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The following code shows how a JSON patch is applied to a value.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/patch.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/patch.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Diff
|
||||||
|
|
||||||
|
The library can also calculate a JSON patch (i.e., a **diff**) given two JSON values.
|
||||||
|
|
||||||
|
!!! success "Invariant"
|
||||||
|
|
||||||
|
For two JSON values *source* and *target*, the following code yields always true:
|
||||||
|
|
||||||
|
```cüü
|
||||||
|
source.patch(diff(source, target)) == target;
|
||||||
|
```
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The following code shows how a JSON patch is created as a diff for two JSON values.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/diff.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/diff.output"
|
||||||
|
```
|
15
doc/mkdocs/docs/features/json_pointer.md
Normal file
15
doc/mkdocs/docs/features/json_pointer.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# JSON Pointer
|
||||||
|
|
||||||
|
The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address structured values.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// a JSON value
|
||||||
|
json j_original = R"({
|
||||||
|
"baz": ["one", "two", "three"],
|
||||||
|
"foo": "bar"
|
||||||
|
})"_json;
|
||||||
|
|
||||||
|
// access members with a JSON pointer (RFC 6901)
|
||||||
|
j_original["/baz/1"_json_pointer];
|
||||||
|
// "two"
|
||||||
|
```
|
20
doc/mkdocs/docs/features/merge_patch.md
Normal file
20
doc/mkdocs/docs/features/merge_patch.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# JSON Merge Patch
|
||||||
|
|
||||||
|
The library supports JSON Merge Patch ([RFC 7386](https://tools.ietf.org/html/rfc7386)) as a patch format.
|
||||||
|
The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of modifications to a target resource's content. This function applies a merge patch to the current JSON value.
|
||||||
|
|
||||||
|
Instead of using [JSON Pointer](json_pointer.md) to specify values to be manipulated, it describes the changes using a syntax that closely mimics the document being modified.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The following code shows how a JSON Merge Patch is applied to a JSON document.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/merge_patch.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/merge_patch.output"
|
||||||
|
```
|
13
doc/mkdocs/docs/features/parsing/index.md
Normal file
13
doc/mkdocs/docs/features/parsing/index.md
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# Overview
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
This page is under construction.
|
||||||
|
|
||||||
|
## Input
|
||||||
|
|
||||||
|
## SAX vs. DOM parsing
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
See [parsing and exceptions](parse_exceptions.md).
|
114
doc/mkdocs/docs/features/parsing/parse_exceptions.md
Normal file
114
doc/mkdocs/docs/features/parsing/parse_exceptions.md
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
# Parsing and exceptions
|
||||||
|
|
||||||
|
When the input is not valid JSON, an exception of type [`parse_error`](../../home/exceptions.md#parse-errors) is thrown. This exception contains the position in the input where the error occurred, together with a diagnostic message and the last read input token. The exceptions page contains a [list of examples for parse error exceptions](../../home/exceptions.md#parse-errors). In case you process untrusted input, always enclose your code with a `#!cpp try`/`#!cpp catch` block, like
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
json j;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
j = json::parse(my_input);
|
||||||
|
}
|
||||||
|
catch (json::exception::parse_error& ex)
|
||||||
|
{
|
||||||
|
std::cerr << "parse error at byte " << ex.byte << std::endl;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In case exceptions are undesired or not supported by the environment, there are different ways to proceed:
|
||||||
|
|
||||||
|
|
||||||
|
## Switch off exceptions
|
||||||
|
|
||||||
|
The `parse()` function accepts as last parameter a `#!cpp bool` variable `allow_exceptions` which controls whether an exception is thrown when a parse error occurs (`#!cpp true`, default) or whether a discarded value should be returned (`#!cpp false`).
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
json j = json::parse(my_input, nullptr, false);
|
||||||
|
if (j.is_discarded())
|
||||||
|
{
|
||||||
|
std::cerr << "parse error" << std::endl;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note there is no diagnostic information available in this scenario.
|
||||||
|
|
||||||
|
## Use accept() function
|
||||||
|
|
||||||
|
Alternatively, function `accept()` can be used which does not return a `json` value, but a `#!cpp bool` indicating whether the input is valid JSON.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
if (!json::accept(my_input))
|
||||||
|
{
|
||||||
|
std::cerr << "parse error" << std::endl;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Again, there is no diagnostic information available.
|
||||||
|
|
||||||
|
|
||||||
|
## User-defined SAX interface
|
||||||
|
|
||||||
|
Finally, you can implement the [SAX interface](sax_interface.md) and decide what should happen in case of a parse error.
|
||||||
|
|
||||||
|
This function has the following interface:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
bool parse_error(std::size_t position,
|
||||||
|
const std::string& last_token,
|
||||||
|
const json::exception& ex);
|
||||||
|
```
|
||||||
|
|
||||||
|
The return value indicates whether the parsing should continue, so the function should usually return `#!cpp false`.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <iostream>
|
||||||
|
#include "json.hpp"
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
class sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sax_no_exception(json& j)
|
||||||
|
: nlohmann::detail::json_sax_dom_parser<json>(j, false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool parse_error(std::size_t position,
|
||||||
|
const std::string& last_token,
|
||||||
|
const json::exception& ex)
|
||||||
|
{
|
||||||
|
std::cerr << "parse error at input byte " << position << "\n"
|
||||||
|
<< ex.what() << "\n"
|
||||||
|
<< "last read: \"" << last_token << "\""
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::string myinput = "[1,2,3,]";
|
||||||
|
|
||||||
|
json result;
|
||||||
|
sax_no_exception sax(result);
|
||||||
|
|
||||||
|
bool parse_result = json::sax_parse(myinput, &sax);
|
||||||
|
if (!parse_result)
|
||||||
|
{
|
||||||
|
std::cerr << "parsing unsuccessful!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "parsed value: " << result << std::endl;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
parse error at input byte 8
|
||||||
|
[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal
|
||||||
|
last read: "3,]"
|
||||||
|
parsing unsuccessful!
|
||||||
|
parsed value: [1,2,3]
|
||||||
|
```
|
79
doc/mkdocs/docs/features/parsing/parser_callbacks.md
Normal file
79
doc/mkdocs/docs/features/parsing/parser_callbacks.md
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
# Parser Callbacks
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
With a parser callback function, the result of parsing a JSON text can be influenced. When passed to `parse`, it is called on certain events
|
||||||
|
(passed as `parse_event_t` via parameter `event`) with a set recursion depth `depth` and context JSON value `parsed`. The return value of the
|
||||||
|
callback function is a boolean indicating whether the element that emitted the callback shall be kept or not.
|
||||||
|
|
||||||
|
The type of the callback function is:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
using parser_callback_t =
|
||||||
|
std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Callback event types
|
||||||
|
|
||||||
|
We distinguish six scenarios (determined by the event type) in which the callback function can be called. The following table describes the values
|
||||||
|
of the parameters `depth`, `event`, and `parsed`.
|
||||||
|
|
||||||
|
parameter `event` | description | parameter `depth` | parameter `parsed`
|
||||||
|
------------------ | ----------- | ------------------ | -------------------
|
||||||
|
`parse_event_t::object_start` | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded
|
||||||
|
`parse_event_t::key` | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key
|
||||||
|
`parse_event_t::object_end` | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object
|
||||||
|
`parse_event_t::array_start` | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded
|
||||||
|
`parse_event_t::array_end` | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array
|
||||||
|
`parse_event_t::value` | the parser finished reading a JSON value | depth of the value | the parsed JSON value
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
When parsing the following JSON text,
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Berlin",
|
||||||
|
"location": [
|
||||||
|
52.519444,
|
||||||
|
13.406667
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
these calls are made to the callback function:
|
||||||
|
|
||||||
|
| event | depth | parsed |
|
||||||
|
| -------------- | ----- | ------ |
|
||||||
|
| `object_start` | 0 | *discarded* |
|
||||||
|
| `key` | 1 | `#!json "name"` |
|
||||||
|
| `value` | 1 | `#!json "Berlin"` |
|
||||||
|
| `key` | 1 | `#!json "location"` |
|
||||||
|
| `array_start` | 1 | *discarded* |
|
||||||
|
| `value` | 2 | `#!json 52.519444` |
|
||||||
|
| `value` | 2 | `#!json 13.406667` |
|
||||||
|
| `array_end` | 1 | `#!json [52.519444,13.406667]` |
|
||||||
|
| `object_end` | 0 | `#!json {"location":[52.519444,13.406667],"name":"Berlin"}` |
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
Discarding a value (i.e., returning `#!c false`) has different effects depending on the context in which function was called:
|
||||||
|
|
||||||
|
- Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never read.
|
||||||
|
- In case a value outside a structured type is skipped, it is replaced with `#!json null`. This case happens if the top-level element is skipped.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below demonstrates the `parse()` function with and without callback function.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/parse__string__parser_callback_t.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/parse__string__parser_callback_t.output"
|
||||||
|
```
|
65
doc/mkdocs/docs/features/parsing/sax_interface.md
Normal file
65
doc/mkdocs/docs/features/parsing/sax_interface.md
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
# SAX Interface
|
||||||
|
|
||||||
|
The library uses a SAX-like interface with the following functions:
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
interface json::sax_t {
|
||||||
|
+ {abstract} bool null()
|
||||||
|
|
||||||
|
+ {abstract} bool boolean(bool val)
|
||||||
|
|
||||||
|
+ {abstract} bool number_integer(number_integer_t val)
|
||||||
|
+ {abstract} bool number_unsigned(number_unsigned_t val)
|
||||||
|
|
||||||
|
+ {abstract} bool number_float(number_float_t val, const string_t& s)
|
||||||
|
|
||||||
|
+ {abstract} bool string(string_t& val)
|
||||||
|
|
||||||
|
+ {abstract} bool start_object(std::size_t elements)
|
||||||
|
+ {abstract} bool end_object()
|
||||||
|
+ {abstract} bool start_array(std::size_t elements)
|
||||||
|
+ {abstract} bool end_array()
|
||||||
|
+ {abstract} bool key(string_t& val)
|
||||||
|
|
||||||
|
+ {abstract} bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// called when null is parsed
|
||||||
|
bool null();
|
||||||
|
|
||||||
|
// called when a boolean is parsed; value is passed
|
||||||
|
bool boolean(bool val);
|
||||||
|
|
||||||
|
// called when a signed or unsigned integer number is parsed; value is passed
|
||||||
|
bool number_integer(number_integer_t val);
|
||||||
|
bool number_unsigned(number_unsigned_t val);
|
||||||
|
|
||||||
|
// called when a floating-point number is parsed; value and original string is passed
|
||||||
|
bool number_float(number_float_t val, const string_t& s);
|
||||||
|
|
||||||
|
// called when a string is parsed; value is passed and can be safely moved away
|
||||||
|
bool string(string_t& val);
|
||||||
|
|
||||||
|
// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known)
|
||||||
|
bool start_object(std::size_t elements);
|
||||||
|
bool end_object();
|
||||||
|
bool start_array(std::size_t elements);
|
||||||
|
bool end_array();
|
||||||
|
// called when an object key is parsed; value is passed and can be safely moved away
|
||||||
|
bool key(string_t& val);
|
||||||
|
|
||||||
|
// called when a parse error occurs; byte position, the last token, and an exception is passed
|
||||||
|
bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex);
|
||||||
|
```
|
||||||
|
|
||||||
|
The return value of each function determines whether parsing should proceed.
|
||||||
|
|
||||||
|
To implement your own SAX handler, proceed as follows:
|
||||||
|
|
||||||
|
1. Implement the SAX interface in a class. You can use class `nlohmann::json_sax<json>` as base class, but you can also use any class where the functions described above are implemented and public.
|
||||||
|
2. Create an object of your SAX interface class, e.g. `my_sax`.
|
||||||
|
3. Call `#!cpp bool json::sax_parse(input, &my_sax);` where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface.
|
||||||
|
|
||||||
|
Note the `sax_parse` function only returns a `#!cpp bool` indicating the result of the last executed SAX event. It does not return `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file `json_sax.hpp`.
|
267
doc/mkdocs/docs/features/types.md
Normal file
267
doc/mkdocs/docs/features/types.md
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
# Types
|
||||||
|
|
||||||
|
This page gives an overview how JSON values are stored and how this can be configured.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
By default, JSON values are stored as follows:
|
||||||
|
|
||||||
|
| JSON type | C++ type |
|
||||||
|
| --------- | -------- |
|
||||||
|
| object | `std::map<std::string, basic_json>` |
|
||||||
|
| array | `std::vector<basic_json>` |
|
||||||
|
| null | `std::nullptr_t` |
|
||||||
|
| string | `std::string` |
|
||||||
|
| boolean | `bool` |
|
||||||
|
| number | `std::int64_t`, `std::uint64_t`, and `double` |
|
||||||
|
|
||||||
|
Note there are three different types for numbers - when parsing JSON text, the best fitting type is chosen.
|
||||||
|
|
||||||
|
## Storage
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
enum value_t {
|
||||||
|
null
|
||||||
|
object
|
||||||
|
array
|
||||||
|
string
|
||||||
|
boolean
|
||||||
|
number_integer
|
||||||
|
number_unsigned
|
||||||
|
number_float
|
||||||
|
binary
|
||||||
|
discarded
|
||||||
|
}
|
||||||
|
|
||||||
|
class json_value << (U,orchid) >> {
|
||||||
|
object_t* object
|
||||||
|
array_t* array
|
||||||
|
string_t* string
|
||||||
|
binary_t* binary
|
||||||
|
boolean_t boolean
|
||||||
|
number_integer_t number_integer
|
||||||
|
number_unsigned_t number_unsigned
|
||||||
|
number_float_t number_float
|
||||||
|
}
|
||||||
|
|
||||||
|
class basic_json {
|
||||||
|
-- type and value --
|
||||||
|
value_t m_type
|
||||||
|
json_value m_value
|
||||||
|
-- derived types --
|
||||||
|
+ <u>typedef</u> object_t
|
||||||
|
+ <u>typedef</u> array_t
|
||||||
|
+ <u>typedef</u> binary_t
|
||||||
|
+ <u>typedef</u> boolean_t
|
||||||
|
+ <u>typedef</u> number_integer_t
|
||||||
|
+ <u>typedef</u> number_unsigned_t
|
||||||
|
+ <u>typedef</u> number_float_t
|
||||||
|
}
|
||||||
|
|
||||||
|
basic_json .. json_value
|
||||||
|
basic_json .. value_t
|
||||||
|
```
|
||||||
|
|
||||||
|
## Template arguments
|
||||||
|
|
||||||
|
The data types to store a JSON value are derived from the template arguments passed to class `basic_json`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template<
|
||||||
|
template<typename U, typename V, typename... Args> class ObjectType = std::map,
|
||||||
|
template<typename U, typename... Args> class ArrayType = std::vector,
|
||||||
|
class StringType = std::string,
|
||||||
|
class BooleanType = bool,
|
||||||
|
class NumberIntegerType = std::int64_t,
|
||||||
|
class NumberUnsignedType = std::uint64_t,
|
||||||
|
class NumberFloatType = double,
|
||||||
|
template<typename U> class AllocatorType = std::allocator,
|
||||||
|
template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer,
|
||||||
|
class BinaryType = std::vector<std::uint8_t>
|
||||||
|
>
|
||||||
|
class basic_json;
|
||||||
|
```
|
||||||
|
|
||||||
|
Type `json` is an alias for `basic_json<>` and uses the default types.
|
||||||
|
|
||||||
|
From the template arguments, the following types are derived:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
using object_comparator_t = std::less<>;
|
||||||
|
using object_t = ObjectType<StringType, basic_json, object_comparator_t,
|
||||||
|
AllocatorType<std::pair<const StringType, basic_json>>>;
|
||||||
|
|
||||||
|
using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
|
||||||
|
|
||||||
|
using string_t = StringType;
|
||||||
|
|
||||||
|
using boolean_t = BooleanType;
|
||||||
|
|
||||||
|
using number_integer_t = NumberIntegerType;
|
||||||
|
using number_unsigned_t = NumberUnsignedType;
|
||||||
|
using number_float_t = NumberFloatType;
|
||||||
|
|
||||||
|
using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Objects
|
||||||
|
|
||||||
|
[RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
|
||||||
|
|
||||||
|
> An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.
|
||||||
|
|
||||||
|
### Default type
|
||||||
|
|
||||||
|
With the default values for *ObjectType* (`std::map`), *StringType* (`std::string`), and *AllocatorType* (`std::allocator`), the default value for `object_t` is:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::map<
|
||||||
|
std::string, // key_type
|
||||||
|
basic_json, // value_type
|
||||||
|
std::less<>, // key_compare
|
||||||
|
std::allocator<std::pair<const std::string, basic_json>> // allocator_type
|
||||||
|
>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Behavior
|
||||||
|
|
||||||
|
The choice of `object_t` influences the behavior of the JSON class. With the default type, objects have the following behavior:
|
||||||
|
|
||||||
|
- When all names are unique, objects will be interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings.
|
||||||
|
- When the names within an object are not unique, it is unspecified which one of the values for a given key will be chosen. For instance, `#!json {"key": 2, "key": 1}` could be equal to either `#!json {"key": 1}` or `#!json {"key": 2}`.
|
||||||
|
- Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see `dump`) in this order. For instance, both `#!json {"b": 1, "a": 2}` and `#!json {"a": 2, "b": 1}` will be stored and serialized as `#!json {"a": 2, "b": 1}`.
|
||||||
|
- When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense that they will not be affected by these differences. For instance, `#!json {"b": 1, "a": 2}` and `#!json {"a": 2, "b": 1}` will be treated as equal.
|
||||||
|
|
||||||
|
### Key order
|
||||||
|
|
||||||
|
The order name/value pairs are added to the object is *not* preserved by the library. Therefore, iterating an object may return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to [RFC 7159](http://rfc7159.net/rfc7159), because any order implements the specified "unordered" nature of JSON objects.
|
||||||
|
|
||||||
|
### Limits
|
||||||
|
|
||||||
|
[RFC 7159](http://rfc7159.net/rfc7159) specifies:
|
||||||
|
|
||||||
|
> An implementation may set limits on the maximum depth of nesting.
|
||||||
|
|
||||||
|
In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the `max_size` function of a JSON object.
|
||||||
|
|
||||||
|
### Storage
|
||||||
|
|
||||||
|
Objects are stored as pointers in a `basic_json` type. That is, for any access to object values, a pointer of type `object_t*` must be dereferenced.
|
||||||
|
|
||||||
|
|
||||||
|
## Arrays
|
||||||
|
|
||||||
|
[RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
|
||||||
|
|
||||||
|
> An array is an ordered sequence of zero or more values.
|
||||||
|
|
||||||
|
### Default type
|
||||||
|
|
||||||
|
With the default values for *ArrayType* (`std::vector`) and *AllocatorType* (`std::allocator`), the default value for `array_t` is:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::vector<
|
||||||
|
basic_json, // value_type
|
||||||
|
std::allocator<basic_json> // allocator_type
|
||||||
|
>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Limits
|
||||||
|
|
||||||
|
[RFC 7159](http://rfc7159.net/rfc7159) specifies:
|
||||||
|
|
||||||
|
> An implementation may set limits on the maximum depth of nesting.
|
||||||
|
|
||||||
|
In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the `max_size` function of a JSON array.
|
||||||
|
|
||||||
|
### Storage
|
||||||
|
|
||||||
|
Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of type `array_t*` must be dereferenced.
|
||||||
|
|
||||||
|
|
||||||
|
## Strings
|
||||||
|
|
||||||
|
[RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
|
||||||
|
|
||||||
|
> A string is a sequence of zero or more Unicode characters.
|
||||||
|
|
||||||
|
Unicode values are split by the JSON class into byte-sized characters during deserialization.
|
||||||
|
|
||||||
|
### Default type
|
||||||
|
|
||||||
|
With the default values for *StringType* (`std::string`), the default value for `string_t` is `#!cpp std::string`.
|
||||||
|
|
||||||
|
### Encoding
|
||||||
|
|
||||||
|
Strings are stored in UTF-8 encoding. Therefore, functions like `std::string::size()` or `std::string::length()` return the number of **bytes** in the string rather than the number of characters or glyphs.
|
||||||
|
|
||||||
|
### String comparison
|
||||||
|
|
||||||
|
[RFC 7159](http://rfc7159.net/rfc7159) states:
|
||||||
|
|
||||||
|
> Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that `"a\\b"` and `"a\u005Cb"` are not equal.
|
||||||
|
|
||||||
|
This implementation is interoperable as it does compare strings code unit by code unit.
|
||||||
|
|
||||||
|
### Storage
|
||||||
|
|
||||||
|
String values are stored as pointers in a `basic_json` type. That is, for any access to string values, a pointer of type `string_t*` must be dereferenced.
|
||||||
|
|
||||||
|
|
||||||
|
## Booleans
|
||||||
|
|
||||||
|
[RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a type which differentiates the two literals `true` and `false`.
|
||||||
|
|
||||||
|
### Default type
|
||||||
|
|
||||||
|
With the default values for *BooleanType* (`#!cpp bool`), the default value for `boolean_t` is `#!cpp bool`.
|
||||||
|
|
||||||
|
### Storage
|
||||||
|
|
||||||
|
Boolean values are stored directly inside a `basic_json` type.
|
||||||
|
|
||||||
|
## Numbers
|
||||||
|
|
||||||
|
[RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
|
||||||
|
|
||||||
|
> The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.
|
||||||
|
|
||||||
|
This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, three different types, `number_integer_t`, `number_unsigned_t`, and `number_float_t` are used.
|
||||||
|
|
||||||
|
### Default types
|
||||||
|
|
||||||
|
With the default values for *NumberIntegerType* (`std::int64_t`), the default value for `number_integer_t` is `std::int64_t`.
|
||||||
|
With the default values for *NumberUnsignedType* (`std::uint64_t`), the default value for `number_unsigned_t` is `std::uint64_t`.
|
||||||
|
With the default values for *NumberFloatType* (`#!cpp double`), the default value for `number_float_t` is `#!cpp double`.
|
||||||
|
|
||||||
|
### Default behavior
|
||||||
|
|
||||||
|
- The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as octal number. Internally, the value will be stored as decimal number. For instance, the C++ integer literal `#!c 010` will be serialized to `#!c 8`. During deserialization, leading zeros yield an error.
|
||||||
|
- Not-a-number (NaN) values will be serialized to `#!json null`.
|
||||||
|
|
||||||
|
### Limits
|
||||||
|
|
||||||
|
[RFC 7159](http://rfc7159.net/rfc7159) specifies:
|
||||||
|
|
||||||
|
> An implementation may set limits on the range and precision of numbers.
|
||||||
|
|
||||||
|
When the default type is used, the maximal integer number that can be stored is `#!c 9223372036854775807` (`INT64_MAX`) and the minimal integer number that can be stored is `#!c -9223372036854775808` (`INT64_MIN`). Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will be automatically be stored as `number_unsigned_t` or `number_float_t`.
|
||||||
|
|
||||||
|
When the default type is used, the maximal unsigned integer number that can be stored is `#!c 18446744073709551615` (`UINT64_MAX`) and the minimal integer number that can be stored is `#!c 0`. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will be automatically be stored as `number_integer_t` or `number_float_t`.
|
||||||
|
|
||||||
|
[RFC 7159](http://rfc7159.net/rfc7159) further states:
|
||||||
|
|
||||||
|
> Note that when such software is used, numbers that are integers and are in the range $[-2^{53}+1, 2^{53}-1]$ are interoperable in the sense that implementations will agree exactly on their numeric values.
|
||||||
|
|
||||||
|
As this range is a subrange of the exactly supported range [`INT64_MIN`, `INT64_MAX`], this class's integer type is interoperable.
|
||||||
|
|
||||||
|
[RFC 7159](http://rfc7159.net/rfc7159) states:
|
||||||
|
|
||||||
|
> This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision.
|
||||||
|
|
||||||
|
This implementation does exactly follow this approach, as it uses double precision floating-point numbers. Note values smaller than `#!c -1.79769313486232e+308` and values greater than `#!c 1.79769313486232e+308` will be stored as NaN internally and be serialized to `#!json null`.
|
||||||
|
|
||||||
|
### Storage
|
||||||
|
|
||||||
|
Integer number values, unsigned integer number values, and floating-point number values are stored directly inside a `basic_json` type.
|
46
doc/mkdocs/docs/home/code_of_conduct.md
Normal file
46
doc/mkdocs/docs/home/code_of_conduct.md
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mail@nlohmann.me. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
|
|
||||||
|
[homepage]: http://contributor-covenant.org
|
||||||
|
[version]: http://contributor-covenant.org/version/1/4/
|
17
doc/mkdocs/docs/home/design_goals.md
Normal file
17
doc/mkdocs/docs/home/design_goals.md
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Design goals
|
||||||
|
|
||||||
|
There are myriads of [JSON](https://json.org) libraries out there, and each may even have its reason to exist. Our class had these design goals:
|
||||||
|
|
||||||
|
- **Intuitive syntax**. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. Check out the [examples below](#examples) and you'll know what I mean.
|
||||||
|
|
||||||
|
- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.
|
||||||
|
|
||||||
|
- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/test/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289).
|
||||||
|
|
||||||
|
Other aspects were not so important to us:
|
||||||
|
|
||||||
|
- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs.
|
||||||
|
|
||||||
|
- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set.
|
||||||
|
|
||||||
|
See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information.
|
801
doc/mkdocs/docs/home/exceptions.md
Normal file
801
doc/mkdocs/docs/home/exceptions.md
Normal file
|
@ -0,0 +1,801 @@
|
||||||
|
# Exceptions
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
### Base type
|
||||||
|
|
||||||
|
All exceptions inherit from class `json::exception` (which in turn inherits from `std::exception`). It is used as the base class for all exceptions thrown by the `basic_json` class. This class can hence be used as "wildcard" to catch exceptions.
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
std::exception <|-- json::exception
|
||||||
|
json::exception <|-- json::parse_error
|
||||||
|
json::exception <|-- json::invalid_iterator
|
||||||
|
json::exception <|-- json::type_error
|
||||||
|
json::exception <|-- json::out_of_range
|
||||||
|
json::exception <|-- json::other_error
|
||||||
|
|
||||||
|
interface std::exception {}
|
||||||
|
|
||||||
|
class json::exception {
|
||||||
|
+ const int id
|
||||||
|
+ const char* what() const
|
||||||
|
}
|
||||||
|
|
||||||
|
class json::parse_error {
|
||||||
|
+ const std::size_t byte
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Switch off exceptions
|
||||||
|
|
||||||
|
Exceptions are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION`. In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `#!cpp throw`), `JSON_TRY_USER` (overriding `#!cpp try`), and `JSON_CATCH_USER` (overriding `#!cpp catch`).
|
||||||
|
|
||||||
|
Note that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.
|
||||||
|
|
||||||
|
## Parse errors
|
||||||
|
|
||||||
|
This exception is thrown by the library when a parse error occurs. Parse errors
|
||||||
|
can occur during the deserialization of JSON text, CBOR, MessagePack, as well
|
||||||
|
as when using JSON Patch.
|
||||||
|
|
||||||
|
Exceptions have ids 1xx.
|
||||||
|
|
||||||
|
!!! info "Byte index"
|
||||||
|
|
||||||
|
Member `byte` holds the byte index of the last read character in the input
|
||||||
|
file.
|
||||||
|
|
||||||
|
For an input with n bytes, 1 is the index of the first character and n+1
|
||||||
|
is the index of the terminating null byte or the end of file. This also
|
||||||
|
holds true when reading a byte vector (CBOR or MessagePack).
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The following code shows how a `parse_error` exception can be caught.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/parse_error.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
--8<-- "examples/parse_error.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### json.exception.parse_error.101
|
||||||
|
|
||||||
|
This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member `byte` indicates the error position.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
Input ended prematurely:
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.101] parse error at 2: unexpected end of input; expected string literal
|
||||||
|
```
|
||||||
|
|
||||||
|
No input:
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal
|
||||||
|
```
|
||||||
|
|
||||||
|
Control character was not escaped:
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \u0009 or \\; last read: '"<U+0009>'"
|
||||||
|
```
|
||||||
|
|
||||||
|
String was not closed:
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '"'
|
||||||
|
```
|
||||||
|
|
||||||
|
Invalid number format:
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E'
|
||||||
|
```
|
||||||
|
|
||||||
|
`\u` was not be followed by four hex digits:
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\u' must be followed by 4 hex digits; last read: '"\u01"'
|
||||||
|
```
|
||||||
|
|
||||||
|
Invalid UTF-8 surrogate pair:
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '"\uD7FF\uDC00'"
|
||||||
|
```
|
||||||
|
|
||||||
|
Invalid UTF-8 byte:
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.101] parse error at line 3, column 24: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '"vous \352t'
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
- Make sure the input is correctly read. Try to write the input to standard output to check if, for instance, the input file was successfully openened.
|
||||||
|
- Paste the input to a JSON validator like <http://jsonlint.com> or a tool like [jq](https://stedolan.github.io/jq/).
|
||||||
|
|
||||||
|
### json.exception.parse_error.102
|
||||||
|
|
||||||
|
JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
parse error at 14: missing or wrong low surrogate
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.parse_error.103
|
||||||
|
|
||||||
|
Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
parse error: code points above 0x10FFFF are invalid
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.parse_error.104
|
||||||
|
|
||||||
|
[RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.104] parse error: JSON patch must be an array of objects
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.parse_error.105
|
||||||
|
|
||||||
|
An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.105] parse error: operation 'add' must have member 'value'
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from'
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.105] parse error: operation value 'foo' is invalid
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.parse_error.106
|
||||||
|
|
||||||
|
An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.parse_error.107
|
||||||
|
|
||||||
|
A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.parse_error.108
|
||||||
|
|
||||||
|
In a JSON Pointer, only `~0` and `~1` are valid escape sequences.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.parse_error.109
|
||||||
|
|
||||||
|
A JSON Pointer array index must be a number.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.109] parse error: array index 'one' is not a number
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.109] parse error: array index '+1' is not a number
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.parse_error.110
|
||||||
|
|
||||||
|
When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: expected end of input; last byte: 0x5A
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.parse_error.112
|
||||||
|
|
||||||
|
Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.parse_error.113
|
||||||
|
|
||||||
|
While parsing a map key, a value that is not a string has been read.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xFF
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack string: expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0xFF
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON char: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.parse_error.114
|
||||||
|
|
||||||
|
The parsing of the corresponding BSON record type is not implemented (yet).
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.114] parse error at byte 5: Unsupported BSON record type 0xFF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Iterator errors
|
||||||
|
|
||||||
|
This exception is thrown if iterators passed to a library function do not match
|
||||||
|
the expected semantics.
|
||||||
|
|
||||||
|
Exceptions have ids 2xx.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The following code shows how an `invalid_iterator` exception can be caught.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/invalid_iterator.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
--8<-- "examples/invalid_iterator.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.201
|
||||||
|
|
||||||
|
The iterators passed to constructor `basic_json(InputIT first, InputIT last)` are not compatible, meaning they do not belong to the same container. Therefore, the range (`first`, `last`) is invalid.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.201] iterators are not compatible
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.202
|
||||||
|
|
||||||
|
In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.202] iterator does not fit current value
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.202] iterators first and last must point to objects
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.203
|
||||||
|
|
||||||
|
Either iterator passed to function `erase(IteratorType` first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.203] iterators do not fit current value
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.204
|
||||||
|
|
||||||
|
When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (`begin(),` `end()),` because this is the only way the single stored value is expressed. All other ranges are invalid.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.204] iterators out of range
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.205
|
||||||
|
|
||||||
|
When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the `begin()` iterator, because it is the only way to address the stored value. All other iterators are invalid.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.205] iterator out of range
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.206
|
||||||
|
|
||||||
|
The iterators passed to constructor `basic_json(InputIT first, InputIT last)` belong to a JSON null value and hence to not define a valid range.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.206] cannot construct with iterators from null
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.207
|
||||||
|
|
||||||
|
The `key()` member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.207] cannot use key() for non-object iterators
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.208
|
||||||
|
|
||||||
|
The `operator[]` to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.208] cannot use operator[] for object iterators
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.209
|
||||||
|
|
||||||
|
The offset operators (`+`, `-`, `+=`, `-=`) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.209] cannot use offsets with object iterators
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.210
|
||||||
|
|
||||||
|
The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (`first`, `last`) is invalid.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.210] iterators do not fit
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.211
|
||||||
|
|
||||||
|
The iterator range passed to the insert function must not be a subrange of the container to insert to.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.211] passed iterators may not belong to container
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.212
|
||||||
|
|
||||||
|
When two iterators are compared, they must belong to the same container.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.212] cannot compare iterators of different containers
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.213
|
||||||
|
|
||||||
|
The order of object iterators cannot be compared, because JSON objects are unordered.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.213] cannot compare order of object iterators
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.invalid_iterator.214
|
||||||
|
|
||||||
|
Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to `begin()`.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.invalid_iterator.214] cannot get value
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Type errors
|
||||||
|
|
||||||
|
This exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type does not match the expected semantics.
|
||||||
|
|
||||||
|
Exceptions have ids 3xx.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The following code shows how a `type_error` exception can be caught.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/type_error.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
--8<-- "examples/type_error.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.301
|
||||||
|
|
||||||
|
To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.301] cannot create object from initializer list
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.302
|
||||||
|
|
||||||
|
During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.302] type must be object, but is null
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.type_error.302] type must be string, but is object
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.303
|
||||||
|
|
||||||
|
To retrieve a reference to a value stored in a `basic_json` object with `get_ref`, the type of the reference must match the value type. For instance, for a JSON array, the `ReferenceType` must be `array_t &`.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number"
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.304
|
||||||
|
|
||||||
|
The `at()` member functions can only be executed for certain JSON types.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.304] cannot use at() with string
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.type_error.304] cannot use at() with number
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.305
|
||||||
|
|
||||||
|
The `operator[]` member functions can only be executed for certain JSON types.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.305] cannot use operator[] with a string argument with array
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.type_error.305] cannot use operator[] with a numeric argument with object
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.306
|
||||||
|
|
||||||
|
The `value()` member functions can only be executed for certain JSON types.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.306] cannot use value() with number
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.307
|
||||||
|
|
||||||
|
The `erase()` member functions can only be executed for certain JSON types.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.307] cannot use erase() with string
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.308
|
||||||
|
|
||||||
|
The `push_back()` and `operator+=` member functions can only be executed for certain JSON types.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.308] cannot use push_back() with string
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.309
|
||||||
|
|
||||||
|
The `insert()` member functions can only be executed for certain JSON types.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.309] cannot use insert() with array
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.type_error.309] cannot use insert() with number
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.310
|
||||||
|
|
||||||
|
The `swap()` member functions can only be executed for certain JSON types.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.310] cannot use swap() with number
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.311
|
||||||
|
|
||||||
|
The `emplace()` and `emplace_back()` member functions can only be executed for certain JSON types.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.311] cannot use emplace() with number
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.type_error.311] cannot use emplace_back() with number
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.312
|
||||||
|
|
||||||
|
The `update()` member functions can only be executed for certain JSON types.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.312] cannot use update() with array
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.313
|
||||||
|
|
||||||
|
The `unflatten` function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.313] invalid value to unflatten
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.314
|
||||||
|
|
||||||
|
The `unflatten` function only works for an object whose keys are JSON Pointers.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
Calling `unflatten()` on an array `#!json [1,2,3]`:
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.314] only objects can be unflattened
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.315
|
||||||
|
|
||||||
|
The `unflatten()` function only works for an object whose keys are JSON Pointers and whose values are primitive.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
Calling `unflatten()` on an object `#!json {"/1", [1,2,3]}`:
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.315] values in object must be primitive
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.type_error.316
|
||||||
|
|
||||||
|
The `dump()` function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
Calling `dump()` on a JSON value containing an ISO 8859-1 encoded string:
|
||||||
|
```
|
||||||
|
[json.exception.type_error.316] invalid UTF-8 byte at index 15: 0x6F
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
- Store the source file with UTF-8 encoding.
|
||||||
|
- Pass an error handler as last parameter to the `dump()` function to avoid this exception:
|
||||||
|
- `json::error_handler_t::replace` will replace invalid bytes sequences with `U+FFFD`
|
||||||
|
- `json::error_handler_t::ignore` will silently ignore invalid byte sequences
|
||||||
|
|
||||||
|
### json.exception.type_error.317
|
||||||
|
|
||||||
|
The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON)
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
Serializing `#!json null` to BSON:
|
||||||
|
```
|
||||||
|
[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is null
|
||||||
|
```
|
||||||
|
Serializing `#!json [1,2,3]` to BSON:
|
||||||
|
```
|
||||||
|
[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is array
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
Encapsulate the JSON value in an object. That is, instead of serializing `#!json true`, serialize `#!json {"value": true}`
|
||||||
|
|
||||||
|
|
||||||
|
## Out of range
|
||||||
|
|
||||||
|
This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance in case of array indices or nonexisting object keys.
|
||||||
|
|
||||||
|
Exceptions have ids 4xx.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The following code shows how an `out_of_range` exception can be caught.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/out_of_range.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
--8<-- "examples/out_of_range.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.out_of_range.401
|
||||||
|
|
||||||
|
The provided array index `i` is larger than `size-1`.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
array index 3 is out of range
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.out_of_range.402
|
||||||
|
|
||||||
|
The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
array index '-' (3) is out of range
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.out_of_range.403
|
||||||
|
|
||||||
|
The provided key was not found in the JSON object.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
key 'foo' not found
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.out_of_range.404
|
||||||
|
|
||||||
|
A reference token in a JSON Pointer could not be resolved.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
unresolved reference token 'foo'
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.out_of_range.405
|
||||||
|
|
||||||
|
The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
JSON pointer has no parent
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.out_of_range.406
|
||||||
|
|
||||||
|
A parsed number could not be stored as without changing it to NaN or INF.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
number overflow parsing '10E1000'
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.out_of_range.407
|
||||||
|
|
||||||
|
UBJSON and BSON only support integer numbers up to 9223372036854775807.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
number overflow serializing '9223372036854775808'
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.out_of_range.408
|
||||||
|
|
||||||
|
The size (following `#`) of an UBJSON array or object exceeds the maximal capacity.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
excessive array size: 8658170730974374167
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.out_of_range.409
|
||||||
|
|
||||||
|
Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
BSON key cannot contain code point U+0000 (at byte 2)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Further exceptions
|
||||||
|
|
||||||
|
This exception is thrown in case of errors that cannot be classified with the
|
||||||
|
other exception types.
|
||||||
|
|
||||||
|
Exceptions have ids 5xx.
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The following code shows how an `other_error` exception can be caught.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/other_error.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
--8<-- "examples/other_error.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
### json.exception.other_error.501
|
||||||
|
|
||||||
|
A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
Executing `#!json {"op":"test", "path":"/baz", "value":"bar"}` on `#!json {"baz": "qux"}`:
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.other_error.501] unsuccessful: {"op":"test","path":"/baz","value":"bar"}
|
||||||
|
```
|
128
doc/mkdocs/docs/home/faq.md
Normal file
128
doc/mkdocs/docs/home/faq.md
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
# Frequently Asked Questions (FAQ)
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
### Comments
|
||||||
|
|
||||||
|
!!! question "Questions"
|
||||||
|
|
||||||
|
- Why does the library not support comments?
|
||||||
|
- Can you add support for JSON5/JSONC/HOCON so that comments are supported?
|
||||||
|
|
||||||
|
This library does not support comments. It does so for three reasons:
|
||||||
|
|
||||||
|
1. Comments are not part of the [JSON specification](https://tools.ietf.org/html/rfc8259). You may argue that `//` or `/* */` are allowed in JavaScript, but JSON is not JavaScript.
|
||||||
|
2. This was not an oversight: Douglas Crockford [wrote on this](https://plus.google.com/118095276221607585885/posts/RK8qyGVaGSr) in May 2012:
|
||||||
|
|
||||||
|
> I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability. I know that the lack of comments makes some people sad, but it shouldn't.
|
||||||
|
|
||||||
|
> Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser.
|
||||||
|
|
||||||
|
3. It is dangerous for interoperability if some libraries would add comment support while others don't. Please check [The Harmful Consequences of the Robustness Principle](https://tools.ietf.org/html/draft-iab-protocol-maintenance-01) on this.
|
||||||
|
|
||||||
|
This library will not support comments in the future. If you wish to use comments, I see three options:
|
||||||
|
|
||||||
|
1. Strip comments before using this library.
|
||||||
|
2. Use a different JSON library with comment support.
|
||||||
|
3. Use a format that natively supports comments (e.g., YAML or JSON5).
|
||||||
|
|
||||||
|
|
||||||
|
### Relaxed parsing
|
||||||
|
|
||||||
|
!!! question
|
||||||
|
|
||||||
|
- Can you add an option to ignore trailing commas?
|
||||||
|
|
||||||
|
For the same reason this library does not support [comments](#comments), this library also does not support any feature which would jeopardize interoperability.
|
||||||
|
|
||||||
|
|
||||||
|
### Parse errors reading non-ASCII characters
|
||||||
|
|
||||||
|
!!! question "Questions"
|
||||||
|
|
||||||
|
- Why is the parser complaining about a Chinese character?
|
||||||
|
- Does the library support Unicode?
|
||||||
|
- I get an exception `[json.exception.parse_error.101] parse error at line 1, column 53: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '"Testé$')"`
|
||||||
|
|
||||||
|
The library supports **Unicode input** as follows:
|
||||||
|
|
||||||
|
- Only **UTF-8** encoded input is supported which is the default encoding for JSON according to [RFC 8259](https://tools.ietf.org/html/rfc8259.html#section-8.1).
|
||||||
|
- `std::u16string` and `std::u32string` can be parsed, assuming UTF-16 and UTF-32 encoding, respectively. These encodings are not supported when reading from files or other input containers.
|
||||||
|
- Other encodings such as Latin-1 or ISO 8859-1 are **not** supported and will yield parse or serialization errors.
|
||||||
|
- [Unicode noncharacters](http://www.unicode.org/faq/private_use.html#nonchar1) will not be replaced by the library.
|
||||||
|
- Invalid surrogates (e.g., incomplete pairs such as `\uDEAD`) will yield parse errors.
|
||||||
|
- The strings stored in the library are UTF-8 encoded. When using the default string type (`std::string`), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs.
|
||||||
|
- When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a50ec80b02d0f3f51130d4abb5d1cfdc5.html#a50ec80b02d0f3f51130d4abb5d1cfdc5) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers.
|
||||||
|
|
||||||
|
In most cases, the parser is right to complain, because the input is not UTF-8 encoded. This is especially true for Microsoft Windows where Latin-1 or ISO 8859-1 is often the standard encoding.
|
||||||
|
|
||||||
|
|
||||||
|
### Key name in exceptions
|
||||||
|
|
||||||
|
!!! question
|
||||||
|
|
||||||
|
Can I get the key of the object item that caused an exception?
|
||||||
|
|
||||||
|
No, this is not possible. See <https://github.com/nlohmann/json/issues/932> for a longer discussion.
|
||||||
|
|
||||||
|
|
||||||
|
## Serialization issues
|
||||||
|
|
||||||
|
|
||||||
|
### Order of object keys
|
||||||
|
|
||||||
|
!!! question "Questions"
|
||||||
|
|
||||||
|
- Why are object keys sorted?
|
||||||
|
- Why is the insertion order of object keys not preserved?
|
||||||
|
|
||||||
|
By default, the library does not preserve the **insertion order of object elements**. This is standards-compliant, as the [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs".
|
||||||
|
|
||||||
|
If you do want to preserve the insertion order, you can specialize the object type with containers like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)).
|
||||||
|
|
||||||
|
|
||||||
|
### Number precision
|
||||||
|
|
||||||
|
!!! question
|
||||||
|
|
||||||
|
- It seems that precision is lost when serializing a double.
|
||||||
|
- Can I change the precision for floating-point serialization?
|
||||||
|
|
||||||
|
The library uses `std::numeric_limits<number_float_t>::digits10` (15 for IEEE `double`s) digits for serialization. This value is sufficient to guarantee roundtripping. If one uses more than this number of digits of precision, then string -> value -> string is not guaranteed to round-trip.
|
||||||
|
|
||||||
|
!!! quote "[cppreference.com](https://en.cppreference.com/w/cpp/types/numeric_limits/digits10)"
|
||||||
|
|
||||||
|
The value of `std::numeric_limits<T>::digits10` is the number of base-10 digits that can be represented by the type T without change, that is, any number with this many significant decimal digits can be converted to a value of type T and back to decimal form, without change due to rounding or overflow.
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
The website https://float.exposed gives a good insight into the internal storage of floating-point numbers.
|
||||||
|
|
||||||
|
|
||||||
|
## Compilation issues
|
||||||
|
|
||||||
|
### Android SDK
|
||||||
|
|
||||||
|
!!! question
|
||||||
|
|
||||||
|
Why does the code not compile with Android SDK?
|
||||||
|
|
||||||
|
Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
APP_STL := c++_shared
|
||||||
|
NDK_TOOLCHAIN_VERSION := clang3.6
|
||||||
|
APP_CPPFLAGS += -frtti -fexceptions
|
||||||
|
```
|
||||||
|
|
||||||
|
The code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10.
|
||||||
|
|
||||||
|
|
||||||
|
### Missing STL function
|
||||||
|
|
||||||
|
!!! question "Questions"
|
||||||
|
|
||||||
|
- Why do I get a compilation error `'to_string' is not a member of 'std'` (or similarly, for `strtod` or `strtof`)?
|
||||||
|
- Why does the code not compile with MinGW or Android SDK?
|
||||||
|
|
||||||
|
This is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to [this site](http://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219).
|
21
doc/mkdocs/docs/home/license.md
Normal file
21
doc/mkdocs/docs/home/license.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# License
|
||||||
|
|
||||||
|
<img align="right" src="http://opensource.org/trademarks/opensource/OSI-Approved-License-100x137.png">
|
||||||
|
|
||||||
|
The class is licensed under the [MIT License](http://opensource.org/licenses/MIT):
|
||||||
|
|
||||||
|
Copyright © 2013-2019 [Niels Lohmann](http://nlohmann.me)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the [MIT License](http://opensource.org/licenses/MIT) (see above). Copyright © 2008-2009 [Björn Hoehrmann](http://bjoern.hoehrmann.de/) <bjoern@hoehrmann.de>
|
||||||
|
|
||||||
|
The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](http://opensource.org/licenses/MIT) (see above). Copyright © 2009 [Florian Loitsch](http://florian.loitsch.com/)
|
||||||
|
|
||||||
|
The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](http://creativecommons.org/publicdomain/zero/1.0/).
|
1225
doc/mkdocs/docs/home/releases.md
Normal file
1225
doc/mkdocs/docs/home/releases.md
Normal file
File diff suppressed because it is too large
Load diff
11
doc/mkdocs/docs/home/sponsors.md
Normal file
11
doc/mkdocs/docs/home/sponsors.md
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Sponsors
|
||||||
|
|
||||||
|
You can sponsor this library at [GitHub Sponsors](https://github.com/sponsors/nlohmann).
|
||||||
|
|
||||||
|
## Named Sponsors
|
||||||
|
|
||||||
|
- [Michael Hartmann](https://github.com/reFX-Mike)
|
||||||
|
- [Stefan Hagen](https://github.com/sthagen)
|
||||||
|
- [Steve Sperandeo](https://github.com/homer6)
|
||||||
|
|
||||||
|
Thanks everyone!
|
7
doc/mkdocs/docs/hooks.py
Normal file
7
doc/mkdocs/docs/hooks.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import shutil
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
|
||||||
|
def copy_doxygen(*args, **kwargs):
|
||||||
|
shutil.copytree('../html', os.path.join(kwargs['config']['site_dir'], 'doxygen'))
|
||||||
|
print('Copy Doxygen complete')
|
7
doc/mkdocs/docs/index.md
Normal file
7
doc/mkdocs/docs/index.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# JSON for Modern C++
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
This page is under construction. You probably want to see the [Doxygen documentation](doxygen).
|
||||||
|
|
||||||
|
![](images/json.gif)
|
103
doc/mkdocs/docs/integration/cmake.md
Normal file
103
doc/mkdocs/docs/integration/cmake.md
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
# CMake
|
||||||
|
|
||||||
|
You can also use the `nlohmann_json::nlohmann_json` interface target in CMake. This target populates the appropriate usage requirements for `INTERFACE_INCLUDE_DIRECTORIES` to point to the appropriate include directories and `INTERFACE_COMPILE_FEATURES` for the necessary C++11 flags.
|
||||||
|
|
||||||
|
## External
|
||||||
|
|
||||||
|
To use this library from a CMake project, you can locate it directly with `find_package()` and use the namespaced imported target from the generated package configuration:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
# CMakeLists.txt
|
||||||
|
find_package(nlohmann_json 3.2.0 REQUIRED)
|
||||||
|
...
|
||||||
|
add_library(foo ...)
|
||||||
|
...
|
||||||
|
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
||||||
|
```
|
||||||
|
|
||||||
|
The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree.
|
||||||
|
|
||||||
|
## Embedded
|
||||||
|
|
||||||
|
To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call `add_subdirectory()` in your `CMakeLists.txt` file:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
# Typically you don't care so much for a third party library's tests to be
|
||||||
|
# run from your own project's code.
|
||||||
|
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||||
|
|
||||||
|
# If you only include this third party in PRIVATE source files, you do not
|
||||||
|
# need to install it when your main project gets installed.
|
||||||
|
# set(JSON_Install OFF CACHE INTERNAL "")
|
||||||
|
|
||||||
|
# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it
|
||||||
|
# unintended consequences that will break the build. It's generally
|
||||||
|
# discouraged (although not necessarily well documented as such) to use
|
||||||
|
# include(...) for pulling in other CMake projects anyways.
|
||||||
|
add_subdirectory(nlohmann_json)
|
||||||
|
...
|
||||||
|
add_library(foo ...)
|
||||||
|
...
|
||||||
|
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Embedded (FetchContent)
|
||||||
|
|
||||||
|
Since CMake v3.11,
|
||||||
|
[FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can
|
||||||
|
be used to automatically download the repository as a dependency at configure type.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```cmake
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(json
|
||||||
|
GIT_REPOSITORY https://github.com/nlohmann/json
|
||||||
|
GIT_TAG v3.7.3)
|
||||||
|
|
||||||
|
FetchContent_GetProperties(json)
|
||||||
|
if(NOT json_POPULATED)
|
||||||
|
FetchContent_Populate(json)
|
||||||
|
add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
The repository <https://github.com/nlohmann/json> download size is huge.
|
||||||
|
It contains all the dataset used for the benchmarks. You might want to depend on
|
||||||
|
a smaller repository. For instance, you might want to replace the URL above by
|
||||||
|
<https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent>.
|
||||||
|
|
||||||
|
## Supporting Both
|
||||||
|
|
||||||
|
To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following:
|
||||||
|
|
||||||
|
``` cmake
|
||||||
|
# Top level CMakeLists.txt
|
||||||
|
project(FOO)
|
||||||
|
...
|
||||||
|
option(FOO_USE_EXTERNAL_JSON "Use an external JSON library" OFF)
|
||||||
|
...
|
||||||
|
add_subdirectory(thirdparty)
|
||||||
|
...
|
||||||
|
add_library(foo ...)
|
||||||
|
...
|
||||||
|
# Note that the namespaced target will always be available regardless of the
|
||||||
|
# import method
|
||||||
|
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
||||||
|
```
|
||||||
|
```cmake
|
||||||
|
# thirdparty/CMakeLists.txt
|
||||||
|
...
|
||||||
|
if(FOO_USE_EXTERNAL_JSON)
|
||||||
|
find_package(nlohmann_json 3.2.0 REQUIRED)
|
||||||
|
else()
|
||||||
|
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||||
|
add_subdirectory(nlohmann_json)
|
||||||
|
endif()
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
`thirdparty/nlohmann_json` is then a complete copy of this source tree.
|
9
doc/mkdocs/docs/integration/conan/CMakeLists.txt
Normal file
9
doc/mkdocs/docs/integration/conan/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
project(json_example)
|
||||||
|
cmake_minimum_required(VERSION 2.8.12)
|
||||||
|
add_definitions("-std=c++11")
|
||||||
|
|
||||||
|
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
|
||||||
|
conan_basic_setup()
|
||||||
|
|
||||||
|
add_executable(json_example example.cpp)
|
||||||
|
target_link_libraries(json_example ${CONAN_LIBS})
|
5
doc/mkdocs/docs/integration/conan/Conanfile.txt
Normal file
5
doc/mkdocs/docs/integration/conan/Conanfile.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[requires]
|
||||||
|
nlohmann_json/3.7.3
|
||||||
|
|
||||||
|
[generators]
|
||||||
|
cmake
|
9
doc/mkdocs/docs/integration/conan/example.cpp
Normal file
9
doc/mkdocs/docs/integration/conan/example.cpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::cout << json::meta() << std::endl;
|
||||||
|
}
|
9
doc/mkdocs/docs/integration/example.cpp
Normal file
9
doc/mkdocs/docs/integration/example.cpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::cout << json::meta() << std::endl;
|
||||||
|
}
|
14
doc/mkdocs/docs/integration/index.md
Normal file
14
doc/mkdocs/docs/integration/index.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Integration
|
||||||
|
|
||||||
|
[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
// for convenience
|
||||||
|
using json = nlohmann::json;
|
||||||
|
```
|
||||||
|
|
||||||
|
to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).
|
||||||
|
|
||||||
|
You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of json_fwd.hpp (as part of cmake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`.
|
143
doc/mkdocs/docs/integration/package_managers.md
Normal file
143
doc/mkdocs/docs/integration/package_managers.md
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
# Package Managers
|
||||||
|
|
||||||
|
Throughout this page, we will describe how to compile the example file `example.cpp` below.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "integration/example.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Homebrew
|
||||||
|
|
||||||
|
If you are using OS X and [Homebrew](http://brew.sh), just type
|
||||||
|
|
||||||
|
```sh
|
||||||
|
brew tap nlohmann/json
|
||||||
|
brew install nlohmann_json
|
||||||
|
```
|
||||||
|
|
||||||
|
and you're set. If you want the bleeding edge rather than the latest release, use
|
||||||
|
|
||||||
|
```sh
|
||||||
|
brew tap nlohmann/json
|
||||||
|
brew install nlohmann_json --HEAD
|
||||||
|
```
|
||||||
|
|
||||||
|
instead.
|
||||||
|
|
||||||
|
!!! example
|
||||||
|
|
||||||
|
1. Create the following file:
|
||||||
|
|
||||||
|
=== "example.cpp"
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "integration/example.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Install the package
|
||||||
|
|
||||||
|
```sh
|
||||||
|
brew tap nlohmann/json
|
||||||
|
brew install nlohmann_json
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Determine the include path, which defaults to `/usr/local/Cellar/nlohmann_json/$version/include`, where `$version` is the version of the library, e.g. `3.7.3`. The path of the library can be determined with
|
||||||
|
|
||||||
|
```sh
|
||||||
|
brew list nlohmann_json
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Compile the code. For instance, the code can be compiled using Clang with
|
||||||
|
|
||||||
|
```sh
|
||||||
|
clang++ example.cpp -I/usr/local/Cellar/nlohmann_json/3.7.3/include -std=c++11 -o example
|
||||||
|
```
|
||||||
|
|
||||||
|
## Meson
|
||||||
|
|
||||||
|
If you are using the [Meson Build System](http://mesonbuild.com), add this source tree as a [meson subproject](https://mesonbuild.com/Subprojects.html#using-a-subproject). You may also use the `include.zip` published in this project's [Releases](https://github.com/nlohmann/json/releases) to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/nlohmann_json), or simply use `meson wrap install nlohmann_json`. Please see the meson project for any issues regarding the packaging.
|
||||||
|
|
||||||
|
The provided meson.build can also be used as an alternative to cmake for installing `nlohmann_json` system-wide in which case a pkg-config file is installed. To use it, simply have your build system require the `nlohmann_json` pkg-config dependency. In Meson, it is preferred to use the [`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a subproject fallback, rather than using the subproject directly.
|
||||||
|
|
||||||
|
## Conan
|
||||||
|
|
||||||
|
If you are using [Conan](https://www.conan.io/) to manage your dependencies, merely add `nlohmann_json/x.y.z` to your `conanfile`'s requires, where `x.y.z` is the release version you want to use. Please file issues [here](https://github.com/conan-io/conan-center-index/issues) if you experience problems with the packages.
|
||||||
|
|
||||||
|
!!! example
|
||||||
|
|
||||||
|
1. Create the following files:
|
||||||
|
|
||||||
|
=== "Conanfile.txt"
|
||||||
|
|
||||||
|
```ini
|
||||||
|
--8<-- "integration/conan/Conanfile.txt"
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "CMakeLists.txt"
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
--8<-- "integration/conan/CMakeLists.txt"
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "example.cpp"
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "integration/conan/example.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
2. Build:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
conan install ..
|
||||||
|
cmake ..
|
||||||
|
cmake --build .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Spack
|
||||||
|
|
||||||
|
If you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the [`nlohmann-json` package](https://spack.readthedocs.io/en/latest/package_list.html#nlohmann-json). Please see the [spack project](https://github.com/spack/spack) for any issues regarding the packaging.
|
||||||
|
|
||||||
|
## Hunter
|
||||||
|
|
||||||
|
If you are using [hunter](https://github.com/cpp-pm/hunter) on your project for external dependencies, then you can use the [nlohmann_json package](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html). Please see the hunter project for any issues regarding the packaging.
|
||||||
|
|
||||||
|
## Buckaroo
|
||||||
|
|
||||||
|
If you are using [Buckaroo](https://buckaroo.pm), you can install this library's module with `buckaroo add github.com/buckaroo-pm/nlohmann-json`. Please file issues [here](https://github.com/buckaroo-pm/nlohmann-json). There is a demo repo [here](https://github.com/njlr/buckaroo-nholmann-json-example).
|
||||||
|
|
||||||
|
## vcpkg
|
||||||
|
|
||||||
|
If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can use the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json). Please see the vcpkg project for any issues regarding the packaging.
|
||||||
|
|
||||||
|
## cget
|
||||||
|
|
||||||
|
If you are using [cget](http://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`).
|
||||||
|
|
||||||
|
|
||||||
|
## CocoaPods
|
||||||
|
|
||||||
|
If you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `"nlohmann_json", '~>3.1.2'` to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues [here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open).
|
||||||
|
|
||||||
|
## NuGet
|
||||||
|
|
||||||
|
If you are using [NuGet](https://www.nuget.org), you can use the package [nlohmann.json](https://www.nuget.org/packages/nlohmann.json/). Please check [this extensive description](https://github.com/nlohmann/json/issues/1132#issuecomment-452250255) on how to use the package. Please files issues [here](https://github.com/hnkb/nlohmann-json-nuget/issues).
|
||||||
|
|
||||||
|
## Conda
|
||||||
|
|
||||||
|
If you are using [conda](https://conda.io/), you can use the package [nlohmann_json](https://github.com/conda-forge/nlohmann_json-feedstock) from [conda-forge](https://conda-forge.org) executing `conda install -c conda-forge nlohmann_json`. Please file issues [here](https://github.com/conda-forge/nlohmann_json-feedstock/issues).
|
||||||
|
|
||||||
|
## MSYS2
|
||||||
|
|
||||||
|
If you are using [MSYS2](http://www.msys2.org/), your can use the [mingw-w64-nlohmann-json](https://packages.msys2.org/base/mingw-w64-nlohmann-json) package, just type `pacman -S mingw-w64-i686-nlohmann-json` or `pacman -S mingw-w64-x86_64-nlohmann-json` for installation. Please file issues [here](https://github.com/msys2/MINGW-packages/issues/new?title=%5Bnlohmann-json%5D) if you experience problems with the packages.
|
||||||
|
|
||||||
|
## build2
|
||||||
|
|
||||||
|
If you are using [`build2`](https://build2.org), you can use the [`nlohmann-json`](https://cppget.org/nlohmann-json) package from the public repository http://cppget.org or directly from the [package's sources repository](https://github.com/build2-packaging/nlohmann-json). In your project's `manifest` file, just add `depends: nlohmann-json` (probably with some [version constraints](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-add-remove-deps)). If you are not familiar with using dependencies in `build2`, [please read this introduction](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml).
|
||||||
|
Please file issues [here](https://github.com/build2-packaging/nlohmann-json) if you experience problems with the packages.
|
||||||
|
|
||||||
|
## wsjcpp
|
||||||
|
|
||||||
|
If you are using [`wsjcpp`](http://wsjcpp.org), you can use the command `wsjcpp install "https://github.com/nlohmann/json:develop"` to get the latest version. Note you can change the branch ":develop" to an existing tag or another branch.
|
120
doc/mkdocs/mkdocs.yml
Normal file
120
doc/mkdocs/mkdocs.yml
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
# Project information
|
||||||
|
site_name: JSON for Modern C++
|
||||||
|
site_author: Niels Lohmann
|
||||||
|
site_url: https://squidfunk.github.io/mkdocs-material/
|
||||||
|
|
||||||
|
# Repository
|
||||||
|
repo_name: nlohmann/json
|
||||||
|
repo_url: https://github.com/nlohmann/json
|
||||||
|
edit_uri: edit/develop/doc/mkdocs/docs
|
||||||
|
|
||||||
|
# Copyright
|
||||||
|
copyright: Copyright © 2013 - 2020 Niels Lohmann
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
theme:
|
||||||
|
name: material
|
||||||
|
language: en
|
||||||
|
palette:
|
||||||
|
primary: indigo
|
||||||
|
accent: indigo
|
||||||
|
font:
|
||||||
|
text: Roboto
|
||||||
|
code: Roboto Mono
|
||||||
|
features:
|
||||||
|
- tabs
|
||||||
|
- instant
|
||||||
|
|
||||||
|
nav:
|
||||||
|
- Home:
|
||||||
|
- index.md
|
||||||
|
- home/license.md
|
||||||
|
- "Code of Conduct": home/code_of_conduct.md
|
||||||
|
- "FAQ": home/faq.md
|
||||||
|
- home/exceptions.md
|
||||||
|
- home/releases.md
|
||||||
|
- home/design_goals.md
|
||||||
|
- home/sponsors.md
|
||||||
|
- Features:
|
||||||
|
- features/arbitrary_types.md
|
||||||
|
- Binary Formats:
|
||||||
|
- features/binary_formats/index.md
|
||||||
|
- features/binary_formats/bson.md
|
||||||
|
- features/binary_formats/cbor.md
|
||||||
|
- features/binary_formats/messagepack.md
|
||||||
|
- features/binary_formats/ubjson.md
|
||||||
|
- features/binary_values.md
|
||||||
|
- features/iterators.md
|
||||||
|
- features/json_pointer.md
|
||||||
|
- features/json_patch.md
|
||||||
|
- features/merge_patch.md
|
||||||
|
- features/enum_conversion.md
|
||||||
|
- Parsing:
|
||||||
|
- features/parsing/index.md
|
||||||
|
- features/parsing/parse_exceptions.md
|
||||||
|
- features/parsing/parser_callbacks.md
|
||||||
|
- features/parsing/sax_interface.md
|
||||||
|
- features/types.md
|
||||||
|
- Integration:
|
||||||
|
- integration/index.md
|
||||||
|
- integration/cmake.md
|
||||||
|
- integration/package_managers.md
|
||||||
|
- Doxygen:
|
||||||
|
- doxygen/index.html
|
||||||
|
|
||||||
|
# Extras
|
||||||
|
extra:
|
||||||
|
social:
|
||||||
|
- icon: fontawesome/brands/github
|
||||||
|
link: https://github.com/nlohmann
|
||||||
|
- icon: fontawesome/brands/twitter
|
||||||
|
link: https://twitter.com/nlohmann
|
||||||
|
- icon: fontawesome/brands/linkedin
|
||||||
|
link: https://www.linkedin.com/in/nielslohmann/
|
||||||
|
- icon: fontawesome/brands/xing
|
||||||
|
link: https://www.xing.com/profile/Niels_Lohmann
|
||||||
|
- icon: fontawesome/brands/paypal
|
||||||
|
link: https://www.paypal.me/nlohmann
|
||||||
|
|
||||||
|
# Extensions
|
||||||
|
markdown_extensions:
|
||||||
|
- admonition
|
||||||
|
- codehilite:
|
||||||
|
guess_lang: false
|
||||||
|
- toc:
|
||||||
|
permalink: true
|
||||||
|
- pymdownx.arithmatex
|
||||||
|
- pymdownx.betterem:
|
||||||
|
smart_enable: all
|
||||||
|
- pymdownx.caret
|
||||||
|
- pymdownx.critic
|
||||||
|
- pymdownx.details
|
||||||
|
- pymdownx.emoji:
|
||||||
|
emoji_index: !!python/name:materialx.emoji.twemoji
|
||||||
|
emoji_generator: !!python/name:materialx.emoji.to_svg
|
||||||
|
- pymdownx.inlinehilite
|
||||||
|
- pymdownx.magiclink
|
||||||
|
- pymdownx.mark
|
||||||
|
#- pymdownx.smartsymbols
|
||||||
|
- pymdownx.superfences
|
||||||
|
- pymdownx.tasklist:
|
||||||
|
custom_checkbox: true
|
||||||
|
- pymdownx.tabbed
|
||||||
|
- pymdownx.tilde
|
||||||
|
- pymdownx.snippets:
|
||||||
|
base_path: docs
|
||||||
|
check_paths: true
|
||||||
|
- plantuml_markdown:
|
||||||
|
format: svg
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
- search:
|
||||||
|
separator: '[\s\-\.]+'
|
||||||
|
- mkdocs-simple-hooks:
|
||||||
|
hooks:
|
||||||
|
on_post_build: "docs.hooks:copy_doxygen"
|
||||||
|
- minify:
|
||||||
|
minify_html: true
|
||||||
|
|
||||||
|
extra_javascript:
|
||||||
|
- https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML
|
29
doc/mkdocs/requirements.txt
Normal file
29
doc/mkdocs/requirements.txt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
click>=7.1.2
|
||||||
|
future>=0.18.2
|
||||||
|
htmlmin>=0.1.12
|
||||||
|
httplib2>=0.18.1
|
||||||
|
importlib-metadata>=1.6.0
|
||||||
|
Jinja2>=2.11.2
|
||||||
|
joblib>=0.15.1
|
||||||
|
jsmin>=2.2.2
|
||||||
|
livereload>=2.6.1
|
||||||
|
lunr>=0.5.8
|
||||||
|
Markdown>=3.2.2
|
||||||
|
markdown-include>=0.5.1
|
||||||
|
MarkupSafe>=1.1.1
|
||||||
|
mkdocs>=1.1.2
|
||||||
|
mkdocs-material>=5.2.1
|
||||||
|
mkdocs-material-extensions>=1.0
|
||||||
|
mkdocs-minify-plugin>=0.3.0
|
||||||
|
mkdocs-simple-hooks>=0.1.1
|
||||||
|
nltk>=3.5
|
||||||
|
plantuml>=0.3.0
|
||||||
|
plantuml-markdown>=3.2.2
|
||||||
|
Pygments>=2.6.1
|
||||||
|
pymdown-extensions>=7.1
|
||||||
|
PyYAML>=5.3.1
|
||||||
|
regex>=2020.5.14
|
||||||
|
six>=1.15.0
|
||||||
|
tornado>=6.0.4
|
||||||
|
tqdm>=4.46.0
|
||||||
|
zipp>=3.1.0
|
|
@ -54,6 +54,8 @@ class binary_reader
|
||||||
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;
|
||||||
using json_sax_t = SAX;
|
using json_sax_t = SAX;
|
||||||
|
using char_type = typename InputAdapterType::char_type;
|
||||||
|
using char_int_type = typename std::char_traits<char_type>::int_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
|
@ -122,7 +124,7 @@ class binary_reader
|
||||||
get();
|
get();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char>::eof()))
|
if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, get_token_string(),
|
return sax->parse_error(chars_read, get_token_string(),
|
||||||
parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
|
parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
|
||||||
|
@ -143,7 +145,7 @@ class binary_reader
|
||||||
*/
|
*/
|
||||||
bool parse_bson_internal()
|
bool parse_bson_internal()
|
||||||
{
|
{
|
||||||
std::int32_t document_size;
|
std::int32_t document_size{};
|
||||||
get_number<std::int32_t, true>(input_format_t::bson, document_size);
|
get_number<std::int32_t, true>(input_format_t::bson, document_size);
|
||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
|
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
|
||||||
|
@ -180,10 +182,8 @@ class binary_reader
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*out++ = static_cast<char>(current);
|
*out++ = static_cast<typename string_t::value_type>(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -206,7 +206,7 @@ class binary_reader
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
|
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char>::eof();
|
return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -228,7 +228,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
|
|
||||||
// All BSON binary values have a subtype
|
// All BSON binary values have a subtype
|
||||||
std::uint8_t subtype;
|
std::uint8_t subtype{};
|
||||||
get_number<std::uint8_t>(input_format_t::bson, subtype);
|
get_number<std::uint8_t>(input_format_t::bson, subtype);
|
||||||
result.set_subtype(subtype);
|
result.set_subtype(subtype);
|
||||||
|
|
||||||
|
@ -245,20 +245,20 @@ class binary_reader
|
||||||
Unsupported BSON record type 0x...
|
Unsupported BSON record type 0x...
|
||||||
@return whether a valid BSON-object/array was passed to the SAX parser
|
@return whether a valid BSON-object/array was passed to the SAX parser
|
||||||
*/
|
*/
|
||||||
bool parse_bson_element_internal(const int element_type,
|
bool parse_bson_element_internal(const char_int_type element_type,
|
||||||
const std::size_t element_type_parse_position)
|
const std::size_t element_type_parse_position)
|
||||||
{
|
{
|
||||||
switch (element_type)
|
switch (element_type)
|
||||||
{
|
{
|
||||||
case 0x01: // double
|
case 0x01: // double
|
||||||
{
|
{
|
||||||
double number;
|
double number{};
|
||||||
return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x02: // string
|
case 0x02: // string
|
||||||
{
|
{
|
||||||
std::int32_t len;
|
std::int32_t len{};
|
||||||
string_t value;
|
string_t value;
|
||||||
return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
|
return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ class binary_reader
|
||||||
|
|
||||||
case 0x05: // binary
|
case 0x05: // binary
|
||||||
{
|
{
|
||||||
std::int32_t len;
|
std::int32_t len{};
|
||||||
binary_t value;
|
binary_t value;
|
||||||
return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
|
return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
|
||||||
}
|
}
|
||||||
|
@ -292,13 +292,13 @@ class binary_reader
|
||||||
|
|
||||||
case 0x10: // int32
|
case 0x10: // int32
|
||||||
{
|
{
|
||||||
std::int32_t value;
|
std::int32_t value{};
|
||||||
return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
|
return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x12: // int64
|
case 0x12: // int64
|
||||||
{
|
{
|
||||||
std::int64_t value;
|
std::int64_t value{};
|
||||||
return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
|
return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ class binary_reader
|
||||||
{
|
{
|
||||||
string_t key;
|
string_t key;
|
||||||
|
|
||||||
while (int element_type = get())
|
while (auto element_type = get())
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
|
if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
|
||||||
{
|
{
|
||||||
|
@ -363,7 +363,7 @@ class binary_reader
|
||||||
*/
|
*/
|
||||||
bool parse_bson_array()
|
bool parse_bson_array()
|
||||||
{
|
{
|
||||||
std::int32_t document_size;
|
std::int32_t document_size{};
|
||||||
get_number<std::int32_t, true>(input_format_t::bson, document_size);
|
get_number<std::int32_t, true>(input_format_t::bson, document_size);
|
||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
|
if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
|
||||||
|
@ -395,7 +395,7 @@ class binary_reader
|
||||||
switch (get_char ? get() : current)
|
switch (get_char ? get() : current)
|
||||||
{
|
{
|
||||||
// EOF
|
// EOF
|
||||||
case std::char_traits<char>::eof():
|
case std::char_traits<char_type>::eof():
|
||||||
return unexpect_eof(input_format_t::cbor, "value");
|
return unexpect_eof(input_format_t::cbor, "value");
|
||||||
|
|
||||||
// Integer 0x00..0x17 (0..23)
|
// Integer 0x00..0x17 (0..23)
|
||||||
|
@ -427,25 +427,25 @@ class binary_reader
|
||||||
|
|
||||||
case 0x18: // Unsigned integer (one-byte uint8_t follows)
|
case 0x18: // Unsigned integer (one-byte uint8_t follows)
|
||||||
{
|
{
|
||||||
std::uint8_t number;
|
std::uint8_t number{};
|
||||||
return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
|
return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x19: // Unsigned integer (two-byte uint16_t follows)
|
case 0x19: // Unsigned integer (two-byte uint16_t follows)
|
||||||
{
|
{
|
||||||
std::uint16_t number;
|
std::uint16_t number{};
|
||||||
return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
|
return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x1A: // Unsigned integer (four-byte uint32_t follows)
|
case 0x1A: // Unsigned integer (four-byte uint32_t follows)
|
||||||
{
|
{
|
||||||
std::uint32_t number;
|
std::uint32_t number{};
|
||||||
return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
|
return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
|
case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
|
||||||
{
|
{
|
||||||
std::uint64_t number;
|
std::uint64_t number{};
|
||||||
return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
|
return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,25 +478,25 @@ class binary_reader
|
||||||
|
|
||||||
case 0x38: // Negative integer (one-byte uint8_t follows)
|
case 0x38: // Negative integer (one-byte uint8_t follows)
|
||||||
{
|
{
|
||||||
std::uint8_t number;
|
std::uint8_t number{};
|
||||||
return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
|
return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
|
case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
|
||||||
{
|
{
|
||||||
std::uint16_t number;
|
std::uint16_t number{};
|
||||||
return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
|
return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
|
case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
|
||||||
{
|
{
|
||||||
std::uint32_t number;
|
std::uint32_t number{};
|
||||||
return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
|
return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
|
case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
|
||||||
{
|
{
|
||||||
std::uint64_t number;
|
std::uint64_t number{};
|
||||||
return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
|
return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
|
||||||
- static_cast<number_integer_t>(number));
|
- static_cast<number_integer_t>(number));
|
||||||
}
|
}
|
||||||
|
@ -600,25 +600,25 @@ class binary_reader
|
||||||
|
|
||||||
case 0x98: // array (one-byte uint8_t for n follows)
|
case 0x98: // array (one-byte uint8_t for n follows)
|
||||||
{
|
{
|
||||||
std::uint8_t len;
|
std::uint8_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x99: // array (two-byte uint16_t for n follow)
|
case 0x99: // array (two-byte uint16_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint16_t len;
|
std::uint16_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x9A: // array (four-byte uint32_t for n follow)
|
case 0x9A: // array (four-byte uint32_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint32_t len;
|
std::uint32_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x9B: // array (eight-byte uint64_t for n follow)
|
case 0x9B: // array (eight-byte uint64_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint64_t len;
|
std::uint64_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,25 +654,25 @@ class binary_reader
|
||||||
|
|
||||||
case 0xB8: // map (one-byte uint8_t for n follows)
|
case 0xB8: // map (one-byte uint8_t for n follows)
|
||||||
{
|
{
|
||||||
std::uint8_t len;
|
std::uint8_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xB9: // map (two-byte uint16_t for n follow)
|
case 0xB9: // map (two-byte uint16_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint16_t len;
|
std::uint16_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xBA: // map (four-byte uint32_t for n follow)
|
case 0xBA: // map (four-byte uint32_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint32_t len;
|
std::uint32_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xBB: // map (eight-byte uint64_t for n follow)
|
case 0xBB: // map (eight-byte uint64_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint64_t len;
|
std::uint64_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len));
|
return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,12 +690,12 @@ class binary_reader
|
||||||
|
|
||||||
case 0xF9: // Half-Precision Float (two-byte IEEE 754)
|
case 0xF9: // Half-Precision Float (two-byte IEEE 754)
|
||||||
{
|
{
|
||||||
const int byte1_raw = get();
|
const auto byte1_raw = get();
|
||||||
if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
|
if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const int byte2_raw = get();
|
const auto byte2_raw = get();
|
||||||
if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
|
if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -738,13 +738,13 @@ class binary_reader
|
||||||
|
|
||||||
case 0xFA: // Single-Precision Float (four-byte IEEE 754)
|
case 0xFA: // Single-Precision Float (four-byte IEEE 754)
|
||||||
{
|
{
|
||||||
float number;
|
float number{};
|
||||||
return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
|
case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
|
||||||
{
|
{
|
||||||
double number;
|
double number{};
|
||||||
return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -807,25 +807,25 @@ class binary_reader
|
||||||
|
|
||||||
case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
|
case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
|
||||||
{
|
{
|
||||||
std::uint8_t len;
|
std::uint8_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
|
return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
|
case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint16_t len;
|
std::uint16_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
|
return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
|
case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint32_t len;
|
std::uint32_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
|
return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
|
case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint64_t len;
|
std::uint64_t len{};
|
||||||
return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
|
return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -902,28 +902,28 @@ 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) &&
|
return get_number(input_format_t::cbor, len) &&
|
||||||
get_binary(input_format_t::cbor, len, result);
|
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) &&
|
return get_number(input_format_t::cbor, len) &&
|
||||||
get_binary(input_format_t::cbor, len, result);
|
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) &&
|
return get_number(input_format_t::cbor, len) &&
|
||||||
get_binary(input_format_t::cbor, len, result);
|
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) &&
|
return get_number(input_format_t::cbor, len) &&
|
||||||
get_binary(input_format_t::cbor, len, result);
|
get_binary(input_format_t::cbor, len, result);
|
||||||
}
|
}
|
||||||
|
@ -1048,7 +1048,7 @@ class binary_reader
|
||||||
switch (get())
|
switch (get())
|
||||||
{
|
{
|
||||||
// EOF
|
// EOF
|
||||||
case std::char_traits<char>::eof():
|
case std::char_traits<char_type>::eof():
|
||||||
return unexpect_eof(input_format_t::msgpack, "value");
|
return unexpect_eof(input_format_t::msgpack, "value");
|
||||||
|
|
||||||
// positive fixint
|
// positive fixint
|
||||||
|
@ -1288,85 +1288,85 @@ class binary_reader
|
||||||
|
|
||||||
case 0xCA: // float 32
|
case 0xCA: // float 32
|
||||||
{
|
{
|
||||||
float number;
|
float number{};
|
||||||
return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xCB: // float 64
|
case 0xCB: // float 64
|
||||||
{
|
{
|
||||||
double number;
|
double number{};
|
||||||
return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xCC: // uint 8
|
case 0xCC: // uint 8
|
||||||
{
|
{
|
||||||
std::uint8_t number;
|
std::uint8_t number{};
|
||||||
return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
|
return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xCD: // uint 16
|
case 0xCD: // uint 16
|
||||||
{
|
{
|
||||||
std::uint16_t number;
|
std::uint16_t number{};
|
||||||
return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
|
return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xCE: // uint 32
|
case 0xCE: // uint 32
|
||||||
{
|
{
|
||||||
std::uint32_t number;
|
std::uint32_t number{};
|
||||||
return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
|
return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xCF: // uint 64
|
case 0xCF: // uint 64
|
||||||
{
|
{
|
||||||
std::uint64_t number;
|
std::uint64_t number{};
|
||||||
return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
|
return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD0: // int 8
|
case 0xD0: // int 8
|
||||||
{
|
{
|
||||||
std::int8_t number;
|
std::int8_t number{};
|
||||||
return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
|
return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD1: // int 16
|
case 0xD1: // int 16
|
||||||
{
|
{
|
||||||
std::int16_t number;
|
std::int16_t number{};
|
||||||
return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
|
return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD2: // int 32
|
case 0xD2: // int 32
|
||||||
{
|
{
|
||||||
std::int32_t number;
|
std::int32_t number{};
|
||||||
return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
|
return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD3: // int 64
|
case 0xD3: // int 64
|
||||||
{
|
{
|
||||||
std::int64_t number;
|
std::int64_t number{};
|
||||||
return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
|
return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xDC: // array 16
|
case 0xDC: // array 16
|
||||||
{
|
{
|
||||||
std::uint16_t len;
|
std::uint16_t len{};
|
||||||
return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
|
return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xDD: // array 32
|
case 0xDD: // array 32
|
||||||
{
|
{
|
||||||
std::uint32_t len;
|
std::uint32_t len{};
|
||||||
return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
|
return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xDE: // map 16
|
case 0xDE: // map 16
|
||||||
{
|
{
|
||||||
std::uint16_t len;
|
std::uint16_t len{};
|
||||||
return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
|
return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xDF: // map 32
|
case 0xDF: // map 32
|
||||||
{
|
{
|
||||||
std::uint32_t len;
|
std::uint32_t len{};
|
||||||
return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
|
return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1471,19 +1471,19 @@ class binary_reader
|
||||||
|
|
||||||
case 0xD9: // str 8
|
case 0xD9: // str 8
|
||||||
{
|
{
|
||||||
std::uint8_t len;
|
std::uint8_t len{};
|
||||||
return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
|
return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xDA: // str 16
|
case 0xDA: // str 16
|
||||||
{
|
{
|
||||||
std::uint16_t len;
|
std::uint16_t len{};
|
||||||
return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
|
return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xDB: // str 32
|
case 0xDB: // str 32
|
||||||
{
|
{
|
||||||
std::uint32_t len;
|
std::uint32_t len{};
|
||||||
return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
|
return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1518,29 +1518,29 @@ class binary_reader
|
||||||
{
|
{
|
||||||
case 0xC4: // bin 8
|
case 0xC4: // bin 8
|
||||||
{
|
{
|
||||||
std::uint8_t len;
|
std::uint8_t len{};
|
||||||
return get_number(input_format_t::msgpack, len) &&
|
return get_number(input_format_t::msgpack, len) &&
|
||||||
get_binary(input_format_t::msgpack, len, result);
|
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) &&
|
return get_number(input_format_t::msgpack, len) &&
|
||||||
get_binary(input_format_t::msgpack, len, result);
|
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) &&
|
return get_number(input_format_t::msgpack, len) &&
|
||||||
get_binary(input_format_t::msgpack, len, result);
|
get_binary(input_format_t::msgpack, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xC7: // ext 8
|
case 0xC7: // ext 8
|
||||||
{
|
{
|
||||||
std::uint8_t len;
|
std::uint8_t len{};
|
||||||
std::int8_t subtype;
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, len) &&
|
return get_number(input_format_t::msgpack, len) &&
|
||||||
get_number(input_format_t::msgpack, subtype) &&
|
get_number(input_format_t::msgpack, subtype) &&
|
||||||
get_binary(input_format_t::msgpack, len, result) &&
|
get_binary(input_format_t::msgpack, len, result) &&
|
||||||
|
@ -1549,8 +1549,8 @@ class binary_reader
|
||||||
|
|
||||||
case 0xC8: // ext 16
|
case 0xC8: // ext 16
|
||||||
{
|
{
|
||||||
std::uint16_t len;
|
std::uint16_t len{};
|
||||||
std::int8_t subtype;
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, len) &&
|
return get_number(input_format_t::msgpack, len) &&
|
||||||
get_number(input_format_t::msgpack, subtype) &&
|
get_number(input_format_t::msgpack, subtype) &&
|
||||||
get_binary(input_format_t::msgpack, len, result) &&
|
get_binary(input_format_t::msgpack, len, result) &&
|
||||||
|
@ -1559,8 +1559,8 @@ class binary_reader
|
||||||
|
|
||||||
case 0xC9: // ext 32
|
case 0xC9: // ext 32
|
||||||
{
|
{
|
||||||
std::uint32_t len;
|
std::uint32_t len{};
|
||||||
std::int8_t subtype;
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, len) &&
|
return get_number(input_format_t::msgpack, len) &&
|
||||||
get_number(input_format_t::msgpack, subtype) &&
|
get_number(input_format_t::msgpack, subtype) &&
|
||||||
get_binary(input_format_t::msgpack, len, result) &&
|
get_binary(input_format_t::msgpack, len, result) &&
|
||||||
|
@ -1569,7 +1569,7 @@ class binary_reader
|
||||||
|
|
||||||
case 0xD4: // fixext 1
|
case 0xD4: // fixext 1
|
||||||
{
|
{
|
||||||
std::int8_t subtype;
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, subtype) &&
|
return get_number(input_format_t::msgpack, subtype) &&
|
||||||
get_binary(input_format_t::msgpack, 1, result) &&
|
get_binary(input_format_t::msgpack, 1, result) &&
|
||||||
assign_and_return_true(subtype);
|
assign_and_return_true(subtype);
|
||||||
|
@ -1577,7 +1577,7 @@ class binary_reader
|
||||||
|
|
||||||
case 0xD5: // fixext 2
|
case 0xD5: // fixext 2
|
||||||
{
|
{
|
||||||
std::int8_t subtype;
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, subtype) &&
|
return get_number(input_format_t::msgpack, subtype) &&
|
||||||
get_binary(input_format_t::msgpack, 2, result) &&
|
get_binary(input_format_t::msgpack, 2, result) &&
|
||||||
assign_and_return_true(subtype);
|
assign_and_return_true(subtype);
|
||||||
|
@ -1585,7 +1585,7 @@ class binary_reader
|
||||||
|
|
||||||
case 0xD6: // fixext 4
|
case 0xD6: // fixext 4
|
||||||
{
|
{
|
||||||
std::int8_t subtype;
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, subtype) &&
|
return get_number(input_format_t::msgpack, subtype) &&
|
||||||
get_binary(input_format_t::msgpack, 4, result) &&
|
get_binary(input_format_t::msgpack, 4, result) &&
|
||||||
assign_and_return_true(subtype);
|
assign_and_return_true(subtype);
|
||||||
|
@ -1593,7 +1593,7 @@ class binary_reader
|
||||||
|
|
||||||
case 0xD7: // fixext 8
|
case 0xD7: // fixext 8
|
||||||
{
|
{
|
||||||
std::int8_t subtype;
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, subtype) &&
|
return get_number(input_format_t::msgpack, subtype) &&
|
||||||
get_binary(input_format_t::msgpack, 8, result) &&
|
get_binary(input_format_t::msgpack, 8, result) &&
|
||||||
assign_and_return_true(subtype);
|
assign_and_return_true(subtype);
|
||||||
|
@ -1601,7 +1601,7 @@ class binary_reader
|
||||||
|
|
||||||
case 0xD8: // fixext 16
|
case 0xD8: // fixext 16
|
||||||
{
|
{
|
||||||
std::int8_t subtype;
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, subtype) &&
|
return get_number(input_format_t::msgpack, subtype) &&
|
||||||
get_binary(input_format_t::msgpack, 16, result) &&
|
get_binary(input_format_t::msgpack, 16, result) &&
|
||||||
assign_and_return_true(subtype);
|
assign_and_return_true(subtype);
|
||||||
|
@ -1710,31 +1710,31 @@ class binary_reader
|
||||||
{
|
{
|
||||||
case 'U':
|
case 'U':
|
||||||
{
|
{
|
||||||
std::uint8_t len;
|
std::uint8_t len{};
|
||||||
return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
|
return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
{
|
{
|
||||||
std::int8_t len;
|
std::int8_t len{};
|
||||||
return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
|
return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'I':
|
case 'I':
|
||||||
{
|
{
|
||||||
std::int16_t len;
|
std::int16_t len{};
|
||||||
return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
|
return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
{
|
{
|
||||||
std::int32_t len;
|
std::int32_t len{};
|
||||||
return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
|
return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'L':
|
case 'L':
|
||||||
{
|
{
|
||||||
std::int64_t len;
|
std::int64_t len{};
|
||||||
return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
|
return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1754,7 +1754,7 @@ class binary_reader
|
||||||
{
|
{
|
||||||
case 'U':
|
case 'U':
|
||||||
{
|
{
|
||||||
std::uint8_t number;
|
std::uint8_t number{};
|
||||||
if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
|
if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -1765,7 +1765,7 @@ class binary_reader
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
{
|
{
|
||||||
std::int8_t number;
|
std::int8_t number{};
|
||||||
if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
|
if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -1776,7 +1776,7 @@ class binary_reader
|
||||||
|
|
||||||
case 'I':
|
case 'I':
|
||||||
{
|
{
|
||||||
std::int16_t number;
|
std::int16_t number{};
|
||||||
if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
|
if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -1787,7 +1787,7 @@ class binary_reader
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
{
|
{
|
||||||
std::int32_t number;
|
std::int32_t number{};
|
||||||
if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
|
if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -1798,7 +1798,7 @@ class binary_reader
|
||||||
|
|
||||||
case 'L':
|
case 'L':
|
||||||
{
|
{
|
||||||
std::int64_t number;
|
std::int64_t number{};
|
||||||
if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
|
if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -1825,7 +1825,7 @@ class binary_reader
|
||||||
|
|
||||||
@return whether pair creation completed
|
@return whether pair creation completed
|
||||||
*/
|
*/
|
||||||
bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
|
bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
|
||||||
{
|
{
|
||||||
result.first = string_t::npos; // size
|
result.first = string_t::npos; // size
|
||||||
result.second = 0; // type
|
result.second = 0; // type
|
||||||
|
@ -1866,11 +1866,11 @@ class binary_reader
|
||||||
@param prefix the previously read or set type prefix
|
@param prefix the previously read or set type prefix
|
||||||
@return whether value creation completed
|
@return whether value creation completed
|
||||||
*/
|
*/
|
||||||
bool get_ubjson_value(const int prefix)
|
bool get_ubjson_value(const char_int_type prefix)
|
||||||
{
|
{
|
||||||
switch (prefix)
|
switch (prefix)
|
||||||
{
|
{
|
||||||
case std::char_traits<char>::eof(): // EOF
|
case std::char_traits<char_type>::eof(): // EOF
|
||||||
return unexpect_eof(input_format_t::ubjson, "value");
|
return unexpect_eof(input_format_t::ubjson, "value");
|
||||||
|
|
||||||
case 'T': // true
|
case 'T': // true
|
||||||
|
@ -1883,43 +1883,43 @@ class binary_reader
|
||||||
|
|
||||||
case 'U':
|
case 'U':
|
||||||
{
|
{
|
||||||
std::uint8_t number;
|
std::uint8_t number{};
|
||||||
return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
|
return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
{
|
{
|
||||||
std::int8_t number;
|
std::int8_t number{};
|
||||||
return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
|
return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'I':
|
case 'I':
|
||||||
{
|
{
|
||||||
std::int16_t number;
|
std::int16_t number{};
|
||||||
return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
|
return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
{
|
{
|
||||||
std::int32_t number;
|
std::int32_t number{};
|
||||||
return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
|
return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'L':
|
case 'L':
|
||||||
{
|
{
|
||||||
std::int64_t number;
|
std::int64_t number{};
|
||||||
return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
|
return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
{
|
{
|
||||||
float number;
|
float number{};
|
||||||
return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
{
|
{
|
||||||
double number;
|
double number{};
|
||||||
return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1935,7 +1935,7 @@ class binary_reader
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
|
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
|
||||||
}
|
}
|
||||||
string_t s(1, static_cast<char>(current));
|
string_t s(1, static_cast<typename string_t::value_type>(current));
|
||||||
return sax->string(s);
|
return sax->string(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1964,7 +1964,7 @@ class binary_reader
|
||||||
*/
|
*/
|
||||||
bool get_ubjson_array()
|
bool get_ubjson_array()
|
||||||
{
|
{
|
||||||
std::pair<std::size_t, int> size_and_type;
|
std::pair<std::size_t, char_int_type> size_and_type;
|
||||||
if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
|
if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -2026,7 +2026,7 @@ class binary_reader
|
||||||
*/
|
*/
|
||||||
bool get_ubjson_object()
|
bool get_ubjson_object()
|
||||||
{
|
{
|
||||||
std::pair<std::size_t, int> size_and_type;
|
std::pair<std::size_t, char_int_type> size_and_type;
|
||||||
if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
|
if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -2108,11 +2108,11 @@ class binary_reader
|
||||||
|
|
||||||
This function provides the interface to the used input adapter. It does
|
This function provides the interface to the used input adapter. It does
|
||||||
not throw in case the input reached EOF, but returns a -'ve valued
|
not throw in case the input reached EOF, but returns a -'ve valued
|
||||||
`std::char_traits<char>::eof()` in that case.
|
`std::char_traits<char_type>::eof()` in that case.
|
||||||
|
|
||||||
@return character read from the input
|
@return character read from the input
|
||||||
*/
|
*/
|
||||||
int get()
|
char_int_type get()
|
||||||
{
|
{
|
||||||
++chars_read;
|
++chars_read;
|
||||||
return current = ia.get_character();
|
return current = ia.get_character();
|
||||||
|
@ -2121,7 +2121,7 @@ class binary_reader
|
||||||
/*!
|
/*!
|
||||||
@return character read from the input after ignoring all 'N' entries
|
@return character read from the input after ignoring all 'N' entries
|
||||||
*/
|
*/
|
||||||
int get_ignore_noop()
|
char_int_type get_ignore_noop()
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -2201,7 +2201,7 @@ class binary_reader
|
||||||
{
|
{
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
return static_cast<char>(current);
|
return std::char_traits<char_type>::to_char_type(current);
|
||||||
});
|
});
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -2246,7 +2246,7 @@ class binary_reader
|
||||||
JSON_HEDLEY_NON_NULL(3)
|
JSON_HEDLEY_NON_NULL(3)
|
||||||
bool unexpect_eof(const input_format_t format, const char* context) const
|
bool unexpect_eof(const input_format_t format, const char* context) const
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char>::eof()))
|
if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, "<end of file>",
|
return sax->parse_error(chars_read, "<end of file>",
|
||||||
parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
|
parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
|
||||||
|
@ -2306,7 +2306,7 @@ class binary_reader
|
||||||
InputAdapterType ia;
|
InputAdapterType ia;
|
||||||
|
|
||||||
/// the current character
|
/// the current character
|
||||||
int current = std::char_traits<char>::eof();
|
char_int_type current = std::char_traits<char_type>::eof();
|
||||||
|
|
||||||
/// the number of characters read
|
/// the number of characters read
|
||||||
std::size_t chars_read = 0;
|
std::size_t chars_read = 0;
|
||||||
|
|
|
@ -34,6 +34,8 @@ Input adapter for stdio file access. This adapter read only 1 byte and do not us
|
||||||
class file_input_adapter
|
class file_input_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using char_type = char;
|
||||||
|
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
JSON_HEDLEY_NON_NULL(2)
|
||||||
explicit file_input_adapter(std::FILE* f) noexcept
|
explicit file_input_adapter(std::FILE* f) noexcept
|
||||||
: m_file(f)
|
: m_file(f)
|
||||||
|
@ -68,11 +70,13 @@ subsequent call for input from the std::istream.
|
||||||
class input_stream_adapter
|
class input_stream_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using char_type = char;
|
||||||
|
|
||||||
~input_stream_adapter()
|
~input_stream_adapter()
|
||||||
{
|
{
|
||||||
// clear stream flags; we use underlying streambuf I/O, do not
|
// clear stream flags; we use underlying streambuf I/O, do not
|
||||||
// maintain ifstream flags, except eof
|
// maintain ifstream flags, except eof
|
||||||
if (is)
|
if (is != nullptr)
|
||||||
{
|
{
|
||||||
is->clear(is->rdstate() & std::ios::eofbit);
|
is->clear(is->rdstate() & std::ios::eofbit);
|
||||||
}
|
}
|
||||||
|
@ -100,7 +104,7 @@ class input_stream_adapter
|
||||||
{
|
{
|
||||||
auto res = sb->sbumpc();
|
auto res = sb->sbumpc();
|
||||||
// set eof manually, as we don't use the istream interface.
|
// set eof manually, as we don't use the istream interface.
|
||||||
if (res == EOF)
|
if (JSON_HEDLEY_UNLIKELY(res == EOF))
|
||||||
{
|
{
|
||||||
is->clear(is->rdstate() | std::ios::eofbit);
|
is->clear(is->rdstate() | std::ios::eofbit);
|
||||||
}
|
}
|
||||||
|
@ -113,51 +117,61 @@ class input_stream_adapter
|
||||||
std::streambuf* sb = nullptr;
|
std::streambuf* sb = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// input adapter for buffer input
|
// General-purpose iterator-based adapter. It might not be as fast as
|
||||||
class input_buffer_adapter
|
// theoretically possible for some containers, but it is extremely versatile.
|
||||||
|
template<typename IteratorType>
|
||||||
|
class iterator_input_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
input_buffer_adapter(const char* b, const std::size_t l) noexcept
|
using char_type = typename std::iterator_traits<IteratorType>::value_type;
|
||||||
: cursor(b), limit(b == nullptr ? nullptr : (b + l))
|
|
||||||
{}
|
|
||||||
|
|
||||||
// delete because of pointer members
|
iterator_input_adapter(IteratorType first, IteratorType last)
|
||||||
input_buffer_adapter(const input_buffer_adapter&) = delete;
|
: current(std::move(first)), end(std::move(last)) {}
|
||||||
input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
|
|
||||||
input_buffer_adapter(input_buffer_adapter&&) = default;
|
|
||||||
input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
|
|
||||||
|
|
||||||
std::char_traits<char>::int_type get_character() noexcept
|
typename std::char_traits<char_type>::int_type get_character()
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_LIKELY(cursor < limit))
|
if (JSON_HEDLEY_LIKELY(current != end))
|
||||||
{
|
{
|
||||||
assert(cursor != nullptr && limit != nullptr);
|
auto result = std::char_traits<char_type>::to_int_type(*current);
|
||||||
return std::char_traits<char>::to_int_type(*(cursor++));
|
std::advance(current, 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return std::char_traits<char_type>::eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::char_traits<char>::eof();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// pointer to the current character
|
IteratorType current;
|
||||||
const char* cursor;
|
IteratorType end;
|
||||||
/// pointer past the last character
|
|
||||||
const char* const limit;
|
template<typename BaseInputAdapter, size_t T>
|
||||||
|
friend struct wide_string_input_helper;
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return current == end;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename WideStringType, size_t T>
|
|
||||||
struct wide_string_input_helper
|
template<typename BaseInputAdapter, size_t T>
|
||||||
|
struct wide_string_input_helper;
|
||||||
|
|
||||||
|
template<typename BaseInputAdapter>
|
||||||
|
struct wide_string_input_helper<BaseInputAdapter, 4>
|
||||||
{
|
{
|
||||||
// UTF-32
|
// UTF-32
|
||||||
static void fill_buffer(const WideStringType& str,
|
static void fill_buffer(BaseInputAdapter& input,
|
||||||
size_t& current_wchar,
|
|
||||||
std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
|
std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
|
||||||
size_t& utf8_bytes_index,
|
size_t& utf8_bytes_index,
|
||||||
size_t& utf8_bytes_filled)
|
size_t& utf8_bytes_filled)
|
||||||
{
|
{
|
||||||
utf8_bytes_index = 0;
|
utf8_bytes_index = 0;
|
||||||
|
|
||||||
if (current_wchar == str.size())
|
if (JSON_HEDLEY_UNLIKELY(input.empty()))
|
||||||
{
|
{
|
||||||
utf8_bytes[0] = std::char_traits<char>::eof();
|
utf8_bytes[0] = std::char_traits<char>::eof();
|
||||||
utf8_bytes_filled = 1;
|
utf8_bytes_filled = 1;
|
||||||
|
@ -165,7 +179,7 @@ struct wide_string_input_helper
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// get the current character
|
// get the current character
|
||||||
const auto wc = static_cast<unsigned int>(str[current_wchar++]);
|
const auto wc = input.get_character();
|
||||||
|
|
||||||
// UTF-32 to UTF-8 encoding
|
// UTF-32 to UTF-8 encoding
|
||||||
if (wc < 0x80)
|
if (wc < 0x80)
|
||||||
|
@ -175,23 +189,23 @@ struct wide_string_input_helper
|
||||||
}
|
}
|
||||||
else if (wc <= 0x7FF)
|
else if (wc <= 0x7FF)
|
||||||
{
|
{
|
||||||
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
|
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
|
||||||
utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
|
utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
|
||||||
utf8_bytes_filled = 2;
|
utf8_bytes_filled = 2;
|
||||||
}
|
}
|
||||||
else if (wc <= 0xFFFF)
|
else if (wc <= 0xFFFF)
|
||||||
{
|
{
|
||||||
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
|
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
|
||||||
utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
|
utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
|
||||||
utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
|
utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
|
||||||
utf8_bytes_filled = 3;
|
utf8_bytes_filled = 3;
|
||||||
}
|
}
|
||||||
else if (wc <= 0x10FFFF)
|
else if (wc <= 0x10FFFF)
|
||||||
{
|
{
|
||||||
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
|
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
|
||||||
utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
|
utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
|
||||||
utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
|
utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
|
||||||
utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
|
utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
|
||||||
utf8_bytes_filled = 4;
|
utf8_bytes_filled = 4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -204,19 +218,18 @@ struct wide_string_input_helper
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename WideStringType>
|
template<typename BaseInputAdapter>
|
||||||
struct wide_string_input_helper<WideStringType, 2>
|
struct wide_string_input_helper<BaseInputAdapter, 2>
|
||||||
{
|
{
|
||||||
// UTF-16
|
// UTF-16
|
||||||
static void fill_buffer(const WideStringType& str,
|
static void fill_buffer(BaseInputAdapter& input,
|
||||||
size_t& current_wchar,
|
|
||||||
std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
|
std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
|
||||||
size_t& utf8_bytes_index,
|
size_t& utf8_bytes_index,
|
||||||
size_t& utf8_bytes_filled)
|
size_t& utf8_bytes_filled)
|
||||||
{
|
{
|
||||||
utf8_bytes_index = 0;
|
utf8_bytes_index = 0;
|
||||||
|
|
||||||
if (current_wchar == str.size())
|
if (JSON_HEDLEY_UNLIKELY(input.empty()))
|
||||||
{
|
{
|
||||||
utf8_bytes[0] = std::char_traits<char>::eof();
|
utf8_bytes[0] = std::char_traits<char>::eof();
|
||||||
utf8_bytes_filled = 1;
|
utf8_bytes_filled = 1;
|
||||||
|
@ -224,7 +237,7 @@ struct wide_string_input_helper<WideStringType, 2>
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// get the current character
|
// get the current character
|
||||||
const auto wc = static_cast<unsigned int>(str[current_wchar++]);
|
const auto wc = input.get_character();
|
||||||
|
|
||||||
// UTF-16 to UTF-8 encoding
|
// UTF-16 to UTF-8 encoding
|
||||||
if (wc < 0x80)
|
if (wc < 0x80)
|
||||||
|
@ -234,23 +247,23 @@ struct wide_string_input_helper<WideStringType, 2>
|
||||||
}
|
}
|
||||||
else if (wc <= 0x7FF)
|
else if (wc <= 0x7FF)
|
||||||
{
|
{
|
||||||
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u)));
|
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
|
||||||
utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
|
utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
|
||||||
utf8_bytes_filled = 2;
|
utf8_bytes_filled = 2;
|
||||||
}
|
}
|
||||||
else if (0xD800 > wc || wc >= 0xE000)
|
else if (0xD800 > wc || wc >= 0xE000)
|
||||||
{
|
{
|
||||||
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u)));
|
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
|
||||||
utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
|
utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
|
||||||
utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
|
utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
|
||||||
utf8_bytes_filled = 3;
|
utf8_bytes_filled = 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (current_wchar < str.size())
|
if (JSON_HEDLEY_UNLIKELY(not input.empty()))
|
||||||
{
|
{
|
||||||
const auto wc2 = static_cast<unsigned int>(str[current_wchar++]);
|
const auto wc2 = static_cast<unsigned int>(input.get_character());
|
||||||
const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
|
const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
|
||||||
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
|
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
|
||||||
utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
|
utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
|
||||||
utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
|
utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
|
||||||
|
@ -259,8 +272,6 @@ struct wide_string_input_helper<WideStringType, 2>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// unknown character
|
|
||||||
++current_wchar;
|
|
||||||
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
|
utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
|
||||||
utf8_bytes_filled = 1;
|
utf8_bytes_filled = 1;
|
||||||
}
|
}
|
||||||
|
@ -269,20 +280,22 @@ struct wide_string_input_helper<WideStringType, 2>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename WideStringType>
|
// Wraps another input apdater to convert wide character types into individual bytes.
|
||||||
|
template<typename BaseInputAdapter, typename WideCharType>
|
||||||
class wide_string_input_adapter
|
class wide_string_input_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit wide_string_input_adapter(const WideStringType& w) noexcept
|
using char_type = char;
|
||||||
: str(w)
|
|
||||||
{}
|
|
||||||
|
|
||||||
std::char_traits<char>::int_type get_character() noexcept
|
wide_string_input_adapter(BaseInputAdapter base)
|
||||||
|
: base_adapter(base) {}
|
||||||
|
|
||||||
|
typename std::char_traits<char>::int_type get_character() noexcept
|
||||||
{
|
{
|
||||||
// check if buffer needs to be filled
|
// check if buffer needs to be filled
|
||||||
if (utf8_bytes_index == utf8_bytes_filled)
|
if (utf8_bytes_index == utf8_bytes_filled)
|
||||||
{
|
{
|
||||||
fill_buffer<sizeof(typename WideStringType::value_type)>();
|
fill_buffer<sizeof(WideCharType)>();
|
||||||
|
|
||||||
assert(utf8_bytes_filled > 0);
|
assert(utf8_bytes_filled > 0);
|
||||||
assert(utf8_bytes_index == 0);
|
assert(utf8_bytes_index == 0);
|
||||||
|
@ -295,18 +308,14 @@ class wide_string_input_adapter
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
BaseInputAdapter base_adapter;
|
||||||
|
|
||||||
template<size_t T>
|
template<size_t T>
|
||||||
void fill_buffer()
|
void fill_buffer()
|
||||||
{
|
{
|
||||||
wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
|
wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// the wstring to process
|
|
||||||
const WideStringType& str;
|
|
||||||
|
|
||||||
/// index of the current wchar in str
|
|
||||||
std::size_t current_wchar = 0;
|
|
||||||
|
|
||||||
/// a buffer for UTF-8 bytes
|
/// a buffer for UTF-8 bytes
|
||||||
std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
|
std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
|
||||||
|
|
||||||
|
@ -316,6 +325,64 @@ class wide_string_input_adapter
|
||||||
std::size_t utf8_bytes_filled = 0;
|
std::size_t utf8_bytes_filled = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename IteratorType, typename Enable = void>
|
||||||
|
struct iterator_input_adapter_factory
|
||||||
|
{
|
||||||
|
using iterator_type = IteratorType;
|
||||||
|
using char_type = typename std::iterator_traits<iterator_type>::value_type;
|
||||||
|
using adapter_type = iterator_input_adapter<iterator_type>;
|
||||||
|
|
||||||
|
static adapter_type create(IteratorType first, IteratorType last)
|
||||||
|
{
|
||||||
|
return adapter_type(std::move(first), std::move(last));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_iterator_of_multibyte
|
||||||
|
{
|
||||||
|
using value_type = typename std::iterator_traits<T>::value_type;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
value = sizeof(value_type) > 1
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename IteratorType>
|
||||||
|
struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
|
||||||
|
{
|
||||||
|
using iterator_type = IteratorType;
|
||||||
|
using char_type = typename std::iterator_traits<iterator_type>::value_type;
|
||||||
|
using base_adapter_type = iterator_input_adapter<iterator_type>;
|
||||||
|
using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
|
||||||
|
|
||||||
|
static adapter_type create(IteratorType first, IteratorType last)
|
||||||
|
{
|
||||||
|
return adapter_type(base_adapter_type(std::move(first), std::move(last)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// General purpose iterator-based input
|
||||||
|
template<typename IteratorType>
|
||||||
|
typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
|
||||||
|
{
|
||||||
|
using factory_type = iterator_input_adapter_factory<IteratorType>;
|
||||||
|
return factory_type::create(first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience shorthand from container to iterator
|
||||||
|
template<typename ContainerType>
|
||||||
|
auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
|
||||||
|
{
|
||||||
|
// Enable ADL
|
||||||
|
using std::begin;
|
||||||
|
using std::end;
|
||||||
|
|
||||||
|
return input_adapter(begin(container), end(container));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special cases with fast paths
|
||||||
inline file_input_adapter input_adapter(std::FILE* file)
|
inline file_input_adapter input_adapter(std::FILE* file)
|
||||||
{
|
{
|
||||||
return file_input_adapter(file);
|
return file_input_adapter(file);
|
||||||
|
@ -331,97 +398,27 @@ inline input_stream_adapter input_adapter(std::istream&& stream)
|
||||||
return input_stream_adapter(stream);
|
return input_stream_adapter(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename CharT, typename SizeT,
|
using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
|
||||||
typename std::enable_if <
|
|
||||||
std::is_pointer<CharT>::value&&
|
|
||||||
std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
|
|
||||||
!std::is_same<SizeT, bool>::value&&
|
|
||||||
sizeof(typename std::remove_pointer<CharT>::type) == 1,
|
|
||||||
int >::type = 0 >
|
|
||||||
input_buffer_adapter input_adapter(CharT b, SizeT l)
|
|
||||||
{
|
|
||||||
return input_buffer_adapter(reinterpret_cast<const char*>(b), l);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Null-delimited strings, and the like.
|
||||||
template < typename CharT,
|
template < typename CharT,
|
||||||
typename std::enable_if <
|
typename std::enable_if <
|
||||||
std::is_pointer<CharT>::value&&
|
std::is_pointer<CharT>::value &&
|
||||||
std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
|
not std::is_array<CharT>::value &&
|
||||||
|
std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
|
||||||
sizeof(typename std::remove_pointer<CharT>::type) == 1,
|
sizeof(typename std::remove_pointer<CharT>::type) == 1,
|
||||||
int >::type = 0 >
|
int >::type = 0 >
|
||||||
input_buffer_adapter input_adapter(CharT b)
|
contiguous_bytes_input_adapter input_adapter(CharT b)
|
||||||
{
|
{
|
||||||
return input_adapter(reinterpret_cast<const char*>(b),
|
auto length = std::strlen(reinterpret_cast<const char*>(b));
|
||||||
std::strlen(reinterpret_cast<const char*>(b)));
|
const auto* ptr = reinterpret_cast<const char*>(b);
|
||||||
|
return input_adapter(ptr, ptr + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class IteratorType,
|
template<typename T, std::size_t N>
|
||||||
typename std::enable_if<
|
auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
|
||||||
std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
|
|
||||||
int>::type = 0>
|
|
||||||
input_buffer_adapter input_adapter(IteratorType first, IteratorType last)
|
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
return input_adapter(array, array + N);
|
||||||
// assertion to check that the iterator range is indeed contiguous,
|
|
||||||
// see https://stackoverflow.com/a/35008842/266378 for more discussion
|
|
||||||
const auto is_contiguous = std::accumulate(
|
|
||||||
first, last, std::pair<bool, int>(true, 0),
|
|
||||||
[&first](std::pair<bool, int> res, decltype(*first) val)
|
|
||||||
{
|
|
||||||
res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
|
|
||||||
return res;
|
|
||||||
}).first;
|
|
||||||
assert(is_contiguous);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// assertion to check that each element is 1 byte long
|
|
||||||
static_assert(
|
|
||||||
sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
|
|
||||||
"each element in the iterator range must have the size of 1 byte");
|
|
||||||
|
|
||||||
const auto len = static_cast<size_t>(std::distance(first, last));
|
|
||||||
if (JSON_HEDLEY_LIKELY(len > 0))
|
|
||||||
{
|
|
||||||
// there is at least one element: use the address of first
|
|
||||||
return input_buffer_adapter(reinterpret_cast<const char*>(&(*first)), len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// the address of first cannot be used: use nullptr
|
|
||||||
return input_buffer_adapter(nullptr, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline wide_string_input_adapter<std::wstring> input_adapter(const std::wstring& ws)
|
|
||||||
{
|
|
||||||
return wide_string_input_adapter<std::wstring>(ws);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline wide_string_input_adapter<std::u16string> input_adapter(const std::u16string& ws)
|
|
||||||
{
|
|
||||||
return wide_string_input_adapter<std::u16string>(ws);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline wide_string_input_adapter<std::u32string> input_adapter(const std::u32string& ws)
|
|
||||||
{
|
|
||||||
return wide_string_input_adapter<std::u32string>(ws);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < class ContiguousContainer, typename
|
|
||||||
std::enable_if < !std::is_pointer<ContiguousContainer>::value&&
|
|
||||||
std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
|
|
||||||
int >::type = 0 >
|
|
||||||
input_buffer_adapter input_adapter(const ContiguousContainer& c)
|
|
||||||
{
|
|
||||||
return input_adapter(std::begin(c), std::end(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
input_buffer_adapter input_adapter(T (&array)[N])
|
|
||||||
{
|
|
||||||
return input_adapter(std::begin(array), std::end(array));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This class only handles inputs of input_buffer_adapter type.
|
// This class only handles inputs of input_buffer_adapter type.
|
||||||
|
@ -437,17 +434,7 @@ class span_input_adapter
|
||||||
sizeof(typename std::remove_pointer<CharT>::type) == 1,
|
sizeof(typename std::remove_pointer<CharT>::type) == 1,
|
||||||
int >::type = 0 >
|
int >::type = 0 >
|
||||||
span_input_adapter(CharT b, std::size_t l)
|
span_input_adapter(CharT b, std::size_t l)
|
||||||
: ia(reinterpret_cast<const char*>(b), l) {}
|
: ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
|
||||||
|
|
||||||
template < typename CharT,
|
|
||||||
typename std::enable_if <
|
|
||||||
std::is_pointer<CharT>::value&&
|
|
||||||
std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
|
|
||||||
sizeof(typename std::remove_pointer<CharT>::type) == 1,
|
|
||||||
int >::type = 0 >
|
|
||||||
span_input_adapter(CharT b)
|
|
||||||
: span_input_adapter(reinterpret_cast<const char*>(b),
|
|
||||||
std::strlen(reinterpret_cast<const char*>(b))) {}
|
|
||||||
|
|
||||||
template<class IteratorType,
|
template<class IteratorType,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
|
@ -456,25 +443,13 @@ class span_input_adapter
|
||||||
span_input_adapter(IteratorType first, IteratorType last)
|
span_input_adapter(IteratorType first, IteratorType last)
|
||||||
: ia(input_adapter(first, last)) {}
|
: ia(input_adapter(first, last)) {}
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
contiguous_bytes_input_adapter&& get()
|
||||||
span_input_adapter(T (&array)[N])
|
|
||||||
: span_input_adapter(std::begin(array), std::end(array)) {}
|
|
||||||
|
|
||||||
/// input adapter for contiguous container
|
|
||||||
template < class ContiguousContainer, typename
|
|
||||||
std::enable_if < !std::is_pointer<ContiguousContainer>::value&&
|
|
||||||
std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
|
|
||||||
int >::type = 0 >
|
|
||||||
span_input_adapter(const ContiguousContainer& c)
|
|
||||||
: span_input_adapter(std::begin(c), std::end(c)) {}
|
|
||||||
|
|
||||||
input_buffer_adapter&& get()
|
|
||||||
{
|
{
|
||||||
return std::move(ia);
|
return std::move(ia);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
input_buffer_adapter ia;
|
contiguous_bytes_input_adapter ia;
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
|
|
@ -269,16 +269,16 @@ class json_sax_dom_parser
|
||||||
switch ((ex.id / 100) % 100)
|
switch ((ex.id / 100) % 100)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
|
JSON_THROW(*dynamic_cast<const detail::parse_error*>(&ex));
|
||||||
case 4:
|
case 4:
|
||||||
JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
|
JSON_THROW(*dynamic_cast<const detail::out_of_range*>(&ex));
|
||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
case 2:
|
case 2:
|
||||||
JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
|
JSON_THROW(*dynamic_cast<const detail::invalid_iterator*>(&ex));
|
||||||
case 3:
|
case 3:
|
||||||
JSON_THROW(*static_cast<const detail::type_error*>(&ex));
|
JSON_THROW(*dynamic_cast<const detail::type_error*>(&ex));
|
||||||
case 5:
|
case 5:
|
||||||
JSON_THROW(*static_cast<const detail::other_error*>(&ex));
|
JSON_THROW(*dynamic_cast<const detail::other_error*>(&ex));
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
@ -523,16 +523,16 @@ class json_sax_dom_callback_parser
|
||||||
switch ((ex.id / 100) % 100)
|
switch ((ex.id / 100) % 100)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
|
JSON_THROW(*dynamic_cast<const detail::parse_error*>(&ex));
|
||||||
case 4:
|
case 4:
|
||||||
JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
|
JSON_THROW(*dynamic_cast<const detail::out_of_range*>(&ex));
|
||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
case 2:
|
case 2:
|
||||||
JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
|
JSON_THROW(*dynamic_cast<const detail::invalid_iterator*>(&ex));
|
||||||
case 3:
|
case 3:
|
||||||
JSON_THROW(*static_cast<const detail::type_error*>(&ex));
|
JSON_THROW(*dynamic_cast<const detail::type_error*>(&ex));
|
||||||
case 5:
|
case 5:
|
||||||
JSON_THROW(*static_cast<const detail::other_error*>(&ex));
|
JSON_THROW(*dynamic_cast<const detail::other_error*>(&ex));
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
|
|
@ -106,12 +106,17 @@ class lexer : public lexer_base<BasicJsonType>
|
||||||
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 char_type = typename InputAdapterType::char_type;
|
||||||
|
using char_int_type = typename std::char_traits<char_type>::int_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using token_type = typename lexer_base<BasicJsonType>::token_type;
|
using token_type = typename lexer_base<BasicJsonType>::token_type;
|
||||||
|
|
||||||
explicit lexer(InputAdapterType&& adapter)
|
explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false)
|
||||||
: ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
|
: ia(std::move(adapter))
|
||||||
|
, ignore_comments(ignore_comments_)
|
||||||
|
, decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
|
||||||
|
{}
|
||||||
|
|
||||||
// delete because of pointer members
|
// delete because of pointer members
|
||||||
lexer(const lexer&) = delete;
|
lexer(const lexer&) = delete;
|
||||||
|
@ -129,7 +134,7 @@ class lexer : public lexer_base<BasicJsonType>
|
||||||
JSON_HEDLEY_PURE
|
JSON_HEDLEY_PURE
|
||||||
static char get_decimal_point() noexcept
|
static char get_decimal_point() noexcept
|
||||||
{
|
{
|
||||||
const auto loc = localeconv();
|
const auto* loc = localeconv();
|
||||||
assert(loc != nullptr);
|
assert(loc != nullptr);
|
||||||
return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
|
return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
|
||||||
}
|
}
|
||||||
|
@ -201,7 +206,7 @@ class lexer : public lexer_base<BasicJsonType>
|
||||||
|
|
||||||
@return true if and only if no range violation was detected
|
@return true if and only if no range violation was detected
|
||||||
*/
|
*/
|
||||||
bool next_byte_in_range(std::initializer_list<int> ranges)
|
bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
|
||||||
{
|
{
|
||||||
assert(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
|
assert(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
|
||||||
add(current);
|
add(current);
|
||||||
|
@ -252,7 +257,7 @@ class lexer : public lexer_base<BasicJsonType>
|
||||||
switch (get())
|
switch (get())
|
||||||
{
|
{
|
||||||
// end of file while parsing string
|
// end of file while parsing string
|
||||||
case std::char_traits<char>::eof():
|
case std::char_traits<char_type>::eof():
|
||||||
{
|
{
|
||||||
error_message = "invalid string: missing closing quote";
|
error_message = "invalid string: missing closing quote";
|
||||||
return token_type::parse_error;
|
return token_type::parse_error;
|
||||||
|
@ -370,28 +375,28 @@ class lexer : public lexer_base<BasicJsonType>
|
||||||
if (codepoint < 0x80)
|
if (codepoint < 0x80)
|
||||||
{
|
{
|
||||||
// 1-byte characters: 0xxxxxxx (ASCII)
|
// 1-byte characters: 0xxxxxxx (ASCII)
|
||||||
add(codepoint);
|
add(static_cast<char_int_type>(codepoint));
|
||||||
}
|
}
|
||||||
else if (codepoint <= 0x7FF)
|
else if (codepoint <= 0x7FF)
|
||||||
{
|
{
|
||||||
// 2-byte characters: 110xxxxx 10xxxxxx
|
// 2-byte characters: 110xxxxx 10xxxxxx
|
||||||
add(static_cast<int>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
|
add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
|
||||||
add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
|
add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
|
||||||
}
|
}
|
||||||
else if (codepoint <= 0xFFFF)
|
else if (codepoint <= 0xFFFF)
|
||||||
{
|
{
|
||||||
// 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
|
// 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
|
||||||
add(static_cast<int>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
|
add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
|
||||||
add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
|
add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
|
||||||
add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
|
add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
// 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
add(static_cast<int>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
|
add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
|
||||||
add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
|
add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
|
||||||
add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
|
add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
|
||||||
add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
|
add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -824,6 +829,77 @@ class lexer : public lexer_base<BasicJsonType>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief scan a comment
|
||||||
|
* @return whether comment could be scanned successfully
|
||||||
|
*/
|
||||||
|
bool scan_comment()
|
||||||
|
{
|
||||||
|
switch (get())
|
||||||
|
{
|
||||||
|
// single-line comments skip input until a newline or EOF is read
|
||||||
|
case '/':
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
switch (get())
|
||||||
|
{
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
case std::char_traits<char_type>::eof():
|
||||||
|
case '\0':
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// multi-line comments skip input until */ is read
|
||||||
|
case '*':
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
switch (get())
|
||||||
|
{
|
||||||
|
case std::char_traits<char_type>::eof():
|
||||||
|
case '\0':
|
||||||
|
{
|
||||||
|
error_message = "invalid comment; missing closing '*/'";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
case '*':
|
||||||
|
{
|
||||||
|
switch (get())
|
||||||
|
{
|
||||||
|
case '/':
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
unget();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unexpected character after reading '/'
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
error_message = "invalid comment; expecting '/' or '*' after '/'";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
JSON_HEDLEY_NON_NULL(2)
|
||||||
static void strtof(float& f, const char* str, char** endptr) noexcept
|
static void strtof(float& f, const char* str, char** endptr) noexcept
|
||||||
{
|
{
|
||||||
|
@ -1213,13 +1289,13 @@ scan_number_done:
|
||||||
@param[in] return_type the token type to return on success
|
@param[in] return_type the token type to return on success
|
||||||
*/
|
*/
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
JSON_HEDLEY_NON_NULL(2)
|
||||||
token_type scan_literal(const char* literal_text, const std::size_t length,
|
token_type scan_literal(const char_type* literal_text, const std::size_t length,
|
||||||
token_type return_type)
|
token_type return_type)
|
||||||
{
|
{
|
||||||
assert(current == literal_text[0]);
|
assert(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
|
||||||
for (std::size_t i = 1; i < length; ++i)
|
for (std::size_t i = 1; i < length; ++i)
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(get() != literal_text[i]))
|
if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
|
||||||
{
|
{
|
||||||
error_message = "invalid literal";
|
error_message = "invalid literal";
|
||||||
return token_type::parse_error;
|
return token_type::parse_error;
|
||||||
|
@ -1237,7 +1313,7 @@ scan_number_done:
|
||||||
{
|
{
|
||||||
token_buffer.clear();
|
token_buffer.clear();
|
||||||
token_string.clear();
|
token_string.clear();
|
||||||
token_string.push_back(std::char_traits<char>::to_char_type(current));
|
token_string.push_back(std::char_traits<char_type>::to_char_type(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1250,7 +1326,7 @@ scan_number_done:
|
||||||
|
|
||||||
@return character read from the input
|
@return character read from the input
|
||||||
*/
|
*/
|
||||||
std::char_traits<char>::int_type get()
|
char_int_type get()
|
||||||
{
|
{
|
||||||
++position.chars_read_total;
|
++position.chars_read_total;
|
||||||
++position.chars_read_current_line;
|
++position.chars_read_current_line;
|
||||||
|
@ -1265,9 +1341,9 @@ scan_number_done:
|
||||||
current = ia.get_character();
|
current = ia.get_character();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
|
if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
|
||||||
{
|
{
|
||||||
token_string.push_back(std::char_traits<char>::to_char_type(current));
|
token_string.push_back(std::char_traits<char_type>::to_char_type(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current == '\n')
|
if (current == '\n')
|
||||||
|
@ -1306,7 +1382,7 @@ scan_number_done:
|
||||||
--position.chars_read_current_line;
|
--position.chars_read_current_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
|
if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
|
||||||
{
|
{
|
||||||
assert(!token_string.empty());
|
assert(!token_string.empty());
|
||||||
token_string.pop_back();
|
token_string.pop_back();
|
||||||
|
@ -1314,9 +1390,9 @@ scan_number_done:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// add a character to token_buffer
|
/// add a character to token_buffer
|
||||||
void add(int c)
|
void add(char_int_type c)
|
||||||
{
|
{
|
||||||
token_buffer.push_back(std::char_traits<char>::to_char_type(c));
|
token_buffer.push_back(static_cast<typename string_t::value_type>(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -1377,7 +1453,7 @@ scan_number_done:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// add character as is
|
// add character as is
|
||||||
result.push_back(c);
|
result.push_back(static_cast<std::string::value_type>(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1413,6 +1489,15 @@ scan_number_done:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void skip_whitespace()
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
get();
|
||||||
|
}
|
||||||
|
while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
|
||||||
|
}
|
||||||
|
|
||||||
token_type scan()
|
token_type scan()
|
||||||
{
|
{
|
||||||
// initially, skip the BOM
|
// initially, skip the BOM
|
||||||
|
@ -1423,9 +1508,18 @@ scan_number_done:
|
||||||
}
|
}
|
||||||
|
|
||||||
// read next character and ignore whitespace
|
// read next character and ignore whitespace
|
||||||
do
|
skip_whitespace();
|
||||||
|
|
||||||
|
// ignore comments
|
||||||
|
if (ignore_comments and current == '/')
|
||||||
{
|
{
|
||||||
get();
|
if (not scan_comment())
|
||||||
|
{
|
||||||
|
return token_type::parse_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip following whitespace
|
||||||
|
skip_whitespace();
|
||||||
}
|
}
|
||||||
while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
|
while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
|
||||||
|
|
||||||
|
@ -1447,11 +1541,20 @@ scan_number_done:
|
||||||
|
|
||||||
// literals
|
// literals
|
||||||
case 't':
|
case 't':
|
||||||
return scan_literal("true", 4, token_type::literal_true);
|
{
|
||||||
|
std::array<char_type, 4> true_literal = {{'t', 'r', 'u', 'e'}};
|
||||||
|
return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
|
||||||
|
}
|
||||||
case 'f':
|
case 'f':
|
||||||
return scan_literal("false", 5, token_type::literal_false);
|
{
|
||||||
|
std::array<char_type, 5> false_literal = {{'f', 'a', 'l', 's', 'e'}};
|
||||||
|
return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
|
||||||
|
}
|
||||||
case 'n':
|
case 'n':
|
||||||
return scan_literal("null", 4, token_type::literal_null);
|
{
|
||||||
|
std::array<char_type, 4> null_literal = {{'n', 'u', 'l', 'l'}};
|
||||||
|
return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
|
||||||
|
}
|
||||||
|
|
||||||
// string
|
// string
|
||||||
case '\"':
|
case '\"':
|
||||||
|
@ -1474,7 +1577,7 @@ scan_number_done:
|
||||||
// end of input (the null byte is needed when parsing from
|
// end of input (the null byte is needed when parsing from
|
||||||
// string literals)
|
// string literals)
|
||||||
case '\0':
|
case '\0':
|
||||||
case std::char_traits<char>::eof():
|
case std::char_traits<char_type>::eof():
|
||||||
return token_type::end_of_input;
|
return token_type::end_of_input;
|
||||||
|
|
||||||
// error
|
// error
|
||||||
|
@ -1488,8 +1591,11 @@ scan_number_done:
|
||||||
/// input adapter
|
/// input adapter
|
||||||
InputAdapterType ia;
|
InputAdapterType ia;
|
||||||
|
|
||||||
|
/// whether comments should be ignored (true) or signaled as errors (false)
|
||||||
|
const bool ignore_comments = false;
|
||||||
|
|
||||||
/// the current character
|
/// the current character
|
||||||
std::char_traits<char>::int_type current = std::char_traits<char>::eof();
|
char_int_type current = std::char_traits<char_type>::eof();
|
||||||
|
|
||||||
/// whether the next get() call should just return current
|
/// whether the next get() call should just return current
|
||||||
bool next_unget = false;
|
bool next_unget = false;
|
||||||
|
@ -1498,7 +1604,7 @@ scan_number_done:
|
||||||
position_t position {};
|
position_t position {};
|
||||||
|
|
||||||
/// raw input token string (for error messages)
|
/// raw input token string (for error messages)
|
||||||
std::vector<char> token_string {};
|
std::vector<char_type> token_string {};
|
||||||
|
|
||||||
/// buffer for variable-length tokens (numbers, strings)
|
/// buffer for variable-length tokens (numbers, strings)
|
||||||
string_t token_buffer {};
|
string_t token_buffer {};
|
||||||
|
@ -1512,7 +1618,7 @@ scan_number_done:
|
||||||
number_float_t value_float = 0;
|
number_float_t value_float = 0;
|
||||||
|
|
||||||
/// the decimal point
|
/// the decimal point
|
||||||
const char decimal_point_char = '.';
|
const char_int_type decimal_point_char = '.';
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
|
|
@ -63,8 +63,11 @@ class parser
|
||||||
/// a parser reading from an input adapter
|
/// a parser reading from an input adapter
|
||||||
explicit parser(InputAdapterType&& adapter,
|
explicit parser(InputAdapterType&& adapter,
|
||||||
const parser_callback_t<BasicJsonType> cb = nullptr,
|
const parser_callback_t<BasicJsonType> cb = nullptr,
|
||||||
const bool allow_exceptions_ = true)
|
const bool allow_exceptions_ = true,
|
||||||
: callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
|
const bool skip_comments = false)
|
||||||
|
: callback(cb)
|
||||||
|
, m_lexer(std::move(adapter), skip_comments)
|
||||||
|
, allow_exceptions(allow_exceptions_)
|
||||||
{
|
{
|
||||||
// read first token
|
// read first token
|
||||||
get_token();
|
get_token();
|
||||||
|
|
|
@ -18,8 +18,6 @@ template<typename BasicJsonType> struct internal_iterator
|
||||||
typename BasicJsonType::object_t::iterator object_iterator {};
|
typename BasicJsonType::object_t::iterator object_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
|
|
||||||
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 {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,7 +15,9 @@ namespace detail
|
||||||
template<typename string_type>
|
template<typename string_type>
|
||||||
void int_to_string( string_type& target, std::size_t value )
|
void int_to_string( string_type& target, std::size_t value )
|
||||||
{
|
{
|
||||||
target = std::to_string(value);
|
// For ADL
|
||||||
|
using std::to_string;
|
||||||
|
target = to_string(value);
|
||||||
}
|
}
|
||||||
template<typename IteratorType> class iteration_proxy_value
|
template<typename IteratorType> class iteration_proxy_value
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <algorithm> // all_of
|
#include <algorithm> // all_of
|
||||||
#include <cassert> // assert
|
#include <cassert> // assert
|
||||||
#include <cctype> // isdigit
|
#include <cctype> // isdigit
|
||||||
|
#include <limits> // max
|
||||||
#include <numeric> // accumulate
|
#include <numeric> // accumulate
|
||||||
#include <string> // string
|
#include <string> // string
|
||||||
#include <utility> // move
|
#include <utility> // move
|
||||||
|
@ -325,10 +326,15 @@ class json_pointer
|
||||||
|
|
||||||
@return integer representation of @a s
|
@return integer representation of @a s
|
||||||
|
|
||||||
|
@throw parse_error.106 if an array index begins with '0'
|
||||||
|
@throw parse_error.109 if an array index begins not with a digit
|
||||||
@throw out_of_range.404 if string @a s could not be converted to an integer
|
@throw out_of_range.404 if string @a s could not be converted to an integer
|
||||||
|
@throw out_of_range.410 if an array index exceeds size_type
|
||||||
*/
|
*/
|
||||||
static int array_index(const std::string& s)
|
static typename BasicJsonType::size_type array_index(const std::string& s)
|
||||||
{
|
{
|
||||||
|
using size_type = typename BasicJsonType::size_type;
|
||||||
|
|
||||||
// error condition (cf. RFC 6901, Sect. 4)
|
// error condition (cf. RFC 6901, Sect. 4)
|
||||||
if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
|
if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
|
||||||
{
|
{
|
||||||
|
@ -344,10 +350,10 @@ class json_pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t processed_chars = 0;
|
std::size_t processed_chars = 0;
|
||||||
int res = 0;
|
unsigned long long res = 0;
|
||||||
JSON_TRY
|
JSON_TRY
|
||||||
{
|
{
|
||||||
res = std::stoi(s, &processed_chars);
|
res = std::stoull(s, &processed_chars);
|
||||||
}
|
}
|
||||||
JSON_CATCH(std::out_of_range&)
|
JSON_CATCH(std::out_of_range&)
|
||||||
{
|
{
|
||||||
|
@ -360,7 +366,14 @@ class json_pointer
|
||||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
|
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
// only triggered on special platforms (like 32bit), see also
|
||||||
|
// https://github.com/nlohmann/json/pull/2203
|
||||||
|
if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))
|
||||||
|
{
|
||||||
|
JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<size_type>(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
json_pointer top() const
|
json_pointer top() const
|
||||||
|
@ -419,7 +432,7 @@ class json_pointer
|
||||||
case detail::value_t::array:
|
case detail::value_t::array:
|
||||||
{
|
{
|
||||||
// create an entry in the array
|
// create an entry in the array
|
||||||
result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
|
result = &result->operator[](array_index(reference_token));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,8 +510,7 @@ class json_pointer
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// convert array index to number; unchecked access
|
// convert array index to number; unchecked access
|
||||||
ptr = &ptr->operator[](
|
ptr = &ptr->operator[](array_index(reference_token));
|
||||||
static_cast<size_type>(array_index(reference_token)));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -542,7 +554,7 @@ class json_pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
// note: at performs range check
|
// note: at performs range check
|
||||||
ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
|
ptr = &ptr->at(array_index(reference_token));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,8 +604,7 @@ class json_pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
// use unchecked array access
|
// use unchecked array access
|
||||||
ptr = &ptr->operator[](
|
ptr = &ptr->operator[](array_index(reference_token));
|
||||||
static_cast<size_type>(array_index(reference_token)));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,7 +647,7 @@ class json_pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
// note: at performs range check
|
// note: at performs range check
|
||||||
ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
|
ptr = &ptr->at(array_index(reference_token));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,7 +711,7 @@ class json_pointer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto idx = static_cast<size_type>(array_index(reference_token));
|
const auto idx = array_index(reference_token);
|
||||||
if (idx >= ptr->size())
|
if (idx >= ptr->size())
|
||||||
{
|
{
|
||||||
// index out of range
|
// index out of range
|
||||||
|
|
|
@ -16,23 +16,30 @@ class json_ref
|
||||||
using value_type = BasicJsonType;
|
using value_type = BasicJsonType;
|
||||||
|
|
||||||
json_ref(value_type&& value)
|
json_ref(value_type&& value)
|
||||||
: owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
|
: owned_value(std::move(value))
|
||||||
|
, value_ref(&owned_value)
|
||||||
|
, is_rvalue(true)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json_ref(const value_type& value)
|
json_ref(const value_type& value)
|
||||||
: value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
|
: value_ref(const_cast<value_type*>(&value))
|
||||||
|
, is_rvalue(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json_ref(std::initializer_list<json_ref> init)
|
json_ref(std::initializer_list<json_ref> init)
|
||||||
: owned_value(init), value_ref(&owned_value), is_rvalue(true)
|
: owned_value(init)
|
||||||
|
, value_ref(&owned_value)
|
||||||
|
, is_rvalue(true)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class... Args,
|
class... Args,
|
||||||
enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
|
enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
|
||||||
json_ref(Args && ... args)
|
json_ref(Args && ... args)
|
||||||
: owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
|
: owned_value(std::forward<Args>(args)...)
|
||||||
is_rvalue(true) {}
|
, value_ref(&owned_value)
|
||||||
|
, is_rvalue(true)
|
||||||
|
{}
|
||||||
|
|
||||||
// class should be movable only
|
// class should be movable only
|
||||||
json_ref(json_ref&&) = default;
|
json_ref(json_ref&&) = default;
|
||||||
|
@ -63,7 +70,7 @@ class json_ref
|
||||||
private:
|
private:
|
||||||
mutable value_type owned_value = nullptr;
|
mutable value_type owned_value = nullptr;
|
||||||
value_type* value_ref = nullptr;
|
value_type* value_ref = nullptr;
|
||||||
const bool is_rvalue;
|
const bool is_rvalue = true;
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
|
|
@ -20,7 +20,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// C++ language standard detection
|
// C++ language standard detection
|
||||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
|
#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
|
||||||
|
#define JSON_HAS_CPP_20
|
||||||
|
#define JSON_HAS_CPP_17
|
||||||
|
#define JSON_HAS_CPP_14
|
||||||
|
#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
|
||||||
#define JSON_HAS_CPP_17
|
#define JSON_HAS_CPP_17
|
||||||
#define JSON_HAS_CPP_14
|
#define JSON_HAS_CPP_14
|
||||||
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
|
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
|
||||||
|
|
|
@ -28,6 +28,7 @@ class binary_writer
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
|
@ -194,18 +195,7 @@ class binary_writer
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (static_cast<double>(j.m_value.number_float) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
|
write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
|
||||||
static_cast<double>(j.m_value.number_float) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
|
|
||||||
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)));
|
|
||||||
write_number(static_cast<float>(j.m_value.number_float));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
|
|
||||||
write_number(j.m_value.number_float);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -504,8 +494,7 @@ class binary_writer
|
||||||
|
|
||||||
case value_t::number_float:
|
case value_t::number_float:
|
||||||
{
|
{
|
||||||
oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
|
write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
|
||||||
write_number(j.m_value.number_float);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,7 +573,7 @@ class binary_writer
|
||||||
const auto N = j.m_value.binary->size();
|
const auto N = j.m_value.binary->size();
|
||||||
if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
||||||
{
|
{
|
||||||
std::uint8_t output_type;
|
std::uint8_t output_type{};
|
||||||
bool fixed = true;
|
bool fixed = true;
|
||||||
if (use_ext)
|
if (use_ext)
|
||||||
{
|
{
|
||||||
|
@ -626,30 +615,18 @@ class binary_writer
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||||
{
|
{
|
||||||
std::uint8_t output_type;
|
std::uint8_t output_type = use_ext
|
||||||
if (use_ext)
|
? 0xC8 // ext 16
|
||||||
{
|
: 0xC5; // bin 16
|
||||||
output_type = 0xC8; // ext 16
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
output_type = 0xC5; // bin 16
|
|
||||||
}
|
|
||||||
|
|
||||||
oa->write_character(to_char_type(output_type));
|
oa->write_character(to_char_type(output_type));
|
||||||
write_number(static_cast<std::uint16_t>(N));
|
write_number(static_cast<std::uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||||
{
|
{
|
||||||
std::uint8_t output_type;
|
std::uint8_t output_type = use_ext
|
||||||
if (use_ext)
|
? 0xC9 // ext 32
|
||||||
{
|
: 0xC6; // bin 32
|
||||||
output_type = 0xC9; // ext 32
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
output_type = 0xC6; // bin 32
|
|
||||||
}
|
|
||||||
|
|
||||||
oa->write_character(to_char_type(output_type));
|
oa->write_character(to_char_type(output_type));
|
||||||
write_number(static_cast<std::uint32_t>(N));
|
write_number(static_cast<std::uint32_t>(N));
|
||||||
|
@ -1518,6 +1495,26 @@ class binary_writer
|
||||||
oa->write_characters(vec.data(), sizeof(NumberType));
|
oa->write_characters(vec.data(), sizeof(NumberType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void write_compact_float(const number_float_t n, detail::input_format_t format)
|
||||||
|
{
|
||||||
|
if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) and
|
||||||
|
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) and
|
||||||
|
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
|
||||||
|
{
|
||||||
|
oa->write_character(format == detail::input_format_t::cbor
|
||||||
|
? get_cbor_float_prefix(static_cast<float>(n))
|
||||||
|
: get_msgpack_float_prefix(static_cast<float>(n)));
|
||||||
|
write_number(static_cast<float>(n));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oa->write_character(format == detail::input_format_t::cbor
|
||||||
|
? get_cbor_float_prefix(n)
|
||||||
|
: get_msgpack_float_prefix(n));
|
||||||
|
write_number(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// The following to_char_type functions are implement the conversion
|
// The following to_char_type functions are implement the conversion
|
||||||
// between uint8_t and CharType. In case CharType is not unsigned,
|
// between uint8_t and CharType. In case CharType is not unsigned,
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <cstdint> // uint8_t
|
#include <cstdint> // uint8_t
|
||||||
#include <cstdio> // snprintf
|
#include <cstdio> // snprintf
|
||||||
#include <limits> // numeric_limits
|
#include <limits> // numeric_limits
|
||||||
#include <string> // string
|
#include <string> // string, char_traits
|
||||||
#include <type_traits> // is_same
|
#include <type_traits> // is_same
|
||||||
#include <utility> // move
|
#include <utility> // move
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ class serializer
|
||||||
error_handler_t error_handler_ = error_handler_t::strict)
|
error_handler_t error_handler_ = error_handler_t::strict)
|
||||||
: o(std::move(s))
|
: o(std::move(s))
|
||||||
, loc(std::localeconv())
|
, loc(std::localeconv())
|
||||||
, thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
|
, thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
|
||||||
, decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
|
, decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
|
||||||
, indent_char(ichar)
|
, indent_char(ichar)
|
||||||
, indent_string(512, indent_char)
|
, indent_string(512, indent_char)
|
||||||
, error_handler(error_handler_)
|
, error_handler(error_handler_)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++
|
__| | __| | | | JSON for Modern C++
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
@ -31,8 +31,8 @@ SOFTWARE.
|
||||||
#define INCLUDE_NLOHMANN_JSON_HPP_
|
#define INCLUDE_NLOHMANN_JSON_HPP_
|
||||||
|
|
||||||
#define NLOHMANN_JSON_VERSION_MAJOR 3
|
#define NLOHMANN_JSON_VERSION_MAJOR 3
|
||||||
#define NLOHMANN_JSON_VERSION_MINOR 7
|
#define NLOHMANN_JSON_VERSION_MINOR 8
|
||||||
#define NLOHMANN_JSON_VERSION_PATCH 3
|
#define NLOHMANN_JSON_VERSION_PATCH 0
|
||||||
|
|
||||||
#include <algorithm> // all_of, find, for_each
|
#include <algorithm> // all_of, find, for_each
|
||||||
#include <cassert> // assert
|
#include <cassert> // assert
|
||||||
|
@ -196,10 +196,12 @@ class basic_json
|
||||||
static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
|
static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
|
||||||
InputAdapterType adapter,
|
InputAdapterType adapter,
|
||||||
detail::parser_callback_t<basic_json>cb = nullptr,
|
detail::parser_callback_t<basic_json>cb = nullptr,
|
||||||
bool allow_exceptions = true
|
const bool allow_exceptions = true,
|
||||||
|
const bool ignore_comments = false
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter), std::move(cb), allow_exceptions);
|
return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
|
||||||
|
std::move(cb), allow_exceptions, ignore_comments);
|
||||||
}
|
}
|
||||||
|
|
||||||
using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
|
using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
|
||||||
|
@ -1048,7 +1050,7 @@ class basic_json
|
||||||
object = nullptr; // silence warning, see #821
|
object = nullptr; // silence warning, see #821
|
||||||
if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
|
if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
|
||||||
{
|
{
|
||||||
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.7.3")); // LCOV_EXCL_LINE
|
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.8.0")); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3770,7 +3772,7 @@ class basic_json
|
||||||
template < class ValueType, typename std::enable_if <
|
template < class ValueType, typename std::enable_if <
|
||||||
std::is_convertible<basic_json_t, ValueType>::value
|
std::is_convertible<basic_json_t, ValueType>::value
|
||||||
&& !std::is_same<value_t, ValueType>::value, int >::type = 0 >
|
&& !std::is_same<value_t, ValueType>::value, int >::type = 0 >
|
||||||
ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
|
ValueType value(const typename object_t::key_type& key, ValueType && default_value) const
|
||||||
{
|
{
|
||||||
// at only works for objects
|
// at only works for objects
|
||||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||||
|
@ -3782,7 +3784,7 @@ class basic_json
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
return default_value;
|
return std::move(default_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
|
JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
|
||||||
|
@ -3794,7 +3796,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
string_t value(const typename object_t::key_type& key, const char* default_value) const
|
string_t value(const typename object_t::key_type& key, const char* default_value) const
|
||||||
{
|
{
|
||||||
return value(key, string_t(default_value));
|
return value(key, std::move(string_t(default_value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -3842,7 +3844,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
template<class ValueType, typename std::enable_if<
|
template<class ValueType, typename std::enable_if<
|
||||||
std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
|
std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
|
||||||
ValueType value(const json_pointer& ptr, const ValueType& default_value) const
|
ValueType value(const json_pointer& ptr, ValueType && default_value) const
|
||||||
{
|
{
|
||||||
// at only works for objects
|
// at only works for objects
|
||||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||||
|
@ -3854,7 +3856,7 @@ class basic_json
|
||||||
}
|
}
|
||||||
JSON_INTERNAL_CATCH (out_of_range&)
|
JSON_INTERNAL_CATCH (out_of_range&)
|
||||||
{
|
{
|
||||||
return default_value;
|
return std::move(default_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3868,7 +3870,7 @@ class basic_json
|
||||||
JSON_HEDLEY_NON_NULL(3)
|
JSON_HEDLEY_NON_NULL(3)
|
||||||
string_t value(const json_pointer& ptr, const char* default_value) const
|
string_t value(const json_pointer& ptr, const char* default_value) const
|
||||||
{
|
{
|
||||||
return value(ptr, string_t(default_value));
|
return value(ptr, std::move(string_t(default_value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -4764,7 +4766,7 @@ class basic_json
|
||||||
future 4.0.0 of the library. Please use @ref items() instead;
|
future 4.0.0 of the library. Please use @ref items() instead;
|
||||||
that is, replace `json::iterator_wrapper(j)` with `j.items()`.
|
that is, replace `json::iterator_wrapper(j)` with `j.items()`.
|
||||||
*/
|
*/
|
||||||
JSON_HEDLEY_DEPRECATED(3.1.0)
|
JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
|
||||||
static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
|
static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
|
||||||
{
|
{
|
||||||
return ref.items();
|
return ref.items();
|
||||||
|
@ -4773,7 +4775,7 @@ class basic_json
|
||||||
/*!
|
/*!
|
||||||
@copydoc iterator_wrapper(reference)
|
@copydoc iterator_wrapper(reference)
|
||||||
*/
|
*/
|
||||||
JSON_HEDLEY_DEPRECATED(3.1.0)
|
JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
|
||||||
static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
|
static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
|
||||||
{
|
{
|
||||||
return ref.items();
|
return ref.items();
|
||||||
|
@ -5865,6 +5867,34 @@ class basic_json
|
||||||
/*!
|
/*!
|
||||||
@brief exchanges the values
|
@brief exchanges the values
|
||||||
|
|
||||||
|
Exchanges the contents of the JSON value from @a left with those of @a right. Does not
|
||||||
|
invoke any move, copy, or swap operations on individual elements. All
|
||||||
|
iterators and references remain valid. The past-the-end iterator is
|
||||||
|
invalidated. implemented as a friend function callable via ADL.
|
||||||
|
|
||||||
|
@param[in,out] left JSON value to exchange the contents with
|
||||||
|
@param[in,out] right JSON value to exchange the contents with
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how JSON values can be swapped with
|
||||||
|
`swap()`.,swap__reference}
|
||||||
|
|
||||||
|
@since version 1.0.0
|
||||||
|
*/
|
||||||
|
friend void swap(reference left, reference right) noexcept (
|
||||||
|
std::is_nothrow_move_constructible<value_t>::value and
|
||||||
|
std::is_nothrow_move_assignable<value_t>::value and
|
||||||
|
std::is_nothrow_move_constructible<json_value>::value and
|
||||||
|
std::is_nothrow_move_assignable<json_value>::value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
left.swap(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief exchanges the values
|
||||||
|
|
||||||
Exchanges the contents of a JSON array with those of @a other. Does not
|
Exchanges the contents of a JSON array with those of @a other. Does not
|
||||||
invoke any move, copy, or swap operations on individual elements. All
|
invoke any move, copy, or swap operations on individual elements. All
|
||||||
iterators and references remain valid. The past-the-end iterator is
|
iterators and references remain valid. The past-the-end iterator is
|
||||||
|
@ -6530,7 +6560,7 @@ class basic_json
|
||||||
instead; that is, replace calls like `j >> o;` with `o << j;`.
|
instead; that is, replace calls like `j >> o;` with `o << j;`.
|
||||||
@since version 1.0.0; deprecated since version 3.0.0
|
@since version 1.0.0; deprecated since version 3.0.0
|
||||||
*/
|
*/
|
||||||
JSON_HEDLEY_DEPRECATED(3.0.0)
|
JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
|
||||||
friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
|
friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
|
||||||
{
|
{
|
||||||
return o << j;
|
return o << j;
|
||||||
|
@ -6549,29 +6579,13 @@ class basic_json
|
||||||
/*!
|
/*!
|
||||||
@brief deserialize from a compatible input
|
@brief deserialize from a compatible input
|
||||||
|
|
||||||
This function reads from a compatible input. Examples are:
|
@tparam InputType A compatible input, for instance
|
||||||
- an array of 1-byte values
|
- an std::istream object
|
||||||
- strings with character/literal type with size of 1 byte
|
- a FILE pointer
|
||||||
- input streams
|
- a C-style array of characters
|
||||||
- container with contiguous storage of 1-byte values. Compatible container
|
- a pointer to a null-terminated string of single byte characters
|
||||||
types include `std::vector`, `std::string`, `std::array`,
|
- an object obj for which begin(obj) and end(obj) produces a valid pair of
|
||||||
`std::valarray`, and `std::initializer_list`. Furthermore, C-style
|
iterators.
|
||||||
arrays can be used with `std::begin()`/`std::end()`. User-defined
|
|
||||||
containers can be used as long as they implement random-access iterators
|
|
||||||
and a contiguous storage.
|
|
||||||
|
|
||||||
@pre Each element of the container has a size of 1 byte. Violating this
|
|
||||||
precondition yields undefined behavior. **This precondition is enforced
|
|
||||||
with a static assertion.**
|
|
||||||
|
|
||||||
@pre The container storage is contiguous. Violating this precondition
|
|
||||||
yields undefined behavior. **This precondition is enforced with an
|
|
||||||
assertion.**
|
|
||||||
|
|
||||||
@warning There is no way to enforce all preconditions at compile-time. If
|
|
||||||
the function is called with a noncompliant container and with
|
|
||||||
assertions switched off, the behavior is undefined and will most
|
|
||||||
likely yield segmentation violation.
|
|
||||||
|
|
||||||
@param[in] i input to read from
|
@param[in] i input to read from
|
||||||
@param[in] cb a parser callback function of type @ref parser_callback_t
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
|
@ -6579,6 +6593,9 @@ class basic_json
|
||||||
(optional)
|
(optional)
|
||||||
@param[in] allow_exceptions whether to throw exceptions in case of a
|
@param[in] allow_exceptions whether to throw exceptions in case of a
|
||||||
parse error (optional, true by default)
|
parse error (optional, true by default)
|
||||||
|
@param[in] ignore_comments whether comments should be ignored and treated
|
||||||
|
like whitespace (true) or yield a parse error (true); (optional, false by
|
||||||
|
default)
|
||||||
|
|
||||||
@return deserialized JSON value; in case of a parse error and
|
@return deserialized JSON value; in case of a parse error and
|
||||||
@a allow_exceptions set to `false`, the return value will be
|
@a allow_exceptions set to `false`, the return value will be
|
||||||
|
@ -6591,7 +6608,7 @@ class basic_json
|
||||||
|
|
||||||
@complexity Linear in the length of the input. The parser is a predictive
|
@complexity Linear in the length of the input. The parser is a predictive
|
||||||
LL(1) parser. The complexity can be higher if the parser callback function
|
LL(1) parser. The complexity can be higher if the parser callback function
|
||||||
@a cb has a super-linear complexity.
|
@a cb or reading from the input @a i has a super-linear complexity.
|
||||||
|
|
||||||
@note A UTF-8 byte order mark is silently ignored.
|
@note A UTF-8 byte order mark is silently ignored.
|
||||||
|
|
||||||
|
@ -6607,74 +6624,144 @@ class basic_json
|
||||||
@liveexample{The example below demonstrates the `parse()` function reading
|
@liveexample{The example below demonstrates the `parse()` function reading
|
||||||
from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
|
from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
|
||||||
|
|
||||||
@since version 2.0.3 (contiguous containers)
|
@since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
|
||||||
|
ignore comments.
|
||||||
*/
|
*/
|
||||||
template<typename InputType>
|
template<typename InputType>
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
static basic_json parse(InputType&& i,
|
static basic_json parse(InputType&& i,
|
||||||
const parser_callback_t cb = nullptr,
|
const parser_callback_t cb = nullptr,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true,
|
||||||
|
const bool ignore_comments = false)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions).parse(true, result);
|
parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief deserialize from a pair of character iterators
|
||||||
|
|
||||||
|
The value_type of the iterator must be a integral type with size of 1, 2 or
|
||||||
|
4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
|
||||||
|
|
||||||
|
@param[in] first iterator to start of character range
|
||||||
|
@param[in] last iterator to end of character range
|
||||||
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
|
which is used to control the deserialization by filtering unwanted values
|
||||||
|
(optional)
|
||||||
|
@param[in] allow_exceptions whether to throw exceptions in case of a
|
||||||
|
parse error (optional, true by default)
|
||||||
|
@param[in] ignore_comments whether comments should be ignored and treated
|
||||||
|
like whitespace (true) or yield a parse error (true); (optional, false by
|
||||||
|
default)
|
||||||
|
|
||||||
|
@return deserialized JSON value; in case of a parse error and
|
||||||
|
@a allow_exceptions set to `false`, the return value will be
|
||||||
|
value_t::discarded.
|
||||||
|
|
||||||
|
@throw parse_error.101 if a parse error occurs; example: `""unexpected end
|
||||||
|
of input; expected string literal""`
|
||||||
|
@throw parse_error.102 if to_unicode fails or surrogate error
|
||||||
|
@throw parse_error.103 if to_unicode fails
|
||||||
|
*/
|
||||||
|
template<typename IteratorType>
|
||||||
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
static basic_json parse(IteratorType first,
|
||||||
|
IteratorType last,
|
||||||
|
const parser_callback_t cb = nullptr,
|
||||||
|
const bool allow_exceptions = true,
|
||||||
|
const bool ignore_comments = false)
|
||||||
|
{
|
||||||
|
basic_json result;
|
||||||
|
parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
|
||||||
static basic_json parse(detail::span_input_adapter&& i,
|
static basic_json parse(detail::span_input_adapter&& i,
|
||||||
const parser_callback_t cb = nullptr,
|
const parser_callback_t cb = nullptr,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true,
|
||||||
|
const bool ignore_comments = false)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
parser(i.get(), cb, allow_exceptions).parse(true, result);
|
parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief check if the input is valid JSON
|
||||||
|
|
||||||
|
Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)
|
||||||
|
function, this function neither throws an exception in case of invalid JSON
|
||||||
|
input (i.e., a parse error) nor creates diagnostic information.
|
||||||
|
|
||||||
|
@tparam InputType A compatible input, for instance
|
||||||
|
- an std::istream object
|
||||||
|
- a FILE pointer
|
||||||
|
- a C-style array of characters
|
||||||
|
- a pointer to a null-terminated string of single byte characters
|
||||||
|
- an object obj for which begin(obj) and end(obj) produces a valid pair of
|
||||||
|
iterators.
|
||||||
|
|
||||||
|
@param[in] i input to read from
|
||||||
|
@param[in] ignore_comments whether comments should be ignored and treated
|
||||||
|
like whitespace (true) or yield a parse error (true); (optional, false by
|
||||||
|
default)
|
||||||
|
|
||||||
|
@return Whether the input read from @a i is valid JSON.
|
||||||
|
|
||||||
|
@complexity Linear in the length of the input. The parser is a predictive
|
||||||
|
LL(1) parser.
|
||||||
|
|
||||||
|
@note A UTF-8 byte order mark is silently ignored.
|
||||||
|
|
||||||
|
@liveexample{The example below demonstrates the `accept()` function reading
|
||||||
|
from a string.,accept__string}
|
||||||
|
*/
|
||||||
template<typename InputType>
|
template<typename InputType>
|
||||||
static bool accept(InputType&& i)
|
static bool accept(InputType&& i,
|
||||||
|
const bool ignore_comments = false)
|
||||||
{
|
{
|
||||||
return parser(detail::input_adapter(std::forward<InputType>(i))).accept(true);
|
return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool accept(detail::span_input_adapter&& i)
|
template<typename IteratorType>
|
||||||
|
static bool accept(IteratorType first, IteratorType last,
|
||||||
|
const bool ignore_comments = false)
|
||||||
{
|
{
|
||||||
return parser(i.get()).accept(true);
|
return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
|
||||||
|
static bool accept(detail::span_input_adapter&& i,
|
||||||
|
const bool ignore_comments = false)
|
||||||
|
{
|
||||||
|
return parser(i.get(), nullptr, false, ignore_comments).accept(true);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief generate SAX events
|
@brief generate SAX events
|
||||||
|
|
||||||
The SAX event lister must follow the interface of @ref json_sax.
|
The SAX event lister must follow the interface of @ref json_sax.
|
||||||
|
|
||||||
This function reads from a compatible input. Examples are:
|
This function reads from a compatible input. Examples are:
|
||||||
- an array of 1-byte values
|
- an std::istream object
|
||||||
- strings with character/literal type with size of 1 byte
|
- a FILE pointer
|
||||||
- input streams
|
- a C-style array of characters
|
||||||
- container with contiguous storage of 1-byte values. Compatible container
|
- a pointer to a null-terminated string of single byte characters
|
||||||
types include `std::vector`, `std::string`, `std::array`,
|
- an object obj for which begin(obj) and end(obj) produces a valid pair of
|
||||||
`std::valarray`, and `std::initializer_list`. Furthermore, C-style
|
iterators.
|
||||||
arrays can be used with `std::begin()`/`std::end()`. User-defined
|
|
||||||
containers can be used as long as they implement random-access iterators
|
|
||||||
and a contiguous storage.
|
|
||||||
|
|
||||||
@pre Each element of the container has a size of 1 byte. Violating this
|
|
||||||
precondition yields undefined behavior. **This precondition is enforced
|
|
||||||
with a static assertion.**
|
|
||||||
|
|
||||||
@pre The container storage is contiguous. Violating this precondition
|
|
||||||
yields undefined behavior. **This precondition is enforced with an
|
|
||||||
assertion.**
|
|
||||||
|
|
||||||
@warning There is no way to enforce all preconditions at compile-time. If
|
|
||||||
the function is called with a noncompliant container and with
|
|
||||||
assertions switched off, the behavior is undefined and will most
|
|
||||||
likely yield segmentation violation.
|
|
||||||
|
|
||||||
@param[in] i input to read from
|
@param[in] i input to read from
|
||||||
@param[in,out] sax SAX event listener
|
@param[in,out] sax SAX event listener
|
||||||
@param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
|
@param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
|
||||||
@param[in] strict whether the input has to be consumed completely
|
@param[in] strict whether the input has to be consumed completely
|
||||||
|
@param[in] ignore_comments whether comments should be ignored and treated
|
||||||
|
like whitespace (true) or yield a parse error (true); (optional, false by
|
||||||
|
default); only applies to the JSON file format.
|
||||||
|
|
||||||
@return return value of the last processed SAX event
|
@return return value of the last processed SAX event
|
||||||
|
|
||||||
|
@ -6695,112 +6782,46 @@ class basic_json
|
||||||
|
|
||||||
@since version 3.2.0
|
@since version 3.2.0
|
||||||
*/
|
*/
|
||||||
template<typename SAX, typename InputType>
|
template <typename InputType, typename SAX>
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
JSON_HEDLEY_NON_NULL(2)
|
||||||
static bool sax_parse(InputType&& i, SAX* sax,
|
static bool sax_parse(InputType&& i, SAX* sax,
|
||||||
input_format_t format = input_format_t::json,
|
input_format_t format = input_format_t::json,
|
||||||
const bool strict = true)
|
const bool strict = true,
|
||||||
|
const bool ignore_comments = false)
|
||||||
{
|
{
|
||||||
auto ia = detail::input_adapter(std::forward<InputType>(i));
|
auto ia = detail::input_adapter(std::forward<InputType>(i));
|
||||||
return format == input_format_t::json
|
return format == input_format_t::json
|
||||||
? parser(std::move(ia)).sax_parse(sax, strict)
|
? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
|
||||||
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
|
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename SAX>
|
template<class IteratorType, class SAX>
|
||||||
|
JSON_HEDLEY_NON_NULL(3)
|
||||||
|
static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
|
||||||
|
input_format_t format = input_format_t::json,
|
||||||
|
const bool strict = true,
|
||||||
|
const bool ignore_comments = false)
|
||||||
|
{
|
||||||
|
auto ia = detail::input_adapter(std::move(first), std::move(last));
|
||||||
|
return format == input_format_t::json
|
||||||
|
? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
|
||||||
|
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename SAX>
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
JSON_HEDLEY_NON_NULL(2)
|
||||||
static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
|
static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
|
||||||
input_format_t format = input_format_t::json,
|
input_format_t format = input_format_t::json,
|
||||||
const bool strict = true)
|
const bool strict = true,
|
||||||
|
const bool ignore_comments = false)
|
||||||
{
|
{
|
||||||
auto ia = i.get();
|
auto ia = i.get();
|
||||||
return format == input_format_t::json
|
return format == input_format_t::json
|
||||||
? parser(std::move(ia)).sax_parse(sax, strict)
|
? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
|
||||||
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
|
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief deserialize from an iterator range with contiguous storage
|
|
||||||
|
|
||||||
This function reads from an iterator range of a container with contiguous
|
|
||||||
storage of 1-byte values. Compatible container types include
|
|
||||||
`std::vector`, `std::string`, `std::array`, `std::valarray`, and
|
|
||||||
`std::initializer_list`. Furthermore, C-style arrays can be used with
|
|
||||||
`std::begin()`/`std::end()`. User-defined containers can be used as long
|
|
||||||
as they implement random-access iterators and a contiguous storage.
|
|
||||||
|
|
||||||
@pre The iterator range is contiguous. Violating this precondition yields
|
|
||||||
undefined behavior. **This precondition is enforced with an assertion.**
|
|
||||||
@pre Each element in the range has a size of 1 byte. Violating this
|
|
||||||
precondition yields undefined behavior. **This precondition is enforced
|
|
||||||
with a static assertion.**
|
|
||||||
|
|
||||||
@warning There is no way to enforce all preconditions at compile-time. If
|
|
||||||
the function is called with noncompliant iterators and with
|
|
||||||
assertions switched off, the behavior is undefined and will most
|
|
||||||
likely yield segmentation violation.
|
|
||||||
|
|
||||||
@tparam IteratorType iterator of container with contiguous storage
|
|
||||||
@param[in] first begin of the range to parse (included)
|
|
||||||
@param[in] last end of the range to parse (excluded)
|
|
||||||
@param[in] cb a parser callback function of type @ref parser_callback_t
|
|
||||||
which is used to control the deserialization by filtering unwanted values
|
|
||||||
(optional)
|
|
||||||
@param[in] allow_exceptions whether to throw exceptions in case of a
|
|
||||||
parse error (optional, true by default)
|
|
||||||
|
|
||||||
@return deserialized JSON value; in case of a parse error and
|
|
||||||
@a allow_exceptions set to `false`, the return value will be
|
|
||||||
value_t::discarded.
|
|
||||||
|
|
||||||
@throw parse_error.101 in case of an unexpected token
|
|
||||||
@throw parse_error.102 if to_unicode fails or surrogate error
|
|
||||||
@throw parse_error.103 if to_unicode fails
|
|
||||||
|
|
||||||
@complexity Linear in the length of the input. The parser is a predictive
|
|
||||||
LL(1) parser. The complexity can be higher if the parser callback function
|
|
||||||
@a cb has a super-linear complexity.
|
|
||||||
|
|
||||||
@note A UTF-8 byte order mark is silently ignored.
|
|
||||||
|
|
||||||
@liveexample{The example below demonstrates the `parse()` function reading
|
|
||||||
from an iterator range.,parse__iteratortype__parser_callback_t}
|
|
||||||
|
|
||||||
@since version 2.0.3
|
|
||||||
*/
|
|
||||||
template<class IteratorType, typename std::enable_if<
|
|
||||||
std::is_base_of<
|
|
||||||
std::random_access_iterator_tag,
|
|
||||||
typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
|
|
||||||
static basic_json parse(IteratorType first, IteratorType last,
|
|
||||||
const parser_callback_t cb = nullptr,
|
|
||||||
const bool allow_exceptions = true)
|
|
||||||
{
|
|
||||||
basic_json result;
|
|
||||||
parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class IteratorType, typename std::enable_if<
|
|
||||||
std::is_base_of<
|
|
||||||
std::random_access_iterator_tag,
|
|
||||||
typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
|
|
||||||
static bool accept(IteratorType first, IteratorType last)
|
|
||||||
{
|
|
||||||
return parser(detail::input_adapter(first, last)).accept(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class IteratorType, class SAX, typename std::enable_if<
|
|
||||||
std::is_base_of<
|
|
||||||
std::random_access_iterator_tag,
|
|
||||||
typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
|
|
||||||
JSON_HEDLEY_NON_NULL(3)
|
|
||||||
static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
|
|
||||||
{
|
|
||||||
return parser(detail::input_adapter(first, last)).sax_parse(sax);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief deserialize from stream
|
@brief deserialize from stream
|
||||||
@deprecated This stream operator is deprecated and will be removed in
|
@deprecated This stream operator is deprecated and will be removed in
|
||||||
|
@ -6809,7 +6830,7 @@ class basic_json
|
||||||
instead; that is, replace calls like `j << i;` with `i >> j;`.
|
instead; that is, replace calls like `j << i;` with `i >> j;`.
|
||||||
@since version 1.0.0; deprecated since version 3.0.0
|
@since version 1.0.0; deprecated since version 3.0.0
|
||||||
*/
|
*/
|
||||||
JSON_HEDLEY_DEPRECATED(3.0.0)
|
JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
|
||||||
friend std::istream& operator<<(basic_json& j, std::istream& i)
|
friend std::istream& operator<<(basic_json& j, std::istream& i)
|
||||||
{
|
{
|
||||||
return operator>>(i, j);
|
return operator>>(i, j);
|
||||||
|
@ -7071,7 +7092,8 @@ class basic_json
|
||||||
number_unsigned | 256..65535 | uint 16 | 0xCD
|
number_unsigned | 256..65535 | uint 16 | 0xCD
|
||||||
number_unsigned | 65536..4294967295 | uint 32 | 0xCE
|
number_unsigned | 65536..4294967295 | uint 32 | 0xCE
|
||||||
number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
|
number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
|
||||||
number_float | *any value* | float 64 | 0xCB
|
number_float | *any value representable by a float* | float 32 | 0xCA
|
||||||
|
number_float | *any value NOT representable by a float* | float 64 | 0xCB
|
||||||
string | *length*: 0..31 | fixstr | 0xA0..0xBF
|
string | *length*: 0..31 | fixstr | 0xA0..0xBF
|
||||||
string | *length*: 32..255 | str 8 | 0xD9
|
string | *length*: 32..255 | str 8 | 0xD9
|
||||||
string | *length*: 256..65535 | str 16 | 0xDA
|
string | *length*: 256..65535 | str 16 | 0xDA
|
||||||
|
@ -7095,9 +7117,6 @@ class basic_json
|
||||||
- arrays with more than 4294967295 elements
|
- arrays with more than 4294967295 elements
|
||||||
- objects with more than 4294967295 elements
|
- objects with more than 4294967295 elements
|
||||||
|
|
||||||
@note The following MessagePack types are not used in the conversion:
|
|
||||||
- float 32 (0xCA)
|
|
||||||
|
|
||||||
@note Any MessagePack output created @ref to_msgpack can be successfully
|
@note Any MessagePack output created @ref to_msgpack can be successfully
|
||||||
parsed by @ref from_msgpack.
|
parsed by @ref from_msgpack.
|
||||||
|
|
||||||
|
@ -7449,27 +7468,40 @@ class basic_json
|
||||||
/*!
|
/*!
|
||||||
@copydoc from_cbor(detail::input_adapter&&, const bool, const bool)
|
@copydoc from_cbor(detail::input_adapter&&, const bool, const bool)
|
||||||
*/
|
*/
|
||||||
template<typename A1, typename A2,
|
template<typename IteratorType>
|
||||||
detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value, int> = 0>
|
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
static basic_json from_cbor(A1 && a1, A2 && a2,
|
static basic_json from_cbor(IteratorType first, IteratorType last,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
||||||
const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).get()).sax_parse(input_format_t::cbor, &sdp, strict);
|
auto ia = detail::input_adapter(std::move(first), std::move(last));
|
||||||
|
const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict);
|
||||||
return res ? result : basic_json(value_t::discarded);
|
return res ? result : basic_json(value_t::discarded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
|
||||||
|
static basic_json from_cbor(const T* ptr, std::size_t len,
|
||||||
|
const bool strict = true,
|
||||||
|
const bool allow_exceptions = true)
|
||||||
|
{
|
||||||
|
return from_cbor(ptr, ptr + len, strict, allow_exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
|
||||||
static basic_json from_cbor(detail::span_input_adapter&& i,
|
static basic_json from_cbor(detail::span_input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
||||||
const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::cbor, &sdp, strict);
|
auto ia = i.get();
|
||||||
|
const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict);
|
||||||
return res ? result : basic_json(value_t::discarded);
|
return res ? result : basic_json(value_t::discarded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7575,28 +7607,40 @@ class basic_json
|
||||||
/*!
|
/*!
|
||||||
@copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
|
@copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
|
||||||
*/
|
*/
|
||||||
template<typename A1, typename A2,
|
template<typename IteratorType>
|
||||||
detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value, int> = 0>
|
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
static basic_json from_msgpack(A1 && a1, A2 && a2,
|
static basic_json from_msgpack(IteratorType first, IteratorType last,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
||||||
const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).get()).sax_parse(input_format_t::msgpack, &sdp, strict);
|
auto ia = detail::input_adapter(std::move(first), std::move(last));
|
||||||
|
const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
|
||||||
return res ? result : basic_json(value_t::discarded);
|
return res ? result : basic_json(value_t::discarded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
|
||||||
|
static basic_json from_msgpack(const T* ptr, std::size_t len,
|
||||||
|
const bool strict = true,
|
||||||
|
const bool allow_exceptions = true)
|
||||||
|
{
|
||||||
|
return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
|
||||||
static basic_json from_msgpack(detail::span_input_adapter&& i,
|
static basic_json from_msgpack(detail::span_input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
||||||
const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::msgpack, &sdp, strict);
|
auto ia = i.get();
|
||||||
|
const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
|
||||||
return res ? result : basic_json(value_t::discarded);
|
return res ? result : basic_json(value_t::discarded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7678,27 +7722,39 @@ class basic_json
|
||||||
/*!
|
/*!
|
||||||
@copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
|
@copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
|
||||||
*/
|
*/
|
||||||
template<typename A1, typename A2,
|
template<typename IteratorType>
|
||||||
detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value, int> = 0>
|
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
static basic_json from_ubjson(A1 && a1, A2 && a2,
|
static basic_json from_ubjson(IteratorType first, IteratorType last,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
||||||
const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).get()).sax_parse(input_format_t::ubjson, &sdp, strict);
|
auto ia = detail::input_adapter(std::move(first), std::move(last));
|
||||||
|
const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
|
||||||
return res ? result : basic_json(value_t::discarded);
|
return res ? result : basic_json(value_t::discarded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
|
||||||
|
static basic_json from_ubjson(const T* ptr, std::size_t len,
|
||||||
|
const bool strict = true,
|
||||||
|
const bool allow_exceptions = true)
|
||||||
|
{
|
||||||
|
return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
|
||||||
static basic_json from_ubjson(detail::span_input_adapter&& i,
|
static basic_json from_ubjson(detail::span_input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
||||||
const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::ubjson, &sdp, strict);
|
auto ia = i.get();
|
||||||
|
const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
|
||||||
return res ? result : basic_json(value_t::discarded);
|
return res ? result : basic_json(value_t::discarded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7779,27 +7835,39 @@ class basic_json
|
||||||
/*!
|
/*!
|
||||||
@copydoc from_bson(detail::input_adapter&&, const bool, const bool)
|
@copydoc from_bson(detail::input_adapter&&, const bool, const bool)
|
||||||
*/
|
*/
|
||||||
template<typename A1, typename A2,
|
template<typename IteratorType>
|
||||||
detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value, int> = 0>
|
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
static basic_json from_bson(A1 && a1, A2 && a2,
|
static basic_json from_bson(IteratorType first, IteratorType last,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
||||||
const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).get()).sax_parse(input_format_t::bson, &sdp, strict);
|
auto ia = detail::input_adapter(std::move(first), std::move(last));
|
||||||
|
const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
|
||||||
return res ? result : basic_json(value_t::discarded);
|
return res ? result : basic_json(value_t::discarded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
|
||||||
|
static basic_json from_bson(const T* ptr, std::size_t len,
|
||||||
|
const bool strict = true,
|
||||||
|
const bool allow_exceptions = true)
|
||||||
|
{
|
||||||
|
return from_bson(ptr, ptr + len, strict, allow_exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
|
||||||
static basic_json from_bson(detail::span_input_adapter&& i,
|
static basic_json from_bson(detail::span_input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
|
||||||
const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::bson, &sdp, strict);
|
auto ia = i.get();
|
||||||
|
const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
|
||||||
return res ? result : basic_json(value_t::discarded);
|
return res ? result : basic_json(value_t::discarded);
|
||||||
}
|
}
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -8163,7 +8231,7 @@ class basic_json
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto idx = json_pointer::array_index(last_path);
|
const auto idx = json_pointer::array_index(last_path);
|
||||||
if (JSON_HEDLEY_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
|
if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
|
||||||
{
|
{
|
||||||
// avoid undefined behavior
|
// avoid undefined behavior
|
||||||
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
|
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
|
||||||
|
@ -8206,7 +8274,7 @@ class basic_json
|
||||||
else if (parent.is_array())
|
else if (parent.is_array())
|
||||||
{
|
{
|
||||||
// note erase performs range check
|
// note erase performs range check
|
||||||
parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
|
parent.erase(json_pointer::array_index(last_path));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8641,6 +8709,9 @@ struct less<::nlohmann::detail::value_t>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// C++20 prohibit function specialization in the std namespace.
|
||||||
|
#ifndef JSON_HAS_CPP_20
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief exchanges the values of two JSON objects
|
@brief exchanges the values of two JSON objects
|
||||||
|
|
||||||
|
@ -8655,6 +8726,8 @@ inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcep
|
||||||
j1.swap(j2);
|
j1.swap(j2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
project('nlohmann_json',
|
project('nlohmann_json',
|
||||||
'cpp',
|
'cpp',
|
||||||
version : '3.7.3',
|
version : '3.8.0',
|
||||||
license : 'MIT',
|
license : 'MIT',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -133,6 +133,7 @@ set(files
|
||||||
src/unit-ubjson.cpp
|
src/unit-ubjson.cpp
|
||||||
src/unit-udt.cpp
|
src/unit-udt.cpp
|
||||||
src/unit-unicode.cpp
|
src/unit-unicode.cpp
|
||||||
|
src/unit-user_defined_input.cpp
|
||||||
src/unit-wstring.cpp)
|
src/unit-wstring.cpp)
|
||||||
|
|
||||||
foreach(file ${files})
|
foreach(file ${files})
|
||||||
|
|
|
@ -44,6 +44,7 @@ SOURCES = src/unit.cpp \
|
||||||
src/unit-testsuites.cpp \
|
src/unit-testsuites.cpp \
|
||||||
src/unit-ubjson.cpp \
|
src/unit-ubjson.cpp \
|
||||||
src/unit-unicode.cpp \
|
src/unit-unicode.cpp \
|
||||||
|
src/unit-user_defined_input.cpp \
|
||||||
src/unit-wstring.cpp
|
src/unit-wstring.cpp
|
||||||
|
|
||||||
OBJECTS = $(SOURCES:.cpp=.o)
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
|
@ -11,8 +11,10 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.11.0")
|
||||||
)
|
)
|
||||||
set_tests_properties(cmake_fetch_content_configure PROPERTIES
|
set_tests_properties(cmake_fetch_content_configure PROPERTIES
|
||||||
FIXTURES_SETUP cmake_fetch_content
|
FIXTURES_SETUP cmake_fetch_content
|
||||||
|
LABELS git_required
|
||||||
)
|
)
|
||||||
set_tests_properties(cmake_fetch_content_build PROPERTIES
|
set_tests_properties(cmake_fetch_content_build PROPERTIES
|
||||||
FIXTURES_REQUIRED cmake_fetch_content
|
FIXTURES_REQUIRED cmake_fetch_content
|
||||||
|
LABELS git_required
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -4,9 +4,8 @@ project(DummyImport CXX)
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
FetchContent_Declare(json
|
get_filename_component(GIT_REPOSITORY_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../.. ABSOLUTE)
|
||||||
GIT_REPOSITORY ${CMAKE_CURRENT_SOURCE_DIR}/../../..
|
FetchContent_Declare(json GIT_REPOSITORY ${GIT_REPOSITORY_DIRECTORY} GIT_TAG HEAD)
|
||||||
GIT_TAG HEAD)
|
|
||||||
|
|
||||||
FetchContent_GetProperties(json)
|
FetchContent_GetProperties(json)
|
||||||
if(NOT json_POPULATED)
|
if(NOT json_POPULATED)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
This file implements a driver for American Fuzzy Lop (afl-fuzz). It relies on
|
This file implements a driver for American Fuzzy Lop (afl-fuzz). It relies on
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||||
|
@ -11,6 +11,12 @@ array data, it performs the following steps:
|
||||||
- vec = to_ubjson(j1)
|
- vec = to_ubjson(j1)
|
||||||
- j2 = from_ubjson(vec)
|
- j2 = from_ubjson(vec)
|
||||||
- assert(j1 == j2)
|
- assert(j1 == j2)
|
||||||
|
- vec2 = to_ubjson(j1, use_size = true, use_type = false)
|
||||||
|
- j3 = from_ubjson(vec2)
|
||||||
|
- assert(j1 == j3)
|
||||||
|
- vec3 = to_ubjson(j1, use_size = true, use_type = true)
|
||||||
|
- j4 = from_ubjson(vec3)
|
||||||
|
- assert(j1 == j4)
|
||||||
|
|
||||||
The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
|
The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
|
||||||
drivers.
|
drivers.
|
||||||
|
@ -35,14 +41,24 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// step 2: round trip
|
// step 2.1: round trip without adding size annotations to container types
|
||||||
std::vector<uint8_t> vec2 = json::to_ubjson(j1);
|
std::vector<uint8_t> vec2 = json::to_ubjson(j1, false, false);
|
||||||
|
|
||||||
|
// step 2.2: round trip with adding size annotations but without adding type annonations to container types
|
||||||
|
std::vector<uint8_t> vec3 = json::to_ubjson(j1, true, false);
|
||||||
|
|
||||||
|
// step 2.3: round trip with adding size as well as type annotations to container types
|
||||||
|
std::vector<uint8_t> vec4 = json::to_ubjson(j1, true, true);
|
||||||
|
|
||||||
// parse serialization
|
// parse serialization
|
||||||
json j2 = json::from_ubjson(vec2);
|
json j2 = json::from_ubjson(vec2);
|
||||||
|
json j3 = json::from_ubjson(vec3);
|
||||||
|
json j4 = json::from_ubjson(vec4);
|
||||||
|
|
||||||
// serializations must match
|
// serializations must match
|
||||||
assert(json::to_ubjson(j2) == vec2);
|
assert(json::to_ubjson(j2, false, false) == vec2);
|
||||||
|
assert(json::to_ubjson(j3, true, false) == vec3);
|
||||||
|
assert(json::to_ubjson(j4, true, true) == vec4);
|
||||||
}
|
}
|
||||||
catch (const json::parse_error&)
|
catch (const json::parse_error&)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
@ -225,9 +225,9 @@ TEST_CASE("alternative string type")
|
||||||
|
|
||||||
{
|
{
|
||||||
alt_json doc;
|
alt_json doc;
|
||||||
doc["list"] = { 1, 0, 2 };
|
doc["object"] = { {"currency", "USD"}, {"value", 42.99} };
|
||||||
alt_string dump = doc.dump();
|
alt_string dump = doc.dump();
|
||||||
CHECK(dump == R"({"list":[1,0,2]})");
|
CHECK(dump == R"({"object":{"currency":"USD","value":42.99}})");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
@ -37,14 +37,23 @@ using nlohmann::json;
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// shortcut to scan a string literal
|
// shortcut to scan a string literal
|
||||||
json::lexer::token_type scan_string(const char* s);
|
json::lexer::token_type scan_string(const char* s, const bool ignore_comments = false);
|
||||||
json::lexer::token_type scan_string(const char* s)
|
json::lexer::token_type scan_string(const char* s, const bool ignore_comments)
|
||||||
{
|
{
|
||||||
auto ia = nlohmann::detail::input_adapter(s);
|
auto ia = nlohmann::detail::input_adapter(s);
|
||||||
return nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia)).scan();
|
return nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments).scan();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string get_error_message(const char* s, const bool ignore_comments = false);
|
||||||
|
std::string get_error_message(const char* s, const bool ignore_comments)
|
||||||
|
{
|
||||||
|
auto ia = nlohmann::detail::input_adapter(s);
|
||||||
|
auto lexer = nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments);
|
||||||
|
lexer.scan();
|
||||||
|
return lexer.get_error_message();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("lexer class")
|
TEST_CASE("lexer class")
|
||||||
{
|
{
|
||||||
SECTION("scan")
|
SECTION("scan")
|
||||||
|
@ -127,6 +136,8 @@ TEST_CASE("lexer class")
|
||||||
// store scan() result
|
// store scan() result
|
||||||
const auto res = scan_string(s.c_str());
|
const auto res = scan_string(s.c_str());
|
||||||
|
|
||||||
|
CAPTURE(s);
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
// single characters that are valid tokens
|
// single characters that are valid tokens
|
||||||
|
@ -179,4 +190,56 @@ TEST_CASE("lexer class")
|
||||||
s += "\"";
|
s += "\"";
|
||||||
CHECK((scan_string(s.c_str()) == json::lexer::token_type::value_string));
|
CHECK((scan_string(s.c_str()) == json::lexer::token_type::value_string));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("fail on comments")
|
||||||
|
{
|
||||||
|
CHECK((scan_string("/", false) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/", false) == "invalid literal");
|
||||||
|
|
||||||
|
CHECK((scan_string("/!", false) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/!", false) == "invalid literal");
|
||||||
|
CHECK((scan_string("/*", false) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/*", false) == "invalid literal");
|
||||||
|
CHECK((scan_string("/**", false) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/**", false) == "invalid literal");
|
||||||
|
|
||||||
|
CHECK((scan_string("//", false) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("//", false) == "invalid literal");
|
||||||
|
CHECK((scan_string("/**/", false) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/**/", false) == "invalid literal");
|
||||||
|
CHECK((scan_string("/** /", false) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/** /", false) == "invalid literal");
|
||||||
|
|
||||||
|
CHECK((scan_string("/***/", false) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/***/", false) == "invalid literal");
|
||||||
|
CHECK((scan_string("/* true */", false) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/* true */", false) == "invalid literal");
|
||||||
|
CHECK((scan_string("/*/**/", false) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/*/**/", false) == "invalid literal");
|
||||||
|
CHECK((scan_string("/*/* */", false) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/*/* */", false) == "invalid literal");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("ignore comments")
|
||||||
|
{
|
||||||
|
CHECK((scan_string("/", true) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/", true) == "invalid comment; expecting '/' or '*' after '/'");
|
||||||
|
|
||||||
|
CHECK((scan_string("/!", true) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/!", true) == "invalid comment; expecting '/' or '*' after '/'");
|
||||||
|
CHECK((scan_string("/*", true) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/*", true) == "invalid comment; missing closing '*/'");
|
||||||
|
CHECK((scan_string("/**", true) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/**", true) == "invalid comment; missing closing '*/'");
|
||||||
|
|
||||||
|
CHECK((scan_string("//", true) == json::lexer::token_type::end_of_input));
|
||||||
|
CHECK((scan_string("/**/", true) == json::lexer::token_type::end_of_input));
|
||||||
|
CHECK((scan_string("/** /", true) == json::lexer::token_type::parse_error));
|
||||||
|
CHECK(get_error_message("/** /", true) == "invalid comment; missing closing '*/'");
|
||||||
|
|
||||||
|
CHECK((scan_string("/***/", true) == json::lexer::token_type::end_of_input));
|
||||||
|
CHECK((scan_string("/* true */", true) == json::lexer::token_type::end_of_input));
|
||||||
|
CHECK((scan_string("/*/**/", true) == json::lexer::token_type::end_of_input));
|
||||||
|
CHECK((scan_string("/*/* */", true) == json::lexer::token_type::end_of_input));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
@ -224,6 +224,7 @@ class SaxCountdown : public nlohmann::json::json_sax_t
|
||||||
|
|
||||||
json parser_helper(const std::string& s);
|
json parser_helper(const std::string& s);
|
||||||
bool accept_helper(const std::string& s);
|
bool accept_helper(const std::string& s);
|
||||||
|
void comments_helper(const std::string& s);
|
||||||
|
|
||||||
json parser_helper(const std::string& s)
|
json parser_helper(const std::string& s)
|
||||||
{
|
{
|
||||||
|
@ -241,6 +242,8 @@ json parser_helper(const std::string& s)
|
||||||
json::sax_parse(s, &sdp);
|
json::sax_parse(s, &sdp);
|
||||||
CHECK(j_sax == j);
|
CHECK(j_sax == j);
|
||||||
|
|
||||||
|
comments_helper(s);
|
||||||
|
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,11 +278,51 @@ bool accept_helper(const std::string& s)
|
||||||
// 6. check if this approach came to the same result
|
// 6. check if this approach came to the same result
|
||||||
CHECK(ok_noexcept == ok_noexcept_cb);
|
CHECK(ok_noexcept == ok_noexcept_cb);
|
||||||
|
|
||||||
// 7. return result
|
// 7. check if comments are properly ignored
|
||||||
|
if (ok_accept)
|
||||||
|
{
|
||||||
|
comments_helper(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. return result
|
||||||
return ok_accept;
|
return ok_accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void comments_helper(const std::string& s)
|
||||||
|
{
|
||||||
|
json _;
|
||||||
|
|
||||||
|
// parse/accept with default parser
|
||||||
|
CHECK_NOTHROW(_ = json::parse(s));
|
||||||
|
CHECK(json::accept(s));
|
||||||
|
|
||||||
|
// parse/accept while skipping comments
|
||||||
|
CHECK_NOTHROW(_ = json::parse(s, nullptr, false, true));
|
||||||
|
CHECK(json::accept(s, true));
|
||||||
|
|
||||||
|
std::vector<std::string> json_with_comments;
|
||||||
|
|
||||||
|
// start with a comment
|
||||||
|
json_with_comments.push_back(std::string("// this is a comment\n") + s);
|
||||||
|
json_with_comments.push_back(std::string("/* this is a comment */") + s);
|
||||||
|
// end with a comment
|
||||||
|
json_with_comments.push_back(s + "// this is a comment");
|
||||||
|
json_with_comments.push_back(s + "/* this is a comment */");
|
||||||
|
|
||||||
|
// check all strings
|
||||||
|
for (const auto& json_with_comment : json_with_comments)
|
||||||
|
{
|
||||||
|
CAPTURE(json_with_comment)
|
||||||
|
CHECK_THROWS_AS(_ = json::parse(json_with_comment), json::parse_error);
|
||||||
|
CHECK(not json::accept(json_with_comment));
|
||||||
|
|
||||||
|
CHECK_NOTHROW(_ = json::parse(json_with_comment, nullptr, true, true));
|
||||||
|
CHECK(json::accept(json_with_comment, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
TEST_CASE("parser class")
|
TEST_CASE("parser class")
|
||||||
{
|
{
|
||||||
SECTION("parse")
|
SECTION("parse")
|
||||||
|
@ -1587,7 +1630,7 @@ TEST_CASE("parser class")
|
||||||
CHECK (j_filtered1.size() == 2);
|
CHECK (j_filtered1.size() == 2);
|
||||||
CHECK (j_filtered1 == json({1, {{"qux", "baz"}}}));
|
CHECK (j_filtered1 == json({1, {{"qux", "baz"}}}));
|
||||||
|
|
||||||
json j_filtered2 = json::parse(structured_array, [](int, json::parse_event_t e, const json & parsed)
|
json j_filtered2 = json::parse(structured_array, [](int, json::parse_event_t e, const json& /*parsed*/)
|
||||||
{
|
{
|
||||||
if (e == json::parse_event_t::object_end)
|
if (e == json::parse_event_t::object_end)
|
||||||
{
|
{
|
||||||
|
@ -1834,4 +1877,10 @@ TEST_CASE("parser class")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("error messages for comments")
|
||||||
|
{
|
||||||
|
CHECK_THROWS_WITH_AS(json::parse("/a", nullptr, true, true), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid comment; expecting '/' or '*' after '/'; last read: '/a'", json::parse_error);
|
||||||
|
CHECK_THROWS_WITH_AS(json::parse("/*", nullptr, true, true), "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid comment; missing closing '*/'; last read: '/*<U+0000>'", json::parse_error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
@ -154,7 +154,7 @@ TEST_CASE("concepts")
|
||||||
json j {1, 2, 3};
|
json j {1, 2, 3};
|
||||||
json::iterator it1 = j.begin();
|
json::iterator it1 = j.begin();
|
||||||
json::iterator it2 = j.end();
|
json::iterator it2 = j.end();
|
||||||
std::swap(it1, it2);
|
swap(it1, it2);
|
||||||
CHECK(it1 == j.end());
|
CHECK(it1 == j.end());
|
||||||
CHECK(it2 == j.begin());
|
CHECK(it2 == j.begin());
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ TEST_CASE("concepts")
|
||||||
json j {1, 2, 3};
|
json j {1, 2, 3};
|
||||||
json::const_iterator it1 = j.cbegin();
|
json::const_iterator it1 = j.cbegin();
|
||||||
json::const_iterator it2 = j.cend();
|
json::const_iterator it2 = j.cend();
|
||||||
std::swap(it1, it2);
|
swap(it1, it2);
|
||||||
CHECK(it1 == j.end());
|
CHECK(it1 == j.end());
|
||||||
CHECK(it2 == j.begin());
|
CHECK(it2 == j.begin());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.7.3
|
| | |__ | | | | | | version 3.8.0
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue