commit
543dcee3a7
8 changed files with 161 additions and 140 deletions
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 \
|
||||||
|
|
|
@ -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")));
|
||||||
|
@ -180,7 +182,7 @@ class binary_reader
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*out++ = static_cast<char>(current);
|
*out++ = static_cast<typename string_t::value_type>(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -206,7 +208,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) and get() != std::char_traits<char>::eof();
|
return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char_type>::eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -245,7 +247,7 @@ 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)
|
||||||
|
@ -327,7 +329,7 @@ class binary_reader
|
||||||
{
|
{
|
||||||
string_t key;
|
string_t key;
|
||||||
|
|
||||||
while (int element_type = get())
|
while (auto element_type = get())
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
|
if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
|
||||||
{
|
{
|
||||||
|
@ -395,7 +397,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)
|
||||||
|
@ -690,12 +692,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(not unexpect_eof(input_format_t::cbor, "number")))
|
if (JSON_HEDLEY_UNLIKELY(not 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(not unexpect_eof(input_format_t::cbor, "number")))
|
if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -1048,7 +1050,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
|
||||||
|
@ -1825,7 +1827,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 +1868,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
|
||||||
|
@ -1935,7 +1937,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 +1966,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(not get_ubjson_size_type(size_and_type)))
|
if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -2026,7 +2028,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(not get_ubjson_size_type(size_and_type)))
|
if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -2108,11 +2110,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 +2123,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 +2203,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 +2248,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 +2308,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;
|
||||||
|
|
|
@ -189,23 +189,23 @@ struct wide_string_input_helper<BaseInputAdapter, 4>
|
||||||
}
|
}
|
||||||
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
|
||||||
|
@ -285,6 +285,8 @@ template<typename BaseInputAdapter, typename WideCharType>
|
||||||
class wide_string_input_adapter
|
class wide_string_input_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using char_type = char;
|
||||||
|
|
||||||
wide_string_input_adapter(BaseInputAdapter base)
|
wide_string_input_adapter(BaseInputAdapter base)
|
||||||
: base_adapter(base) {}
|
: base_adapter(base) {}
|
||||||
|
|
||||||
|
|
|
@ -106,12 +106,14 @@ 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)
|
||||||
: ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
|
: ia(std::move(adapter)), decimal_point_char(static_cast<char_type>(get_decimal_point())) {}
|
||||||
|
|
||||||
// delete because of pointer members
|
// delete because of pointer members
|
||||||
lexer(const lexer&) = delete;
|
lexer(const lexer&) = delete;
|
||||||
|
@ -201,7 +203,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 or ranges.size() == 4 or ranges.size() == 6);
|
assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
|
||||||
add(current);
|
add(current);
|
||||||
|
@ -252,7 +254,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 +372,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;
|
||||||
|
@ -1213,13 +1215,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(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 +1239,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 +1252,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 +1267,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 +1308,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(not token_string.empty());
|
assert(not token_string.empty());
|
||||||
token_string.pop_back();
|
token_string.pop_back();
|
||||||
|
@ -1314,9 +1316,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 +1379,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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1447,11 +1449,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 +1485,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
|
||||||
|
@ -1489,7 +1500,7 @@ scan_number_done:
|
||||||
InputAdapterType ia;
|
InputAdapterType ia;
|
||||||
|
|
||||||
/// 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 +1509,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 +1523,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_type decimal_point_char = '.';
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
|
|
@ -4764,7 +4764,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 +4773,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();
|
||||||
|
@ -6530,7 +6530,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;
|
||||||
|
@ -6743,9 +6743,6 @@ class basic_json
|
||||||
: 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 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
|
||||||
|
@ -6754,7 +6751,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);
|
||||||
|
|
|
@ -4611,23 +4611,23 @@ struct wide_string_input_helper<BaseInputAdapter, 4>
|
||||||
}
|
}
|
||||||
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
|
||||||
|
@ -4707,6 +4707,8 @@ template<typename BaseInputAdapter, typename WideCharType>
|
||||||
class wide_string_input_adapter
|
class wide_string_input_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using char_type = char;
|
||||||
|
|
||||||
wide_string_input_adapter(BaseInputAdapter base)
|
wide_string_input_adapter(BaseInputAdapter base)
|
||||||
: base_adapter(base) {}
|
: base_adapter(base) {}
|
||||||
|
|
||||||
|
@ -5786,6 +5788,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:
|
||||||
/*!
|
/*!
|
||||||
|
@ -5854,7 +5858,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")));
|
||||||
|
@ -5912,7 +5916,7 @@ class binary_reader
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*out++ = static_cast<char>(current);
|
*out++ = static_cast<typename string_t::value_type>(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -5938,7 +5942,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) and get() != std::char_traits<char>::eof();
|
return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char_type>::eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -5977,7 +5981,7 @@ 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)
|
||||||
|
@ -6059,7 +6063,7 @@ class binary_reader
|
||||||
{
|
{
|
||||||
string_t key;
|
string_t key;
|
||||||
|
|
||||||
while (int element_type = get())
|
while (auto element_type = get())
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
|
if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
|
||||||
{
|
{
|
||||||
|
@ -6127,7 +6131,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)
|
||||||
|
@ -6422,12 +6426,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(not unexpect_eof(input_format_t::cbor, "number")))
|
if (JSON_HEDLEY_UNLIKELY(not 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(not unexpect_eof(input_format_t::cbor, "number")))
|
if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -6780,7 +6784,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
|
||||||
|
@ -7557,7 +7561,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
|
||||||
|
@ -7598,11 +7602,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
|
||||||
|
@ -7667,7 +7671,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7696,7 +7700,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(not get_ubjson_size_type(size_and_type)))
|
if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -7758,7 +7762,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(not get_ubjson_size_type(size_and_type)))
|
if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -7840,11 +7844,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();
|
||||||
|
@ -7853,7 +7857,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
|
||||||
{
|
{
|
||||||
|
@ -7933,7 +7937,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;
|
||||||
}
|
}
|
||||||
|
@ -7978,7 +7982,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)));
|
||||||
|
@ -8038,7 +8042,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;
|
||||||
|
@ -8166,12 +8170,14 @@ 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)
|
||||||
: ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
|
: ia(std::move(adapter)), decimal_point_char(static_cast<char_type>(get_decimal_point())) {}
|
||||||
|
|
||||||
// delete because of pointer members
|
// delete because of pointer members
|
||||||
lexer(const lexer&) = delete;
|
lexer(const lexer&) = delete;
|
||||||
|
@ -8261,7 +8267,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 or ranges.size() == 4 or ranges.size() == 6);
|
assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
|
||||||
add(current);
|
add(current);
|
||||||
|
@ -8312,7 +8318,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;
|
||||||
|
@ -8430,28 +8436,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;
|
||||||
|
@ -9273,13 +9279,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(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;
|
||||||
|
@ -9297,7 +9303,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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -9310,7 +9316,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;
|
||||||
|
@ -9325,9 +9331,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')
|
||||||
|
@ -9366,7 +9372,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(not token_string.empty());
|
assert(not token_string.empty());
|
||||||
token_string.pop_back();
|
token_string.pop_back();
|
||||||
|
@ -9374,9 +9380,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:
|
||||||
|
@ -9437,7 +9443,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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9507,11 +9513,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 '\"':
|
||||||
|
@ -9534,7 +9549,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
|
||||||
|
@ -9549,7 +9564,7 @@ scan_number_done:
|
||||||
InputAdapterType ia;
|
InputAdapterType ia;
|
||||||
|
|
||||||
/// 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;
|
||||||
|
@ -9558,7 +9573,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 {};
|
||||||
|
@ -9572,7 +9587,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_type decimal_point_char = '.';
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
@ -20527,7 +20542,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();
|
||||||
|
@ -20536,7 +20551,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();
|
||||||
|
@ -22293,7 +22308,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;
|
||||||
|
@ -22506,9 +22521,6 @@ class basic_json
|
||||||
: 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 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
|
||||||
|
@ -22517,7 +22529,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);
|
||||||
|
|
|
@ -1587,7 +1587,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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,7 +87,6 @@ TEST_CASE("Custom iterator")
|
||||||
using reference = const char&;
|
using reference = const char&;
|
||||||
using iterator_category = std::input_iterator_tag;
|
using iterator_category = std::input_iterator_tag;
|
||||||
|
|
||||||
|
|
||||||
MyIterator& operator++()
|
MyIterator& operator++()
|
||||||
{
|
{
|
||||||
++ptr;
|
++ptr;
|
||||||
|
@ -117,6 +116,4 @@ TEST_CASE("Custom iterator")
|
||||||
CHECK(as_json.at(3) == 4);
|
CHECK(as_json.at(3) == 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue