🚧 a lot of minor changes
- Removed unused headers. - Added override where needed. - Added description for parse_error.113 exception. - Fixed some conversion warnings. - Integrated cbor_expect_string function for CBOR maps. - Added documentation on the supported CBOR/MessagePack features. - Added test to check all initial bytes for CBOR input.
This commit is contained in:
parent
483a58f625
commit
c5711f3072
10 changed files with 385 additions and 90 deletions
137
src/json.hpp
137
src/json.hpp
|
@ -32,7 +32,6 @@ SOFTWARE.
|
||||||
#include <algorithm> // all_of, copy, fill, find, for_each, none_of, remove, reverse, transform
|
#include <algorithm> // all_of, copy, fill, find, for_each, none_of, remove, reverse, transform
|
||||||
#include <array> // array
|
#include <array> // array
|
||||||
#include <cassert> // assert
|
#include <cassert> // assert
|
||||||
#include <cctype> // isdigit
|
|
||||||
#include <ciso646> // and, not, or
|
#include <ciso646> // and, not, or
|
||||||
#include <clocale> // lconv, localeconv
|
#include <clocale> // lconv, localeconv
|
||||||
#include <cmath> // isfinite, labs, ldexp, signbit
|
#include <cmath> // isfinite, labs, ldexp, signbit
|
||||||
|
@ -43,7 +42,6 @@ SOFTWARE.
|
||||||
#include <forward_list> // forward_list
|
#include <forward_list> // forward_list
|
||||||
#include <functional> // function, hash, less
|
#include <functional> // function, hash, less
|
||||||
#include <initializer_list> // initializer_list
|
#include <initializer_list> // initializer_list
|
||||||
#include <iomanip> // setw
|
|
||||||
#include <iostream> // istream, ostream
|
#include <iostream> // istream, ostream
|
||||||
#include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
|
#include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
|
||||||
#include <limits> // numeric_limits
|
#include <limits> // numeric_limits
|
||||||
|
@ -130,7 +128,7 @@ class exception : public std::exception
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// returns the explanatory string
|
/// returns the explanatory string
|
||||||
virtual const char* what() const noexcept
|
virtual const char* what() const noexcept override
|
||||||
{
|
{
|
||||||
return what_arg.c_str();
|
return what_arg.c_str();
|
||||||
}
|
}
|
||||||
|
@ -174,7 +172,7 @@ json.exception.parse_error.109 | parse error: array index 'one' is not a number
|
||||||
json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
|
json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
|
||||||
json.exception.parse_error.111 | parse error: bad input stream | Parsing CBOR or MessagePack from an input stream where the [`badbit` or `failbit`](http://en.cppreference.com/w/cpp/io/ios_base/iostate) is set.
|
json.exception.parse_error.111 | parse error: bad input stream | Parsing CBOR or MessagePack from an input stream where the [`badbit` or `failbit`](http://en.cppreference.com/w/cpp/io/ios_base/iostate) is set.
|
||||||
json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xf8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
|
json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xf8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
|
||||||
json.exception.parse_error.113 | | While parsing a map key, a value that is not a string has been read.
|
json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.
|
||||||
|
|
||||||
@since version 3.0.0
|
@since version 3.0.0
|
||||||
*/
|
*/
|
||||||
|
@ -6468,7 +6466,7 @@ class basic_json
|
||||||
auto i = val.m_value.object->cbegin();
|
auto i = val.m_value.object->cbegin();
|
||||||
for (size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
|
for (size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
|
||||||
{
|
{
|
||||||
o.write(indent_string.c_str(), new_indent);
|
o.write(indent_string.c_str(), static_cast<std::streamsize>(new_indent));
|
||||||
o.put('\"');
|
o.put('\"');
|
||||||
dump_escaped(i->first);
|
dump_escaped(i->first);
|
||||||
o.write("\": ", 3);
|
o.write("\": ", 3);
|
||||||
|
@ -6478,14 +6476,14 @@ class basic_json
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(i != val.m_value.object->cend());
|
assert(i != val.m_value.object->cend());
|
||||||
o.write(indent_string.c_str(), new_indent);
|
o.write(indent_string.c_str(), static_cast<std::streamsize>(new_indent));
|
||||||
o.put('\"');
|
o.put('\"');
|
||||||
dump_escaped(i->first);
|
dump_escaped(i->first);
|
||||||
o.write("\": ", 3);
|
o.write("\": ", 3);
|
||||||
dump(i->second, true, indent_step, new_indent);
|
dump(i->second, true, indent_step, new_indent);
|
||||||
|
|
||||||
o.put('\n');
|
o.put('\n');
|
||||||
o.write(indent_string.c_str(), current_indent);
|
o.write(indent_string.c_str(), static_cast<std::streamsize>(current_indent));
|
||||||
o.put('}');
|
o.put('}');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -6538,18 +6536,18 @@ class basic_json
|
||||||
// first n-1 elements
|
// first n-1 elements
|
||||||
for (auto i = val.m_value.array->cbegin(); i != val.m_value.array->cend() - 1; ++i)
|
for (auto i = val.m_value.array->cbegin(); i != val.m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
o.write(indent_string.c_str(), new_indent);
|
o.write(indent_string.c_str(), static_cast<std::streamsize>(new_indent));
|
||||||
dump(*i, true, indent_step, new_indent);
|
dump(*i, true, indent_step, new_indent);
|
||||||
o.write(",\n", 2);
|
o.write(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(not val.m_value.array->empty());
|
assert(not val.m_value.array->empty());
|
||||||
o.write(indent_string.c_str(), new_indent);
|
o.write(indent_string.c_str(), static_cast<std::streamsize>(new_indent));
|
||||||
dump(val.m_value.array->back(), true, indent_step, new_indent);
|
dump(val.m_value.array->back(), true, indent_step, new_indent);
|
||||||
|
|
||||||
o.put('\n');
|
o.put('\n');
|
||||||
o.write(indent_string.c_str(), current_indent);
|
o.write(indent_string.c_str(), static_cast<std::streamsize>(current_indent));
|
||||||
o.put(']');
|
o.put(']');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -7848,7 +7846,7 @@ class basic_json
|
||||||
const auto N = j.m_value.string->size();
|
const auto N = j.m_value.string->size();
|
||||||
if (N <= 0x17)
|
if (N <= 0x17)
|
||||||
{
|
{
|
||||||
v.push_back(0x60 + static_cast<uint8_t>(N)); // 1 byte for string + size
|
v.push_back(static_cast<uint8_t>(0x60 + N)); // 1 byte for string + size
|
||||||
}
|
}
|
||||||
else if (N <= 0xff)
|
else if (N <= 0xff)
|
||||||
{
|
{
|
||||||
|
@ -7884,7 +7882,7 @@ class basic_json
|
||||||
const auto N = j.m_value.array->size();
|
const auto N = j.m_value.array->size();
|
||||||
if (N <= 0x17)
|
if (N <= 0x17)
|
||||||
{
|
{
|
||||||
v.push_back(0x80 + static_cast<uint8_t>(N)); // 1 byte for array + size
|
v.push_back(static_cast<uint8_t>(0x80 + N)); // 1 byte for array + size
|
||||||
}
|
}
|
||||||
else if (N <= 0xff)
|
else if (N <= 0xff)
|
||||||
{
|
{
|
||||||
|
@ -7922,7 +7920,7 @@ class basic_json
|
||||||
const auto N = j.m_value.object->size();
|
const auto N = j.m_value.object->size();
|
||||||
if (N <= 0x17)
|
if (N <= 0x17)
|
||||||
{
|
{
|
||||||
v.push_back(0xa0 + static_cast<uint8_t>(N)); // 1 byte for object + size
|
v.push_back(static_cast<uint8_t>(0xa0 + N)); // 1 byte for object + size
|
||||||
}
|
}
|
||||||
else if (N <= 0xff)
|
else if (N <= 0xff)
|
||||||
{
|
{
|
||||||
|
@ -8653,6 +8651,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(v[current_idx] - 0xa0);
|
const auto len = static_cast<size_t>(v[current_idx] - 0xa0);
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
|
cbor_expect_string(v, idx);
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
}
|
}
|
||||||
|
@ -8666,6 +8665,7 @@ class basic_json
|
||||||
idx += 1; // skip 1 size byte
|
idx += 1; // skip 1 size byte
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
|
cbor_expect_string(v, idx);
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
}
|
}
|
||||||
|
@ -8679,6 +8679,7 @@ class basic_json
|
||||||
idx += 2; // skip 2 size bytes
|
idx += 2; // skip 2 size bytes
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
|
cbor_expect_string(v, idx);
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
}
|
}
|
||||||
|
@ -8692,6 +8693,7 @@ class basic_json
|
||||||
idx += 4; // skip 4 size bytes
|
idx += 4; // skip 4 size bytes
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
|
cbor_expect_string(v, idx);
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
}
|
}
|
||||||
|
@ -8705,6 +8707,7 @@ class basic_json
|
||||||
idx += 8; // skip 8 size bytes
|
idx += 8; // skip 8 size bytes
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
|
cbor_expect_string(v, idx);
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
}
|
}
|
||||||
|
@ -8716,6 +8719,7 @@ class basic_json
|
||||||
basic_json result = value_t::object;
|
basic_json result = value_t::object;
|
||||||
while (check_length(v.size(), 1, idx), v[idx] != 0xff)
|
while (check_length(v.size(), 1, idx), v[idx] != 0xff)
|
||||||
{
|
{
|
||||||
|
cbor_expect_string(v, idx);
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
}
|
}
|
||||||
|
@ -8864,6 +8868,9 @@ class basic_json
|
||||||
- float 32 (0xca)
|
- float 32 (0xca)
|
||||||
- fixext 1 - fixext 16 (0xd4..0xd8)
|
- fixext 1 - fixext 16 (0xd4..0xd8)
|
||||||
|
|
||||||
|
@note Any MessagePack output created @ref to_msgpack can be successfully
|
||||||
|
parsed by @ref from_msgpack.
|
||||||
|
|
||||||
@param[in] j JSON value to serialize
|
@param[in] j JSON value to serialize
|
||||||
@return MessagePack serialization as byte vector
|
@return MessagePack serialization as byte vector
|
||||||
|
|
||||||
|
@ -8892,6 +8899,46 @@ class basic_json
|
||||||
Deserializes a given byte vector @a v to a JSON value using the MessagePack
|
Deserializes a given byte vector @a v to a JSON value using the MessagePack
|
||||||
serialization format.
|
serialization format.
|
||||||
|
|
||||||
|
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
|
||||||
|
negative fixint | number_integer | 0xe0-0xff
|
||||||
|
|
||||||
|
@warning The mapping 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)
|
||||||
|
|
||||||
|
@note Any MessagePack output created @ref to_msgpack can be successfully
|
||||||
|
parsed by @ref from_msgpack.
|
||||||
|
|
||||||
@param[in] v a byte vector in MessagePack format
|
@param[in] v a byte vector in MessagePack format
|
||||||
@param[in] start_index the index to start reading from @a v (0 by default)
|
@param[in] start_index the index to start reading from @a v (0 by default)
|
||||||
@return deserialized JSON value
|
@return deserialized JSON value
|
||||||
|
@ -8899,6 +8946,7 @@ class basic_json
|
||||||
@throw parse_error.110 if the given vector ends prematurely
|
@throw parse_error.110 if the given vector ends prematurely
|
||||||
@throw parse_error.112 if unsupported features from MessagePack were
|
@throw parse_error.112 if unsupported features from MessagePack were
|
||||||
used in the given vector @a v or if the input is not valid MessagePack
|
used in the given vector @a v or if the input is not valid MessagePack
|
||||||
|
@throw parse_error.113 if a string was expected as map key, but not found
|
||||||
|
|
||||||
@complexity Linear in the size of the byte vector @a v.
|
@complexity Linear in the size of the byte vector @a v.
|
||||||
|
|
||||||
|
@ -9014,6 +9062,66 @@ class basic_json
|
||||||
Deserializes a given byte vector @a v to a JSON value using the CBOR
|
Deserializes a given byte vector @a v to a JSON value using the CBOR
|
||||||
(Concise Binary Object Representation) serialization format.
|
(Concise Binary Object Representation) serialization format.
|
||||||
|
|
||||||
|
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
|
||||||
|
Negative integer | number_integer | 0x40..0x57
|
||||||
|
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
|
||||||
|
Nill | `null` | 0xf6
|
||||||
|
Half-Precision Float | number_float | 0xf9
|
||||||
|
Single-Precision Float | number_float | 0xfa
|
||||||
|
Double-Precision Float | number_float | 0xfb
|
||||||
|
|
||||||
|
@warning 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 (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)
|
||||||
|
|
||||||
|
@warning 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 (parse_error.113).
|
||||||
|
|
||||||
|
@note Any CBOR output created @ref to_cbor can be successfully parsed by
|
||||||
|
@ref from_cbor.
|
||||||
|
|
||||||
@param[in] v a byte vector in CBOR format
|
@param[in] v a byte vector in CBOR format
|
||||||
@param[in] start_index the index to start reading from @a v (0 by default)
|
@param[in] start_index the index to start reading from @a v (0 by default)
|
||||||
@return deserialized JSON value
|
@return deserialized JSON value
|
||||||
|
@ -9021,6 +9129,7 @@ class basic_json
|
||||||
@throw parse_error.110 if the given vector ends prematurely
|
@throw parse_error.110 if the given vector ends prematurely
|
||||||
@throw parse_error.112 if unsupported features from CBOR were
|
@throw parse_error.112 if unsupported features from CBOR were
|
||||||
used in the given vector @a v or if the input is not valid CBOR
|
used in the given vector @a v or if the input is not valid CBOR
|
||||||
|
@throw parse_error.113 if a string was expected as map key, but not found
|
||||||
|
|
||||||
@complexity Linear in the size of the byte vector @a v.
|
@complexity Linear in the size of the byte vector @a v.
|
||||||
|
|
||||||
|
@ -12423,7 +12532,7 @@ basic_json_parser_74:
|
||||||
reference_token.end(),
|
reference_token.end(),
|
||||||
[](const char x)
|
[](const char x)
|
||||||
{
|
{
|
||||||
return std::isdigit(x);
|
return (x >= '0' and x <= '9');
|
||||||
});
|
});
|
||||||
|
|
||||||
// change value to array for numbers or "-" or to object
|
// change value to array for numbers or "-" or to object
|
||||||
|
|
|
@ -32,7 +32,6 @@ SOFTWARE.
|
||||||
#include <algorithm> // all_of, copy, fill, find, for_each, none_of, remove, reverse, transform
|
#include <algorithm> // all_of, copy, fill, find, for_each, none_of, remove, reverse, transform
|
||||||
#include <array> // array
|
#include <array> // array
|
||||||
#include <cassert> // assert
|
#include <cassert> // assert
|
||||||
#include <cctype> // isdigit
|
|
||||||
#include <ciso646> // and, not, or
|
#include <ciso646> // and, not, or
|
||||||
#include <clocale> // lconv, localeconv
|
#include <clocale> // lconv, localeconv
|
||||||
#include <cmath> // isfinite, labs, ldexp, signbit
|
#include <cmath> // isfinite, labs, ldexp, signbit
|
||||||
|
@ -43,7 +42,6 @@ SOFTWARE.
|
||||||
#include <forward_list> // forward_list
|
#include <forward_list> // forward_list
|
||||||
#include <functional> // function, hash, less
|
#include <functional> // function, hash, less
|
||||||
#include <initializer_list> // initializer_list
|
#include <initializer_list> // initializer_list
|
||||||
#include <iomanip> // setw
|
|
||||||
#include <iostream> // istream, ostream
|
#include <iostream> // istream, ostream
|
||||||
#include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
|
#include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
|
||||||
#include <limits> // numeric_limits
|
#include <limits> // numeric_limits
|
||||||
|
@ -130,7 +128,7 @@ class exception : public std::exception
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// returns the explanatory string
|
/// returns the explanatory string
|
||||||
virtual const char* what() const noexcept
|
virtual const char* what() const noexcept override
|
||||||
{
|
{
|
||||||
return what_arg.c_str();
|
return what_arg.c_str();
|
||||||
}
|
}
|
||||||
|
@ -174,7 +172,7 @@ json.exception.parse_error.109 | parse error: array index 'one' is not a number
|
||||||
json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
|
json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
|
||||||
json.exception.parse_error.111 | parse error: bad input stream | Parsing CBOR or MessagePack from an input stream where the [`badbit` or `failbit`](http://en.cppreference.com/w/cpp/io/ios_base/iostate) is set.
|
json.exception.parse_error.111 | parse error: bad input stream | Parsing CBOR or MessagePack from an input stream where the [`badbit` or `failbit`](http://en.cppreference.com/w/cpp/io/ios_base/iostate) is set.
|
||||||
json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xf8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
|
json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xf8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
|
||||||
json.exception.parse_error.113 | | While parsing a map key, a value that is not a string has been read.
|
json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.
|
||||||
|
|
||||||
@since version 3.0.0
|
@since version 3.0.0
|
||||||
*/
|
*/
|
||||||
|
@ -6468,7 +6466,7 @@ class basic_json
|
||||||
auto i = val.m_value.object->cbegin();
|
auto i = val.m_value.object->cbegin();
|
||||||
for (size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
|
for (size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
|
||||||
{
|
{
|
||||||
o.write(indent_string.c_str(), new_indent);
|
o.write(indent_string.c_str(), static_cast<std::streamsize>(new_indent));
|
||||||
o.put('\"');
|
o.put('\"');
|
||||||
dump_escaped(i->first);
|
dump_escaped(i->first);
|
||||||
o.write("\": ", 3);
|
o.write("\": ", 3);
|
||||||
|
@ -6478,14 +6476,14 @@ class basic_json
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(i != val.m_value.object->cend());
|
assert(i != val.m_value.object->cend());
|
||||||
o.write(indent_string.c_str(), new_indent);
|
o.write(indent_string.c_str(), static_cast<std::streamsize>(new_indent));
|
||||||
o.put('\"');
|
o.put('\"');
|
||||||
dump_escaped(i->first);
|
dump_escaped(i->first);
|
||||||
o.write("\": ", 3);
|
o.write("\": ", 3);
|
||||||
dump(i->second, true, indent_step, new_indent);
|
dump(i->second, true, indent_step, new_indent);
|
||||||
|
|
||||||
o.put('\n');
|
o.put('\n');
|
||||||
o.write(indent_string.c_str(), current_indent);
|
o.write(indent_string.c_str(), static_cast<std::streamsize>(current_indent));
|
||||||
o.put('}');
|
o.put('}');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -6538,18 +6536,18 @@ class basic_json
|
||||||
// first n-1 elements
|
// first n-1 elements
|
||||||
for (auto i = val.m_value.array->cbegin(); i != val.m_value.array->cend() - 1; ++i)
|
for (auto i = val.m_value.array->cbegin(); i != val.m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
o.write(indent_string.c_str(), new_indent);
|
o.write(indent_string.c_str(), static_cast<std::streamsize>(new_indent));
|
||||||
dump(*i, true, indent_step, new_indent);
|
dump(*i, true, indent_step, new_indent);
|
||||||
o.write(",\n", 2);
|
o.write(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(not val.m_value.array->empty());
|
assert(not val.m_value.array->empty());
|
||||||
o.write(indent_string.c_str(), new_indent);
|
o.write(indent_string.c_str(), static_cast<std::streamsize>(new_indent));
|
||||||
dump(val.m_value.array->back(), true, indent_step, new_indent);
|
dump(val.m_value.array->back(), true, indent_step, new_indent);
|
||||||
|
|
||||||
o.put('\n');
|
o.put('\n');
|
||||||
o.write(indent_string.c_str(), current_indent);
|
o.write(indent_string.c_str(), static_cast<std::streamsize>(current_indent));
|
||||||
o.put(']');
|
o.put(']');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -7848,7 +7846,7 @@ class basic_json
|
||||||
const auto N = j.m_value.string->size();
|
const auto N = j.m_value.string->size();
|
||||||
if (N <= 0x17)
|
if (N <= 0x17)
|
||||||
{
|
{
|
||||||
v.push_back(0x60 + static_cast<uint8_t>(N)); // 1 byte for string + size
|
v.push_back(static_cast<uint8_t>(0x60 + N)); // 1 byte for string + size
|
||||||
}
|
}
|
||||||
else if (N <= 0xff)
|
else if (N <= 0xff)
|
||||||
{
|
{
|
||||||
|
@ -7884,7 +7882,7 @@ class basic_json
|
||||||
const auto N = j.m_value.array->size();
|
const auto N = j.m_value.array->size();
|
||||||
if (N <= 0x17)
|
if (N <= 0x17)
|
||||||
{
|
{
|
||||||
v.push_back(0x80 + static_cast<uint8_t>(N)); // 1 byte for array + size
|
v.push_back(static_cast<uint8_t>(0x80 + N)); // 1 byte for array + size
|
||||||
}
|
}
|
||||||
else if (N <= 0xff)
|
else if (N <= 0xff)
|
||||||
{
|
{
|
||||||
|
@ -7922,7 +7920,7 @@ class basic_json
|
||||||
const auto N = j.m_value.object->size();
|
const auto N = j.m_value.object->size();
|
||||||
if (N <= 0x17)
|
if (N <= 0x17)
|
||||||
{
|
{
|
||||||
v.push_back(0xa0 + static_cast<uint8_t>(N)); // 1 byte for object + size
|
v.push_back(static_cast<uint8_t>(0xa0 + N)); // 1 byte for object + size
|
||||||
}
|
}
|
||||||
else if (N <= 0xff)
|
else if (N <= 0xff)
|
||||||
{
|
{
|
||||||
|
@ -8653,6 +8651,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(v[current_idx] - 0xa0);
|
const auto len = static_cast<size_t>(v[current_idx] - 0xa0);
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
|
cbor_expect_string(v, idx);
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
}
|
}
|
||||||
|
@ -8666,6 +8665,7 @@ class basic_json
|
||||||
idx += 1; // skip 1 size byte
|
idx += 1; // skip 1 size byte
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
|
cbor_expect_string(v, idx);
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
}
|
}
|
||||||
|
@ -8679,6 +8679,7 @@ class basic_json
|
||||||
idx += 2; // skip 2 size bytes
|
idx += 2; // skip 2 size bytes
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
|
cbor_expect_string(v, idx);
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
}
|
}
|
||||||
|
@ -8692,6 +8693,7 @@ class basic_json
|
||||||
idx += 4; // skip 4 size bytes
|
idx += 4; // skip 4 size bytes
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
|
cbor_expect_string(v, idx);
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
}
|
}
|
||||||
|
@ -8705,6 +8707,7 @@ class basic_json
|
||||||
idx += 8; // skip 8 size bytes
|
idx += 8; // skip 8 size bytes
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
|
cbor_expect_string(v, idx);
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
}
|
}
|
||||||
|
@ -8716,6 +8719,7 @@ class basic_json
|
||||||
basic_json result = value_t::object;
|
basic_json result = value_t::object;
|
||||||
while (check_length(v.size(), 1, idx), v[idx] != 0xff)
|
while (check_length(v.size(), 1, idx), v[idx] != 0xff)
|
||||||
{
|
{
|
||||||
|
cbor_expect_string(v, idx);
|
||||||
std::string key = from_cbor_internal(v, idx);
|
std::string key = from_cbor_internal(v, idx);
|
||||||
result[key] = from_cbor_internal(v, idx);
|
result[key] = from_cbor_internal(v, idx);
|
||||||
}
|
}
|
||||||
|
@ -8864,6 +8868,9 @@ class basic_json
|
||||||
- float 32 (0xca)
|
- float 32 (0xca)
|
||||||
- fixext 1 - fixext 16 (0xd4..0xd8)
|
- fixext 1 - fixext 16 (0xd4..0xd8)
|
||||||
|
|
||||||
|
@note Any MessagePack output created @ref to_msgpack can be successfully
|
||||||
|
parsed by @ref from_msgpack.
|
||||||
|
|
||||||
@param[in] j JSON value to serialize
|
@param[in] j JSON value to serialize
|
||||||
@return MessagePack serialization as byte vector
|
@return MessagePack serialization as byte vector
|
||||||
|
|
||||||
|
@ -8892,6 +8899,46 @@ class basic_json
|
||||||
Deserializes a given byte vector @a v to a JSON value using the MessagePack
|
Deserializes a given byte vector @a v to a JSON value using the MessagePack
|
||||||
serialization format.
|
serialization format.
|
||||||
|
|
||||||
|
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
|
||||||
|
negative fixint | number_integer | 0xe0-0xff
|
||||||
|
|
||||||
|
@warning The mapping 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)
|
||||||
|
|
||||||
|
@note Any MessagePack output created @ref to_msgpack can be successfully
|
||||||
|
parsed by @ref from_msgpack.
|
||||||
|
|
||||||
@param[in] v a byte vector in MessagePack format
|
@param[in] v a byte vector in MessagePack format
|
||||||
@param[in] start_index the index to start reading from @a v (0 by default)
|
@param[in] start_index the index to start reading from @a v (0 by default)
|
||||||
@return deserialized JSON value
|
@return deserialized JSON value
|
||||||
|
@ -8899,6 +8946,7 @@ class basic_json
|
||||||
@throw parse_error.110 if the given vector ends prematurely
|
@throw parse_error.110 if the given vector ends prematurely
|
||||||
@throw parse_error.112 if unsupported features from MessagePack were
|
@throw parse_error.112 if unsupported features from MessagePack were
|
||||||
used in the given vector @a v or if the input is not valid MessagePack
|
used in the given vector @a v or if the input is not valid MessagePack
|
||||||
|
@throw parse_error.113 if a string was expected as map key, but not found
|
||||||
|
|
||||||
@complexity Linear in the size of the byte vector @a v.
|
@complexity Linear in the size of the byte vector @a v.
|
||||||
|
|
||||||
|
@ -9014,6 +9062,66 @@ class basic_json
|
||||||
Deserializes a given byte vector @a v to a JSON value using the CBOR
|
Deserializes a given byte vector @a v to a JSON value using the CBOR
|
||||||
(Concise Binary Object Representation) serialization format.
|
(Concise Binary Object Representation) serialization format.
|
||||||
|
|
||||||
|
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
|
||||||
|
Negative integer | number_integer | 0x40..0x57
|
||||||
|
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
|
||||||
|
Nill | `null` | 0xf6
|
||||||
|
Half-Precision Float | number_float | 0xf9
|
||||||
|
Single-Precision Float | number_float | 0xfa
|
||||||
|
Double-Precision Float | number_float | 0xfb
|
||||||
|
|
||||||
|
@warning 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 (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)
|
||||||
|
|
||||||
|
@warning 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 (parse_error.113).
|
||||||
|
|
||||||
|
@note Any CBOR output created @ref to_cbor can be successfully parsed by
|
||||||
|
@ref from_cbor.
|
||||||
|
|
||||||
@param[in] v a byte vector in CBOR format
|
@param[in] v a byte vector in CBOR format
|
||||||
@param[in] start_index the index to start reading from @a v (0 by default)
|
@param[in] start_index the index to start reading from @a v (0 by default)
|
||||||
@return deserialized JSON value
|
@return deserialized JSON value
|
||||||
|
@ -9021,6 +9129,7 @@ class basic_json
|
||||||
@throw parse_error.110 if the given vector ends prematurely
|
@throw parse_error.110 if the given vector ends prematurely
|
||||||
@throw parse_error.112 if unsupported features from CBOR were
|
@throw parse_error.112 if unsupported features from CBOR were
|
||||||
used in the given vector @a v or if the input is not valid CBOR
|
used in the given vector @a v or if the input is not valid CBOR
|
||||||
|
@throw parse_error.113 if a string was expected as map key, but not found
|
||||||
|
|
||||||
@complexity Linear in the size of the byte vector @a v.
|
@complexity Linear in the size of the byte vector @a v.
|
||||||
|
|
||||||
|
@ -11456,7 +11565,7 @@ class basic_json
|
||||||
reference_token.end(),
|
reference_token.end(),
|
||||||
[](const char x)
|
[](const char x)
|
||||||
{
|
{
|
||||||
return std::isdigit(x);
|
return (x >= '0' and x <= '9');
|
||||||
});
|
});
|
||||||
|
|
||||||
// change value to array for numbers or "-" or to object
|
// change value to array for numbers or "-" or to object
|
||||||
|
|
|
@ -130,14 +130,14 @@ TEST_CASE("CBOR")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0x3b);
|
CHECK(result[0] == 0x3b);
|
||||||
uint64_t restored = static_cast<uint64_t>((static_cast<uint64_t>(result[1]) << 070) +
|
uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
|
||||||
(static_cast<uint64_t>(result[2]) << 060) +
|
(static_cast<uint64_t>(result[2]) << 060) +
|
||||||
(static_cast<uint64_t>(result[3]) << 050) +
|
(static_cast<uint64_t>(result[3]) << 050) +
|
||||||
(static_cast<uint64_t>(result[4]) << 040) +
|
(static_cast<uint64_t>(result[4]) << 040) +
|
||||||
(static_cast<uint64_t>(result[5]) << 030) +
|
(static_cast<uint64_t>(result[5]) << 030) +
|
||||||
(static_cast<uint64_t>(result[6]) << 020) +
|
(static_cast<uint64_t>(result[6]) << 020) +
|
||||||
(static_cast<uint64_t>(result[7]) << 010) +
|
(static_cast<uint64_t>(result[7]) << 010) +
|
||||||
static_cast<uint64_t>(result[8]));
|
static_cast<uint64_t>(result[8]);
|
||||||
CHECK(restored == positive);
|
CHECK(restored == positive);
|
||||||
CHECK(-1 - static_cast<int64_t>(restored) == i);
|
CHECK(-1 - static_cast<int64_t>(restored) == i);
|
||||||
|
|
||||||
|
@ -182,10 +182,10 @@ TEST_CASE("CBOR")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0x3a);
|
CHECK(result[0] == 0x3a);
|
||||||
uint32_t restored = static_cast<uint32_t>((static_cast<uint32_t>(result[1]) << 030) +
|
uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
|
||||||
(static_cast<uint32_t>(result[2]) << 020) +
|
(static_cast<uint32_t>(result[2]) << 020) +
|
||||||
(static_cast<uint32_t>(result[3]) << 010) +
|
(static_cast<uint32_t>(result[3]) << 010) +
|
||||||
static_cast<uint32_t>(result[4]));
|
static_cast<uint32_t>(result[4]);
|
||||||
CHECK(restored == positive);
|
CHECK(restored == positive);
|
||||||
CHECK(-1ll - restored == i);
|
CHECK(-1ll - restored == i);
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ TEST_CASE("CBOR")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0x39);
|
CHECK(result[0] == 0x39);
|
||||||
uint16_t restored = static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]);
|
uint16_t restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
|
||||||
CHECK(restored == positive);
|
CHECK(restored == positive);
|
||||||
CHECK(-1 - restored == i);
|
CHECK(-1 - restored == i);
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ TEST_CASE("CBOR")
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> expected;
|
std::vector<uint8_t> expected;
|
||||||
expected.push_back(0x20 - 1 - static_cast<uint8_t>(i));
|
expected.push_back(static_cast<uint8_t>(0x20 - 1 - static_cast<uint8_t>(i)));
|
||||||
|
|
||||||
// compare result + size
|
// compare result + size
|
||||||
const auto result = json::to_cbor(j);
|
const auto result = json::to_cbor(j);
|
||||||
|
@ -392,7 +392,7 @@ TEST_CASE("CBOR")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0x19);
|
CHECK(result[0] == 0x19);
|
||||||
uint16_t restored = static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]);
|
uint16_t restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -431,10 +431,10 @@ TEST_CASE("CBOR")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0x1a);
|
CHECK(result[0] == 0x1a);
|
||||||
uint32_t restored = static_cast<uint32_t>((static_cast<uint32_t>(result[1]) << 030) +
|
uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
|
||||||
(static_cast<uint32_t>(result[2]) << 020) +
|
(static_cast<uint32_t>(result[2]) << 020) +
|
||||||
(static_cast<uint32_t>(result[3]) << 010) +
|
(static_cast<uint32_t>(result[3]) << 010) +
|
||||||
static_cast<uint32_t>(result[4]));
|
static_cast<uint32_t>(result[4]);
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -477,14 +477,14 @@ TEST_CASE("CBOR")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0x1b);
|
CHECK(result[0] == 0x1b);
|
||||||
uint64_t restored = static_cast<uint64_t>((static_cast<uint64_t>(result[1]) << 070) +
|
uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
|
||||||
(static_cast<uint64_t>(result[2]) << 060) +
|
(static_cast<uint64_t>(result[2]) << 060) +
|
||||||
(static_cast<uint64_t>(result[3]) << 050) +
|
(static_cast<uint64_t>(result[3]) << 050) +
|
||||||
(static_cast<uint64_t>(result[4]) << 040) +
|
(static_cast<uint64_t>(result[4]) << 040) +
|
||||||
(static_cast<uint64_t>(result[5]) << 030) +
|
(static_cast<uint64_t>(result[5]) << 030) +
|
||||||
(static_cast<uint64_t>(result[6]) << 020) +
|
(static_cast<uint64_t>(result[6]) << 020) +
|
||||||
(static_cast<uint64_t>(result[7]) << 010) +
|
(static_cast<uint64_t>(result[7]) << 010) +
|
||||||
static_cast<uint64_t>(result[8]));
|
static_cast<uint64_t>(result[8]);
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -616,7 +616,7 @@ TEST_CASE("CBOR")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0x19);
|
CHECK(result[0] == 0x19);
|
||||||
uint16_t restored = static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]);
|
uint16_t restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -654,10 +654,10 @@ TEST_CASE("CBOR")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0x1a);
|
CHECK(result[0] == 0x1a);
|
||||||
uint32_t restored = static_cast<uint32_t>((static_cast<uint32_t>(result[1]) << 030) +
|
uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
|
||||||
(static_cast<uint32_t>(result[2]) << 020) +
|
(static_cast<uint32_t>(result[2]) << 020) +
|
||||||
(static_cast<uint32_t>(result[3]) << 010) +
|
(static_cast<uint32_t>(result[3]) << 010) +
|
||||||
static_cast<uint32_t>(result[4]));
|
static_cast<uint32_t>(result[4]);
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -699,14 +699,14 @@ TEST_CASE("CBOR")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0x1b);
|
CHECK(result[0] == 0x1b);
|
||||||
uint64_t restored = static_cast<uint64_t>((static_cast<uint64_t>(result[1]) << 070) +
|
uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
|
||||||
(static_cast<uint64_t>(result[2]) << 060) +
|
(static_cast<uint64_t>(result[2]) << 060) +
|
||||||
(static_cast<uint64_t>(result[3]) << 050) +
|
(static_cast<uint64_t>(result[3]) << 050) +
|
||||||
(static_cast<uint64_t>(result[4]) << 040) +
|
(static_cast<uint64_t>(result[4]) << 040) +
|
||||||
(static_cast<uint64_t>(result[5]) << 030) +
|
(static_cast<uint64_t>(result[5]) << 030) +
|
||||||
(static_cast<uint64_t>(result[6]) << 020) +
|
(static_cast<uint64_t>(result[6]) << 020) +
|
||||||
(static_cast<uint64_t>(result[7]) << 010) +
|
(static_cast<uint64_t>(result[7]) << 010) +
|
||||||
static_cast<uint64_t>(result[8]));
|
static_cast<uint64_t>(result[8]);
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -1538,6 +1538,83 @@ TEST_CASE("CBOR roundtrips", "[hide]")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("all first bytes", "[!throws]")
|
||||||
|
{
|
||||||
|
// these bytes will fail immediately with exception parse_error.112
|
||||||
|
std::set<uint8_t> unsupported =
|
||||||
|
{
|
||||||
|
//// types not supported by this library
|
||||||
|
|
||||||
|
// byte strings
|
||||||
|
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||||
|
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||||
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||||
|
// byte strings
|
||||||
|
0x58, 0x59, 0x5a, 0x5b, 0x5f,
|
||||||
|
// date/time
|
||||||
|
0xc0, 0xc1,
|
||||||
|
// bignum
|
||||||
|
0xc2, 0xc3,
|
||||||
|
// decimal fracion
|
||||||
|
0xc4,
|
||||||
|
// bigfloat
|
||||||
|
0xc5,
|
||||||
|
// tagged item
|
||||||
|
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd,
|
||||||
|
0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd8,
|
||||||
|
0xd9, 0xda, 0xdb,
|
||||||
|
// expected conversion
|
||||||
|
0xd5, 0xd6, 0xd7,
|
||||||
|
// simple value
|
||||||
|
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
||||||
|
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xef, 0xf0,
|
||||||
|
0xf1, 0xf2, 0xf3,
|
||||||
|
0xf8,
|
||||||
|
// undefined
|
||||||
|
0xf7,
|
||||||
|
|
||||||
|
//// bytes not specified by CBOR
|
||||||
|
|
||||||
|
0x1c, 0x1d, 0x1e, 0x1f,
|
||||||
|
0x3c, 0x3d, 0x3e, 0x3f,
|
||||||
|
0x5c, 0x5d, 0x5e,
|
||||||
|
0x7c, 0x7d, 0x7e,
|
||||||
|
0x9c, 0x9d, 0x9e,
|
||||||
|
0xbc, 0xbd, 0xbe,
|
||||||
|
0xdc, 0xdd, 0xde, 0xdf,
|
||||||
|
0xee,
|
||||||
|
0xfc, 0xfe, 0xfd,
|
||||||
|
|
||||||
|
/// break cannot be the first byte
|
||||||
|
|
||||||
|
0xff
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
|
const auto byte = static_cast<uint8_t>(i);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
json::from_cbor({byte});
|
||||||
|
}
|
||||||
|
catch (const json::parse_error& e)
|
||||||
|
{
|
||||||
|
// check that parse_error.112 is only thrown if the
|
||||||
|
// first byte is in the unsupported set
|
||||||
|
CAPTURE(e.what());
|
||||||
|
if (std::find(unsupported.begin(), unsupported.end(), byte) != unsupported.end())
|
||||||
|
{
|
||||||
|
CHECK(e.id == 112);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CHECK(e.id != 112);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("examples from RFC 7049 Appendix A")
|
TEST_CASE("examples from RFC 7049 Appendix A")
|
||||||
{
|
{
|
||||||
SECTION("numbers")
|
SECTION("numbers")
|
||||||
|
|
|
@ -139,7 +139,7 @@ TEST_CASE("lexer class")
|
||||||
for (int c = 1; c < 128; ++c)
|
for (int c = 1; c < 128; ++c)
|
||||||
{
|
{
|
||||||
// create string from the ASCII code
|
// create string from the ASCII code
|
||||||
const auto s = std::string(1, c);
|
const auto s = std::string(1, static_cast<char>(c));
|
||||||
// store scan() result
|
// store scan() result
|
||||||
const auto res = json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>(s.c_str()),
|
const auto res = json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>(s.c_str()),
|
||||||
1).scan();
|
1).scan();
|
||||||
|
|
|
@ -494,7 +494,7 @@ TEST_CASE("parser class")
|
||||||
// invalid escapes
|
// invalid escapes
|
||||||
for (int c = 1; c < 128; ++c)
|
for (int c = 1; c < 128; ++c)
|
||||||
{
|
{
|
||||||
auto s = std::string("\"\\") + std::string(1, c) + "\"";
|
auto s = std::string("\"\\") + std::string(1, static_cast<char>(c)) + "\"";
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
@ -574,10 +574,10 @@ TEST_CASE("parser class")
|
||||||
std::string s = "\"\\u";
|
std::string s = "\"\\u";
|
||||||
|
|
||||||
// create a string with the iterated character at each position
|
// create a string with the iterated character at each position
|
||||||
auto s1 = s + "000" + std::string(1, c) + "\"";
|
auto s1 = s + "000" + std::string(1, static_cast<char>(c)) + "\"";
|
||||||
auto s2 = s + "00" + std::string(1, c) + "0\"";
|
auto s2 = s + "00" + std::string(1, static_cast<char>(c)) + "0\"";
|
||||||
auto s3 = s + "0" + std::string(1, c) + "00\"";
|
auto s3 = s + "0" + std::string(1, static_cast<char>(c)) + "00\"";
|
||||||
auto s4 = s + std::string(1, c) + "000\"";
|
auto s4 = s + std::string(1, static_cast<char>(c)) + "000\"";
|
||||||
|
|
||||||
if (valid(c))
|
if (valid(c))
|
||||||
{
|
{
|
||||||
|
|
|
@ -72,8 +72,8 @@ TEST_CASE("concepts")
|
||||||
// X::size_type must return an unsigned integer
|
// X::size_type must return an unsigned integer
|
||||||
CHECK((std::is_unsigned<json::size_type>::value));
|
CHECK((std::is_unsigned<json::size_type>::value));
|
||||||
// X::size_type can represent any non-negative value of X::difference_type
|
// X::size_type can represent any non-negative value of X::difference_type
|
||||||
CHECK(static_cast<size_t>(std::numeric_limits<json::difference_type>::max()) <=
|
CHECK(static_cast<json::size_type>(std::numeric_limits<json::difference_type>::max()) <=
|
||||||
static_cast<size_t>(std::numeric_limits<json::size_type>::max()));
|
std::numeric_limits<json::size_type>::max());
|
||||||
|
|
||||||
// the expression "X u" has the post-condition "u.empty()"
|
// the expression "X u" has the post-condition "u.empty()"
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,7 +48,7 @@ TEST_CASE("element access 1")
|
||||||
CHECK(j.at(3) == json(nullptr));
|
CHECK(j.at(3) == json(nullptr));
|
||||||
CHECK(j.at(4) == json("string"));
|
CHECK(j.at(4) == json("string"));
|
||||||
CHECK(j.at(5) == json(42.23));
|
CHECK(j.at(5) == json(42.23));
|
||||||
CHECK(j.at(6) == json(json::object()));
|
CHECK(j.at(6) == json::object());
|
||||||
CHECK(j.at(7) == json({1, 2, 3}));
|
CHECK(j.at(7) == json({1, 2, 3}));
|
||||||
|
|
||||||
CHECK(j_const.at(0) == json(1));
|
CHECK(j_const.at(0) == json(1));
|
||||||
|
@ -57,7 +57,7 @@ TEST_CASE("element access 1")
|
||||||
CHECK(j_const.at(3) == json(nullptr));
|
CHECK(j_const.at(3) == json(nullptr));
|
||||||
CHECK(j_const.at(4) == json("string"));
|
CHECK(j_const.at(4) == json("string"));
|
||||||
CHECK(j_const.at(5) == json(42.23));
|
CHECK(j_const.at(5) == json(42.23));
|
||||||
CHECK(j_const.at(6) == json(json::object()));
|
CHECK(j_const.at(6) == json::object());
|
||||||
CHECK(j_const.at(7) == json({1, 2, 3}));
|
CHECK(j_const.at(7) == json({1, 2, 3}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ TEST_CASE("element access 1")
|
||||||
CHECK(j[3] == json(nullptr));
|
CHECK(j[3] == json(nullptr));
|
||||||
CHECK(j[4] == json("string"));
|
CHECK(j[4] == json("string"));
|
||||||
CHECK(j[5] == json(42.23));
|
CHECK(j[5] == json(42.23));
|
||||||
CHECK(j[6] == json(json::object()));
|
CHECK(j[6] == json::object());
|
||||||
CHECK(j[7] == json({1, 2, 3}));
|
CHECK(j[7] == json({1, 2, 3}));
|
||||||
|
|
||||||
CHECK(j_const[0] == json(1));
|
CHECK(j_const[0] == json(1));
|
||||||
|
@ -180,7 +180,7 @@ TEST_CASE("element access 1")
|
||||||
CHECK(j_const[3] == json(nullptr));
|
CHECK(j_const[3] == json(nullptr));
|
||||||
CHECK(j_const[4] == json("string"));
|
CHECK(j_const[4] == json("string"));
|
||||||
CHECK(j_const[5] == json(42.23));
|
CHECK(j_const[5] == json(42.23));
|
||||||
CHECK(j_const[6] == json(json::object()));
|
CHECK(j_const[6] == json::object());
|
||||||
CHECK(j_const[7] == json({1, 2, 3}));
|
CHECK(j_const[7] == json({1, 2, 3}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ TEST_CASE("element access 2")
|
||||||
CHECK(j.at("null") == json(nullptr));
|
CHECK(j.at("null") == json(nullptr));
|
||||||
CHECK(j.at("string") == json("hello world"));
|
CHECK(j.at("string") == json("hello world"));
|
||||||
CHECK(j.at("floating") == json(42.23));
|
CHECK(j.at("floating") == json(42.23));
|
||||||
CHECK(j.at("object") == json(json::object()));
|
CHECK(j.at("object") == json::object());
|
||||||
CHECK(j.at("array") == json({1, 2, 3}));
|
CHECK(j.at("array") == json({1, 2, 3}));
|
||||||
|
|
||||||
CHECK(j_const.at("integer") == json(1));
|
CHECK(j_const.at("integer") == json(1));
|
||||||
|
@ -57,7 +57,7 @@ TEST_CASE("element access 2")
|
||||||
CHECK(j_const.at("null") == json(nullptr));
|
CHECK(j_const.at("null") == json(nullptr));
|
||||||
CHECK(j_const.at("string") == json("hello world"));
|
CHECK(j_const.at("string") == json("hello world"));
|
||||||
CHECK(j_const.at("floating") == json(42.23));
|
CHECK(j_const.at("floating") == json(42.23));
|
||||||
CHECK(j_const.at("object") == json(json::object()));
|
CHECK(j_const.at("object") == json::object());
|
||||||
CHECK(j_const.at("array") == json({1, 2, 3}));
|
CHECK(j_const.at("array") == json({1, 2, 3}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ TEST_CASE("element access 2")
|
||||||
CHECK(j.value("string", std::string("bar")) == "hello world");
|
CHECK(j.value("string", std::string("bar")) == "hello world");
|
||||||
CHECK(j.value("floating", 12.34) == Approx(42.23));
|
CHECK(j.value("floating", 12.34) == Approx(42.23));
|
||||||
CHECK(j.value("floating", 12) == 42);
|
CHECK(j.value("floating", 12) == 42);
|
||||||
CHECK(j.value("object", json({{"foo", "bar"}})) == json(json::object()));
|
CHECK(j.value("object", json({{"foo", "bar"}})) == json::object());
|
||||||
CHECK(j.value("array", json({10, 100})) == json({1, 2, 3}));
|
CHECK(j.value("array", json({10, 100})) == json({1, 2, 3}));
|
||||||
|
|
||||||
CHECK(j_const.value("integer", 2) == 1);
|
CHECK(j_const.value("integer", 2) == 1);
|
||||||
|
@ -173,7 +173,7 @@ TEST_CASE("element access 2")
|
||||||
CHECK(j_const.value("string", std::string("bar")) == "hello world");
|
CHECK(j_const.value("string", std::string("bar")) == "hello world");
|
||||||
CHECK(j_const.value("floating", 12.34) == Approx(42.23));
|
CHECK(j_const.value("floating", 12.34) == Approx(42.23));
|
||||||
CHECK(j_const.value("floating", 12) == 42);
|
CHECK(j_const.value("floating", 12) == 42);
|
||||||
CHECK(j_const.value("object", json({{"foo", "bar"}})) == json(json::object()));
|
CHECK(j_const.value("object", json({{"foo", "bar"}})) == json::object());
|
||||||
CHECK(j_const.value("array", json({10, 100})) == json({1, 2, 3}));
|
CHECK(j_const.value("array", json({10, 100})) == json({1, 2, 3}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ TEST_CASE("element access 2")
|
||||||
CHECK(j.value("/string"_json_pointer, std::string("bar")) == "hello world");
|
CHECK(j.value("/string"_json_pointer, std::string("bar")) == "hello world");
|
||||||
CHECK(j.value("/floating"_json_pointer, 12.34) == Approx(42.23));
|
CHECK(j.value("/floating"_json_pointer, 12.34) == Approx(42.23));
|
||||||
CHECK(j.value("/floating"_json_pointer, 12) == 42);
|
CHECK(j.value("/floating"_json_pointer, 12) == 42);
|
||||||
CHECK(j.value("/object"_json_pointer, json({{"foo", "bar"}})) == json(json::object()));
|
CHECK(j.value("/object"_json_pointer, json({{"foo", "bar"}})) == json::object());
|
||||||
CHECK(j.value("/array"_json_pointer, json({10, 100})) == json({1, 2, 3}));
|
CHECK(j.value("/array"_json_pointer, json({10, 100})) == json({1, 2, 3}));
|
||||||
|
|
||||||
CHECK(j_const.value("/integer"_json_pointer, 2) == 1);
|
CHECK(j_const.value("/integer"_json_pointer, 2) == 1);
|
||||||
|
@ -310,7 +310,7 @@ TEST_CASE("element access 2")
|
||||||
CHECK(j_const.value("/string"_json_pointer, std::string("bar")) == "hello world");
|
CHECK(j_const.value("/string"_json_pointer, std::string("bar")) == "hello world");
|
||||||
CHECK(j_const.value("/floating"_json_pointer, 12.34) == Approx(42.23));
|
CHECK(j_const.value("/floating"_json_pointer, 12.34) == Approx(42.23));
|
||||||
CHECK(j_const.value("/floating"_json_pointer, 12) == 42);
|
CHECK(j_const.value("/floating"_json_pointer, 12) == 42);
|
||||||
CHECK(j_const.value("/object"_json_pointer, json({{"foo", "bar"}})) == json(json::object()));
|
CHECK(j_const.value("/object"_json_pointer, json({{"foo", "bar"}})) == json::object());
|
||||||
CHECK(j_const.value("/array"_json_pointer, json({10, 100})) == json({1, 2, 3}));
|
CHECK(j_const.value("/array"_json_pointer, json({10, 100})) == json({1, 2, 3}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +435,7 @@ TEST_CASE("element access 2")
|
||||||
CHECK(j["floating"] == json(42.23));
|
CHECK(j["floating"] == json(42.23));
|
||||||
CHECK(j[json::object_t::key_type("floating")] == j["floating"]);
|
CHECK(j[json::object_t::key_type("floating")] == j["floating"]);
|
||||||
|
|
||||||
CHECK(j["object"] == json(json::object()));
|
CHECK(j["object"] == json::object());
|
||||||
CHECK(j[json::object_t::key_type("object")] == j["object"]);
|
CHECK(j[json::object_t::key_type("object")] == j["object"]);
|
||||||
|
|
||||||
CHECK(j["array"] == json({1, 2, 3}));
|
CHECK(j["array"] == json({1, 2, 3}));
|
||||||
|
@ -456,7 +456,7 @@ TEST_CASE("element access 2")
|
||||||
CHECK(j_const["floating"] == json(42.23));
|
CHECK(j_const["floating"] == json(42.23));
|
||||||
CHECK(j_const[json::object_t::key_type("floating")] == j["floating"]);
|
CHECK(j_const[json::object_t::key_type("floating")] == j["floating"]);
|
||||||
|
|
||||||
CHECK(j_const["object"] == json(json::object()));
|
CHECK(j_const["object"] == json::object());
|
||||||
CHECK(j_const[json::object_t::key_type("object")] == j["object"]);
|
CHECK(j_const[json::object_t::key_type("object")] == j["object"]);
|
||||||
|
|
||||||
CHECK(j_const["array"] == json({1, 2, 3}));
|
CHECK(j_const["array"] == json({1, 2, 3}));
|
||||||
|
|
|
@ -203,7 +203,7 @@ TEST_CASE("MessagePack")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xcd);
|
CHECK(result[0] == 0xcd);
|
||||||
uint16_t restored = static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]);
|
uint16_t restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -242,10 +242,10 @@ TEST_CASE("MessagePack")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xce);
|
CHECK(result[0] == 0xce);
|
||||||
uint32_t restored = static_cast<uint32_t>((static_cast<uint32_t>(result[1]) << 030) +
|
uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
|
||||||
(static_cast<uint32_t>(result[2]) << 020) +
|
(static_cast<uint32_t>(result[2]) << 020) +
|
||||||
(static_cast<uint32_t>(result[3]) << 010) +
|
(static_cast<uint32_t>(result[3]) << 010) +
|
||||||
static_cast<uint32_t>(result[4]));
|
static_cast<uint32_t>(result[4]);
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -288,14 +288,14 @@ TEST_CASE("MessagePack")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xcf);
|
CHECK(result[0] == 0xcf);
|
||||||
uint64_t restored = static_cast<uint64_t>((static_cast<uint64_t>(result[1]) << 070) +
|
uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
|
||||||
(static_cast<uint64_t>(result[2]) << 060) +
|
(static_cast<uint64_t>(result[2]) << 060) +
|
||||||
(static_cast<uint64_t>(result[3]) << 050) +
|
(static_cast<uint64_t>(result[3]) << 050) +
|
||||||
(static_cast<uint64_t>(result[4]) << 040) +
|
(static_cast<uint64_t>(result[4]) << 040) +
|
||||||
(static_cast<uint64_t>(result[5]) << 030) +
|
(static_cast<uint64_t>(result[5]) << 030) +
|
||||||
(static_cast<uint64_t>(result[6]) << 020) +
|
(static_cast<uint64_t>(result[6]) << 020) +
|
||||||
(static_cast<uint64_t>(result[7]) << 010) +
|
(static_cast<uint64_t>(result[7]) << 010) +
|
||||||
static_cast<uint64_t>(result[8]));
|
static_cast<uint64_t>(result[8]);
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -415,10 +415,10 @@ TEST_CASE("MessagePack")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xd2);
|
CHECK(result[0] == 0xd2);
|
||||||
uint32_t restored = static_cast<uint32_t>((static_cast<uint32_t>(result[1]) << 030) +
|
uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
|
||||||
(static_cast<uint32_t>(result[2]) << 020) +
|
(static_cast<uint32_t>(result[2]) << 020) +
|
||||||
(static_cast<uint32_t>(result[3]) << 010) +
|
(static_cast<uint32_t>(result[3]) << 010) +
|
||||||
static_cast<uint32_t>(result[4]));
|
static_cast<uint32_t>(result[4]);
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -460,14 +460,14 @@ TEST_CASE("MessagePack")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xd3);
|
CHECK(result[0] == 0xd3);
|
||||||
int64_t restored = static_cast<int64_t>((static_cast<int64_t>(result[1]) << 070) +
|
int64_t restored = (static_cast<int64_t>(result[1]) << 070) +
|
||||||
(static_cast<int64_t>(result[2]) << 060) +
|
(static_cast<int64_t>(result[2]) << 060) +
|
||||||
(static_cast<int64_t>(result[3]) << 050) +
|
(static_cast<int64_t>(result[3]) << 050) +
|
||||||
(static_cast<int64_t>(result[4]) << 040) +
|
(static_cast<int64_t>(result[4]) << 040) +
|
||||||
(static_cast<int64_t>(result[5]) << 030) +
|
(static_cast<int64_t>(result[5]) << 030) +
|
||||||
(static_cast<int64_t>(result[6]) << 020) +
|
(static_cast<int64_t>(result[6]) << 020) +
|
||||||
(static_cast<int64_t>(result[7]) << 010) +
|
(static_cast<int64_t>(result[7]) << 010) +
|
||||||
static_cast<int64_t>(result[8]));
|
static_cast<int64_t>(result[8]);
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -564,7 +564,7 @@ TEST_CASE("MessagePack")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xcd);
|
CHECK(result[0] == 0xcd);
|
||||||
uint16_t restored = static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]);
|
uint16_t restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -602,10 +602,10 @@ TEST_CASE("MessagePack")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xce);
|
CHECK(result[0] == 0xce);
|
||||||
uint32_t restored = static_cast<uint32_t>((static_cast<uint32_t>(result[1]) << 030) +
|
uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
|
||||||
(static_cast<uint32_t>(result[2]) << 020) +
|
(static_cast<uint32_t>(result[2]) << 020) +
|
||||||
(static_cast<uint32_t>(result[3]) << 010) +
|
(static_cast<uint32_t>(result[3]) << 010) +
|
||||||
static_cast<uint32_t>(result[4]));
|
static_cast<uint32_t>(result[4]);
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
@ -647,14 +647,14 @@ TEST_CASE("MessagePack")
|
||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xcf);
|
CHECK(result[0] == 0xcf);
|
||||||
uint64_t restored = static_cast<uint64_t>((static_cast<uint64_t>(result[1]) << 070) +
|
uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
|
||||||
(static_cast<uint64_t>(result[2]) << 060) +
|
(static_cast<uint64_t>(result[2]) << 060) +
|
||||||
(static_cast<uint64_t>(result[3]) << 050) +
|
(static_cast<uint64_t>(result[3]) << 050) +
|
||||||
(static_cast<uint64_t>(result[4]) << 040) +
|
(static_cast<uint64_t>(result[4]) << 040) +
|
||||||
(static_cast<uint64_t>(result[5]) << 030) +
|
(static_cast<uint64_t>(result[5]) << 030) +
|
||||||
(static_cast<uint64_t>(result[6]) << 020) +
|
(static_cast<uint64_t>(result[6]) << 020) +
|
||||||
(static_cast<uint64_t>(result[7]) << 010) +
|
(static_cast<uint64_t>(result[7]) << 010) +
|
||||||
static_cast<uint64_t>(result[8]));
|
static_cast<uint64_t>(result[8]);
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
|
|
|
@ -412,17 +412,17 @@ TEST_CASE("regression tests")
|
||||||
class CommaDecimalSeparator : public std::numpunct<char>
|
class CommaDecimalSeparator : public std::numpunct<char>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
char do_decimal_point() const
|
char do_decimal_point() const override
|
||||||
{
|
{
|
||||||
return ',';
|
return ',';
|
||||||
}
|
}
|
||||||
|
|
||||||
char do_thousands_sep() const
|
char do_thousands_sep() const override
|
||||||
{
|
{
|
||||||
return '.';
|
return '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string do_grouping() const
|
std::string do_grouping() const override
|
||||||
{
|
{
|
||||||
return "\03";
|
return "\03";
|
||||||
}
|
}
|
||||||
|
@ -755,7 +755,7 @@ TEST_CASE("regression tests")
|
||||||
};
|
};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec),
|
CHECK_THROWS_WITH(json::from_cbor(vec),
|
||||||
"[json.exception.parse_error.110] parse error at 137: cannot read 1 bytes from vector");
|
"[json.exception.parse_error.113] parse error at 2: expected a CBOR string; last byte: 0x98");
|
||||||
|
|
||||||
// related test case: nonempty UTF-8 string (indefinite length)
|
// related test case: nonempty UTF-8 string (indefinite length)
|
||||||
std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61};
|
std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61};
|
||||||
|
@ -808,7 +808,7 @@ TEST_CASE("regression tests")
|
||||||
};
|
};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec1),
|
CHECK_THROWS_WITH(json::from_cbor(vec1),
|
||||||
"[json.exception.parse_error.110] parse error at 49: cannot read 4 bytes from vector");
|
"[json.exception.parse_error.113] parse error at 13: expected a CBOR string; last byte: 0xb4");
|
||||||
|
|
||||||
// related test case: double-precision
|
// related test case: double-precision
|
||||||
std::vector<uint8_t> vec2
|
std::vector<uint8_t> vec2
|
||||||
|
@ -822,7 +822,7 @@ TEST_CASE("regression tests")
|
||||||
};
|
};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec2),
|
CHECK_THROWS_WITH(json::from_cbor(vec2),
|
||||||
"[json.exception.parse_error.110] parse error at 49: cannot read 8 bytes from vector");
|
"[json.exception.parse_error.113] parse error at 13: expected a CBOR string; last byte: 0xb4");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)")
|
SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)")
|
||||||
|
|
Loading…
Reference in a new issue