mirror of
https://github.com/nlohmann/json.git
synced 2026-10-02 12:40:32 +00:00
Correct documentation errors found while hunting for bugs
- patch/patch_inplace: list the JSON pointer errors parse_error.106-109 and out_of_range.402/404, and quote the actual parse_error.105 message. - unflatten: list parse_error.106/107/108 and out_of_range.404. - to_bson: list out_of_range.415 (binary subtype above 255) and note that 412 and 415 are new in 3.13.0. - to_string: state that string_t must be convertible to std::string, also in the StringType requirements table. - JSON Lines: a `while (input >> j)` loop also throws after the last value for concatenated JSON values; show a loop that works for both. - BON8: a string gets 0xFF only if nothing follows it in the message; a string at the end of an array or object is ended by 0xFE. - custom_string_type.hpp: add operator+=(char), which the "Always required" list asks for (json_pointer::to_string, flatten, unflatten, and diff did not compile), and an ADL int_to_string for diff and items. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
@@ -26,10 +26,24 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
||||
- Throws [`parse_error.104`](../../home/exceptions.md#jsonexceptionparse_error104) if the JSON patch does not consist of
|
||||
an array of objects.
|
||||
- Throws [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105) if the JSON patch is malformed (e.g.,
|
||||
mandatory attributes are missing); example: `"operation add must have member path"`.
|
||||
mandatory attributes are missing); example: `"operation 'add' must have member 'path'"`.
|
||||
- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index is out of range.
|
||||
- Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in a "path" or
|
||||
"from" member begins with '0'; example: `"array index '01' must not begin with '0'"`.
|
||||
- Throws [`parse_error.107`](../../home/exceptions.md#jsonexceptionparse_error107) if a "path" or "from" member is not
|
||||
empty and does not begin with a slash (`/`); example: `"JSON pointer must be empty or begin with '/' - was: 'a'"`.
|
||||
- Throws [`parse_error.108`](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in a "path" or
|
||||
"from" member is not followed by `0` or `1`; example: `"escape character '~' must be followed with '0' or '1'"`.
|
||||
- Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in a "path" or
|
||||
"from" member is not a number; example: `"array index 'foo' is not a number"`.
|
||||
- Throws [`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402) if the array index `-` is used
|
||||
where an existing element is required (the "path" of "replace", the "from" of "move" and "copy"); example:
|
||||
`"array index '-' (3) is out of range"`.
|
||||
- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch
|
||||
could not be resolved successfully in the current JSON value; example: `"key baz not found"`.
|
||||
- Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if a reference token of a JSON
|
||||
pointer inside the patch cannot be resolved, e.g., `-` in a "remove" operation or `1a` for an array; example:
|
||||
`"unresolved reference token '-'"`.
|
||||
- Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent
|
||||
("add", "remove", "move")
|
||||
- Throws [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) if an "add" operation's target
|
||||
|
||||
@@ -22,10 +22,24 @@ No guarantees, value may be corrupted by an unsuccessful patch operation.
|
||||
- Throws [`parse_error.104`](../../home/exceptions.md#jsonexceptionparse_error104) if the JSON patch does not consist of
|
||||
an array of objects.
|
||||
- Throws [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105) if the JSON patch is malformed (e.g.,
|
||||
mandatory attributes are missing); example: `"operation add must have member path"`.
|
||||
mandatory attributes are missing); example: `"operation 'add' must have member 'path'"`.
|
||||
- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index is out of range.
|
||||
- Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in a "path" or
|
||||
"from" member begins with '0'; example: `"array index '01' must not begin with '0'"`.
|
||||
- Throws [`parse_error.107`](../../home/exceptions.md#jsonexceptionparse_error107) if a "path" or "from" member is not
|
||||
empty and does not begin with a slash (`/`); example: `"JSON pointer must be empty or begin with '/' - was: 'a'"`.
|
||||
- Throws [`parse_error.108`](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in a "path" or
|
||||
"from" member is not followed by `0` or `1`; example: `"escape character '~' must be followed with '0' or '1'"`.
|
||||
- Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in a "path" or
|
||||
"from" member is not a number; example: `"array index 'foo' is not a number"`.
|
||||
- Throws [`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402) if the array index `-` is used
|
||||
where an existing element is required (the "path" of "replace", the "from" of "move" and "copy"); example:
|
||||
`"array index '-' (3) is out of range"`.
|
||||
- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch
|
||||
could not be resolved successfully in the current JSON value; example: `"key baz not found"`.
|
||||
- Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if a reference token of a JSON
|
||||
pointer inside the patch cannot be resolved, e.g., `-` in a "remove" operation or `1a` for an array; example:
|
||||
`"unresolved reference token '-'"`.
|
||||
- Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent
|
||||
("add", "remove", "move")
|
||||
- Throws [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) if an "add" operation's target
|
||||
|
||||
@@ -43,6 +43,9 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
||||
- Throws [`out_of_range.412`](../../home/exceptions.md#jsonexceptionout_of_range412) if the length of a document, array,
|
||||
string, or binary value exceeds the range of the 32-bit BSON length field; example:
|
||||
`"BSON length 2147483661 exceeds maximum of 2147483647"`
|
||||
- Throws [`out_of_range.415`](../../home/exceptions.md#jsonexceptionout_of_range415) if the subtype of a binary value
|
||||
exceeds 255, the maximum of the BSON binary subtype; example:
|
||||
`"subtype 300 is too large for the BSON binary subtype (max 255)"`
|
||||
|
||||
## Complexity
|
||||
|
||||
@@ -92,4 +95,5 @@ pass before anything is written.
|
||||
## Version history
|
||||
|
||||
- Added in version 3.4.0.
|
||||
- Throws `out_of_range.412` and `out_of_range.415` since version 3.13.0.
|
||||
- Linear in the size of `j`, and no longer limited by the call stack for deeply nested values, since version 3.13.0.
|
||||
|
||||
@@ -10,7 +10,8 @@ This function implements a user-defined to_string for JSON objects.
|
||||
## Template parameters
|
||||
|
||||
`BasicJsonType`
|
||||
: a specialization of [`basic_json`](index.md)
|
||||
: a specialization of [`basic_json`](index.md) whose [`string_t`](string_t.md) is convertible to `#!cpp std::string`;
|
||||
for other string types, use [`dump`](dump.md), which returns a `string_t`
|
||||
|
||||
## Return value
|
||||
|
||||
|
||||
@@ -27,8 +27,17 @@ The function can throw the following exceptions:
|
||||
- Throws [`type_error.315`](../../home/exceptions.md#jsonexceptiontype_error315) if object values are not primitive
|
||||
- Throws [`type_error.313`](../../home/exceptions.md#jsonexceptiontype_error313) if a key (JSON pointer) leads to a
|
||||
conflicting nesting; example: `"invalid value to unflatten"`
|
||||
- Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in a key begins
|
||||
with '0'; example: `"array index '01' must not begin with '0'"`
|
||||
- Throws [`parse_error.107`](../../home/exceptions.md#jsonexceptionparse_error107) if a key is not empty and does not
|
||||
begin with a slash (`/`); example: `"JSON pointer must be empty or begin with '/' - was: 'a'"`
|
||||
- Throws [`parse_error.108`](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in a key is not
|
||||
followed by `0` or `1`; example: `"escape character '~' must be followed with '0' or '1'"`
|
||||
- Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in a key is not a
|
||||
number; example: `"array index 'one' is not a number"`
|
||||
- Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if a level becomes an array
|
||||
(because one of its keys is `0`) and another key at that level cannot be an array index; example:
|
||||
`"unresolved reference token 'x'"`
|
||||
|
||||
## Complexity
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
@@ -8,10 +9,10 @@
|
||||
// and nothing more of std::string's interface.
|
||||
//
|
||||
// Covers the "Always required" members, the extras needed for the binary
|
||||
// formats, and the extras needed for JSON Pointer / flatten / unflatten /
|
||||
// diff. Extending it further (e.g. for std::hash<basic_json> or to_bson) is
|
||||
// a matter of adding the extra members listed in the "Required for other
|
||||
// functionality" table.
|
||||
// formats, JSON Pointer / flatten / unflatten, and the int_to_string overload
|
||||
// needed for diff and items. Extending it further (e.g. for
|
||||
// std::hash<basic_json> or to_bson) is a matter of adding the extra members
|
||||
// listed in the "Required for other functionality" table.
|
||||
//
|
||||
// See https://json.nlohmann.me/features/types/template_parameters/#stringtype
|
||||
class custom_string_type
|
||||
@@ -93,6 +94,11 @@ class custom_string_type
|
||||
data_.append(other.data_);
|
||||
return *this;
|
||||
}
|
||||
custom_string_type& operator+=(char c)
|
||||
{
|
||||
data_.push_back(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_type find_first_of(char c, size_type pos = 0) const
|
||||
{
|
||||
@@ -116,6 +122,12 @@ class custom_string_type
|
||||
return data_.end();
|
||||
}
|
||||
|
||||
// found by ADL; converts array indices to keys in diff and items
|
||||
friend void int_to_string(custom_string_type& target, std::size_t value)
|
||||
{
|
||||
target.data_ = std::to_string(value);
|
||||
}
|
||||
|
||||
friend bool operator==(const custom_string_type& lhs, const custom_string_type& rhs)
|
||||
{
|
||||
return lhs.data_ == rhs.data_;
|
||||
|
||||
@@ -53,8 +53,9 @@ The library uses the following mapping from JSON values types to BON8 types acco
|
||||
|
||||
An integer that takes 2 to 4 bytes starts with a UTF-8 lead byte (0xC2..0xF7) that is followed by a byte that cannot
|
||||
continue a UTF-8 character: 0x00..0x7F for positive and 0xC0..0xFF for negative integers. A string is terminated by
|
||||
0xFF only if it is empty, if another string follows it, or if it is the last value of the message; otherwise, the first
|
||||
byte of the next value ends it.
|
||||
0xFF only if it is empty, if another string follows it, or if nothing follows it in the message; otherwise, the byte
|
||||
after it ends it: the first byte of the next value, or the 0xFE that ends an array or object. For example, `["e"]` is
|
||||
serialized as 0x81 0x65 0xFF, but `[1,2,3,4,"e"]` as 0x85 0x91 0x92 0x93 0x94 0x65 0xFE.
|
||||
|
||||
!!! success "Complete mapping"
|
||||
|
||||
@@ -140,7 +141,7 @@ Non-negative integers are read as number_unsigned, negative integers as number_i
|
||||
arrays and objects with up to four elements that are terminated by 0xFE, unsorted object keys, or a 0xFF after a
|
||||
string that would also end without it, are accepted. A second 0xFF is not a terminator but an empty string.
|
||||
|
||||
Strings must be valid UTF-8, and the last string of a message must be terminated by 0xFF.
|
||||
Strings must be valid UTF-8, and a string at the very end of a message must be terminated by 0xFF.
|
||||
|
||||
!!! info
|
||||
|
||||
|
||||
@@ -46,8 +46,20 @@ JSON Lines input with more than one value is treated as invalid JSON by the [`pa
|
||||
}
|
||||
```
|
||||
|
||||
with a JSON Lines input does not work, because the parser will try to parse one value after the last one.
|
||||
with a JSON Lines input does not work, because the parser will try to parse one value after the last one and throw
|
||||
a [`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) exception. The same happens for a
|
||||
stream of *concatenated* (non-newline-delimited) JSON values: `operator>>` reads them one at a time, but the loop
|
||||
above throws after the last value. To read either format with `operator>>`, check for the end of the stream before
|
||||
each read:
|
||||
|
||||
This is different from parsing a stream of *concatenated* (non-newline-delimited) JSON values, for which
|
||||
`operator>>` does work, provided that a value that is a number is followed by whitespace -- see its
|
||||
[notes](../../api/operator_gtgt.md#notes) for details.
|
||||
```cpp
|
||||
json j;
|
||||
while (input >> std::ws && input.peek() != std::char_traits<char>::eof())
|
||||
{
|
||||
input >> j;
|
||||
std::cout << j << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
A value that is a number must be followed by whitespace -- see the [notes](../../api/operator_gtgt.md#notes) of
|
||||
`operator>>` for details.
|
||||
|
||||
@@ -394,6 +394,7 @@ using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
|
||||
| [`to_bson`](../../api/basic_json/to_bson.md) | `find(value_type)` and `npos` |
|
||||
| [`parse`](../../api/basic_json/parse.md) from a `string_t` | the input adapters must accept it; otherwise pass a character range |
|
||||
| `#!cpp operator<<(std::ostream&, const json_pointer&)` | streamability to `#!cpp std::ostream` |
|
||||
| [`to_string`](../../api/basic_json/to_string.md) | conversion of `StringType` to `#!cpp std::string` (the function returns a `#!cpp std::string`) |
|
||||
| exception messages | `data()` and `size()`, or `begin()` and `end()` |
|
||||
|
||||
### Compatible types
|
||||
|
||||
Reference in New Issue
Block a user