⚗️ add Hedley annotations

This commit is contained in:
Niels Lohmann 2019-06-30 22:14:02 +02:00
parent 9a775bcb14
commit 1720bfedd1
No known key found for this signature in database
GPG key ID: 7F3CEA63AE251B69
19 changed files with 3689 additions and 642 deletions

View file

@ -66,6 +66,7 @@ class binary_reader
@return
*/
HEDLEY_NON_NULL(3)
bool sax_parse(const input_format_t format,
json_sax_t* sax_,
const bool strict = true)
@ -107,7 +108,7 @@ class binary_reader
get();
}
if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
if (HEDLEY_UNLIKELY(current != std::char_traits<char>::eof()))
{
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")));
@ -143,12 +144,12 @@ class binary_reader
std::int32_t document_size;
get_number<std::int32_t, true>(input_format_t::bson, document_size);
if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
if (HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
{
return false;
}
if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
if (HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
{
return false;
}
@ -169,7 +170,7 @@ class binary_reader
while (true)
{
get();
if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
if (HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
{
return false;
}
@ -197,7 +198,7 @@ class binary_reader
template<typename NumberType>
bool get_bson_string(const NumberType len, string_t& result)
{
if (JSON_UNLIKELY(len < 1))
if (HEDLEY_UNLIKELY(len < 1))
{
auto last_token = get_token_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")));
@ -292,13 +293,13 @@ class binary_reader
string_t key;
while (int element_type = get())
{
if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
if (HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
{
return false;
}
const std::size_t element_type_parse_position = chars_read;
if (JSON_UNLIKELY(not get_bson_cstr(key)))
if (HEDLEY_UNLIKELY(not get_bson_cstr(key)))
{
return false;
}
@ -308,7 +309,7 @@ class binary_reader
return false;
}
if (JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
if (HEDLEY_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
{
return false;
}
@ -329,12 +330,12 @@ class binary_reader
std::int32_t document_size;
get_number<std::int32_t, true>(input_format_t::bson, document_size);
if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
if (HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
{
return false;
}
if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
if (HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
{
return false;
}
@ -619,12 +620,12 @@ class binary_reader
case 0xF9: // Half-Precision Float (two-byte IEEE 754)
{
const int byte1_raw = get();
if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
if (HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
{
return false;
}
const int byte2_raw = get();
if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
if (HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
{
return false;
}
@ -697,7 +698,7 @@ class binary_reader
*/
bool get_cbor_string(string_t& result)
{
if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
if (HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
{
return false;
}
@ -786,7 +787,7 @@ class binary_reader
*/
bool get_cbor_array(const std::size_t len)
{
if (JSON_UNLIKELY(not sax->start_array(len)))
if (HEDLEY_UNLIKELY(not sax->start_array(len)))
{
return false;
}
@ -795,7 +796,7 @@ class binary_reader
{
for (std::size_t i = 0; i < len; ++i)
{
if (JSON_UNLIKELY(not parse_cbor_internal()))
if (HEDLEY_UNLIKELY(not parse_cbor_internal()))
{
return false;
}
@ -805,7 +806,7 @@ class binary_reader
{
while (get() != 0xFF)
{
if (JSON_UNLIKELY(not parse_cbor_internal(false)))
if (HEDLEY_UNLIKELY(not parse_cbor_internal(false)))
{
return false;
}
@ -822,7 +823,7 @@ class binary_reader
*/
bool get_cbor_object(const std::size_t len)
{
if (JSON_UNLIKELY(not sax->start_object(len)))
if (HEDLEY_UNLIKELY(not sax->start_object(len)))
{
return false;
}
@ -833,12 +834,12 @@ class binary_reader
for (std::size_t i = 0; i < len; ++i)
{
get();
if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
if (HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
{
return false;
}
if (JSON_UNLIKELY(not parse_cbor_internal()))
if (HEDLEY_UNLIKELY(not parse_cbor_internal()))
{
return false;
}
@ -849,12 +850,12 @@ class binary_reader
{
while (get() != 0xFF)
{
if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
if (HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
{
return false;
}
if (JSON_UNLIKELY(not parse_cbor_internal()))
if (HEDLEY_UNLIKELY(not parse_cbor_internal()))
{
return false;
}
@ -1243,7 +1244,7 @@ class binary_reader
*/
bool get_msgpack_string(string_t& result)
{
if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
if (HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
{
return false;
}
@ -1319,14 +1320,14 @@ class binary_reader
*/
bool get_msgpack_array(const std::size_t len)
{
if (JSON_UNLIKELY(not sax->start_array(len)))
if (HEDLEY_UNLIKELY(not sax->start_array(len)))
{
return false;
}
for (std::size_t i = 0; i < len; ++i)
{
if (JSON_UNLIKELY(not parse_msgpack_internal()))
if (HEDLEY_UNLIKELY(not parse_msgpack_internal()))
{
return false;
}
@ -1341,7 +1342,7 @@ class binary_reader
*/
bool get_msgpack_object(const std::size_t len)
{
if (JSON_UNLIKELY(not sax->start_object(len)))
if (HEDLEY_UNLIKELY(not sax->start_object(len)))
{
return false;
}
@ -1350,12 +1351,12 @@ class binary_reader
for (std::size_t i = 0; i < len; ++i)
{
get();
if (JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
if (HEDLEY_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
{
return false;
}
if (JSON_UNLIKELY(not parse_msgpack_internal()))
if (HEDLEY_UNLIKELY(not parse_msgpack_internal()))
{
return false;
}
@ -1402,7 +1403,7 @@ class binary_reader
get(); // TODO(niels): may we ignore N here?
}
if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
if (HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
{
return false;
}
@ -1456,7 +1457,7 @@ class binary_reader
case 'U':
{
std::uint8_t number;
if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
if (HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{
return false;
}
@ -1467,7 +1468,7 @@ class binary_reader
case 'i':
{
std::int8_t number;
if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
if (HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{
return false;
}
@ -1478,7 +1479,7 @@ class binary_reader
case 'I':
{
std::int16_t number;
if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
if (HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{
return false;
}
@ -1489,7 +1490,7 @@ class binary_reader
case 'l':
{
std::int32_t number;
if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
if (HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{
return false;
}
@ -1500,7 +1501,7 @@ class binary_reader
case 'L':
{
std::int64_t number;
if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
if (HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{
return false;
}
@ -1536,15 +1537,15 @@ class binary_reader
if (current == '$')
{
result.second = get(); // must not ignore 'N', because 'N' maybe the type
if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
if (HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
{
return false;
}
get_ignore_noop();
if (JSON_UNLIKELY(current != '#'))
if (HEDLEY_UNLIKELY(current != '#'))
{
if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
if (HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
{
return false;
}
@ -1627,11 +1628,11 @@ class binary_reader
case 'C': // char
{
get();
if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
if (HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
{
return false;
}
if (JSON_UNLIKELY(current > 127))
if (HEDLEY_UNLIKELY(current > 127))
{
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")));
@ -1666,14 +1667,14 @@ class binary_reader
bool get_ubjson_array()
{
std::pair<std::size_t, int> size_and_type;
if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
if (HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
{
return false;
}
if (size_and_type.first != string_t::npos)
{
if (JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
if (HEDLEY_UNLIKELY(not sax->start_array(size_and_type.first)))
{
return false;
}
@ -1684,7 +1685,7 @@ class binary_reader
{
for (std::size_t i = 0; i < size_and_type.first; ++i)
{
if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
if (HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
{
return false;
}
@ -1695,7 +1696,7 @@ class binary_reader
{
for (std::size_t i = 0; i < size_and_type.first; ++i)
{
if (JSON_UNLIKELY(not parse_ubjson_internal()))
if (HEDLEY_UNLIKELY(not parse_ubjson_internal()))
{
return false;
}
@ -1704,14 +1705,14 @@ class binary_reader
}
else
{
if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
if (HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
{
return false;
}
while (current != ']')
{
if (JSON_UNLIKELY(not parse_ubjson_internal(false)))
if (HEDLEY_UNLIKELY(not parse_ubjson_internal(false)))
{
return false;
}
@ -1728,7 +1729,7 @@ class binary_reader
bool get_ubjson_object()
{
std::pair<std::size_t, int> size_and_type;
if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
if (HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
{
return false;
}
@ -1736,7 +1737,7 @@ class binary_reader
string_t key;
if (size_and_type.first != string_t::npos)
{
if (JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
if (HEDLEY_UNLIKELY(not sax->start_object(size_and_type.first)))
{
return false;
}
@ -1745,11 +1746,11 @@ class binary_reader
{
for (std::size_t i = 0; i < size_and_type.first; ++i)
{
if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
if (HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
{
return false;
}
if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
if (HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
{
return false;
}
@ -1760,11 +1761,11 @@ class binary_reader
{
for (std::size_t i = 0; i < size_and_type.first; ++i)
{
if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
if (HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
{
return false;
}
if (JSON_UNLIKELY(not parse_ubjson_internal()))
if (HEDLEY_UNLIKELY(not parse_ubjson_internal()))
{
return false;
}
@ -1774,18 +1775,18 @@ class binary_reader
}
else
{
if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
if (HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
{
return false;
}
while (current != '}')
{
if (JSON_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
if (HEDLEY_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
{
return false;
}
if (JSON_UNLIKELY(not parse_ubjson_internal()))
if (HEDLEY_UNLIKELY(not parse_ubjson_internal()))
{
return false;
}
@ -1851,7 +1852,7 @@ class binary_reader
for (std::size_t i = 0; i < sizeof(NumberType); ++i)
{
get();
if (JSON_UNLIKELY(not unexpect_eof(format, "number")))
if (HEDLEY_UNLIKELY(not unexpect_eof(format, "number")))
{
return false;
}
@ -1895,7 +1896,7 @@ class binary_reader
std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
{
get();
if (JSON_UNLIKELY(not unexpect_eof(format, "string")))
if (HEDLEY_UNLIKELY(not unexpect_eof(format, "string")))
{
success = false;
}
@ -1909,9 +1910,10 @@ class binary_reader
@param[in] context further context information (for diagnostics)
@return whether the last read character is not EOF
*/
HEDLEY_NON_NULL(3)
bool unexpect_eof(const input_format_t format, const char* context) const
{
if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
if (HEDLEY_UNLIKELY(current == std::char_traits<char>::eof()))
{
return sax->parse_error(chars_read, "<end of file>",
parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));

View file

@ -55,6 +55,7 @@ Input adapter for stdio file access. This adapter read only 1 byte and do not us
class file_input_adapter : public input_adapter_protocol
{
public:
HEDLEY_NON_NULL(2)
explicit file_input_adapter(std::FILE* f) noexcept
: m_file(f)
{}
@ -130,6 +131,7 @@ class input_stream_adapter : public input_adapter_protocol
class input_buffer_adapter : public input_adapter_protocol
{
public:
HEDLEY_NON_NULL(2)
input_buffer_adapter(const char* b, const std::size_t l) noexcept
: cursor(b), limit(b + l)
{}
@ -143,7 +145,7 @@ class input_buffer_adapter : public input_adapter_protocol
std::char_traits<char>::int_type get_character() noexcept override
{
if (JSON_LIKELY(cursor < limit))
if (HEDLEY_LIKELY(cursor < limit))
{
return std::char_traits<char>::to_int_type(*(cursor++));
}
@ -333,6 +335,7 @@ class input_adapter
{
public:
// native support
HEDLEY_NON_NULL(2)
input_adapter(std::FILE* file)
: ia(std::make_shared<file_input_adapter>(file)) {}
/// input adapter for input stream
@ -401,7 +404,7 @@ class input_adapter
"each element in the iterator range must have the size of 1 byte");
const auto len = static_cast<size_t>(std::distance(first, last));
if (JSON_LIKELY(len > 0))
if (HEDLEY_LIKELY(len > 0))
{
// there is at least one element: use the address of first
ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);

View file

@ -206,7 +206,7 @@ class json_sax_dom_parser
{
ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
if (HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
{
JSON_THROW(out_of_range::create(408,
"excessive object size: " + std::to_string(len)));
@ -232,7 +232,7 @@ class json_sax_dom_parser
{
ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
if (HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
{
JSON_THROW(out_of_range::create(408,
"excessive array size: " + std::to_string(len)));
@ -288,6 +288,7 @@ class json_sax_dom_parser
object to which we can add elements
*/
template<typename Value>
HEDLEY_RETURNS_NON_NULL
BasicJsonType* handle_value(Value&& v)
{
if (ref_stack.empty())
@ -394,7 +395,7 @@ class json_sax_dom_callback_parser
ref_stack.push_back(val.second);
// check object limit
if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
if (ref_stack.back() and HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
{
JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
}
@ -457,7 +458,7 @@ class json_sax_dom_callback_parser
ref_stack.push_back(val.second);
// check array limit
if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
if (ref_stack.back() and HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
{
JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
}

View file

@ -59,6 +59,7 @@ class lexer
};
/// return name of values of type token_type (only used for errors)
HEDLEY_RETURNS_NON_NULL
static const char* token_type_name(const token_type t) noexcept
{
switch (t)
@ -200,7 +201,7 @@ class lexer
for (auto range = ranges.begin(); range != ranges.end(); ++range)
{
get();
if (JSON_LIKELY(*range <= current and current <= *(++range)))
if (HEDLEY_LIKELY(*range <= current and current <= *(++range)))
{
add(current);
}
@ -299,7 +300,7 @@ class lexer
const int codepoint1 = get_codepoint();
int codepoint = codepoint1; // start with codepoint1
if (JSON_UNLIKELY(codepoint1 == -1))
if (HEDLEY_UNLIKELY(codepoint1 == -1))
{
error_message = "invalid string: '\\u' must be followed by 4 hex digits";
return token_type::parse_error;
@ -309,18 +310,18 @@ class lexer
if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
{
// expect next \uxxxx entry
if (JSON_LIKELY(get() == '\\' and get() == 'u'))
if (HEDLEY_LIKELY(get() == '\\' and get() == 'u'))
{
const int codepoint2 = get_codepoint();
if (JSON_UNLIKELY(codepoint2 == -1))
if (HEDLEY_UNLIKELY(codepoint2 == -1))
{
error_message = "invalid string: '\\u' must be followed by 4 hex digits";
return token_type::parse_error;
}
// check if codepoint2 is a low surrogate
if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
if (HEDLEY_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
{
// overwrite codepoint
codepoint = static_cast<int>(
@ -347,7 +348,7 @@ class lexer
}
else
{
if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
if (HEDLEY_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
{
error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
return token_type::parse_error;
@ -722,7 +723,7 @@ class lexer
case 0xDE:
case 0xDF:
{
if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
if (HEDLEY_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
{
return token_type::parse_error;
}
@ -732,7 +733,7 @@ class lexer
// U+0800..U+0FFF: bytes E0 A0..BF 80..BF
case 0xE0:
{
if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
if (HEDLEY_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
{
return token_type::parse_error;
}
@ -756,7 +757,7 @@ class lexer
case 0xEE:
case 0xEF:
{
if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
if (HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
{
return token_type::parse_error;
}
@ -766,7 +767,7 @@ class lexer
// U+D000..U+D7FF: bytes ED 80..9F 80..BF
case 0xED:
{
if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
if (HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
{
return token_type::parse_error;
}
@ -776,7 +777,7 @@ class lexer
// U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
case 0xF0:
{
if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
if (HEDLEY_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
{
return token_type::parse_error;
}
@ -788,7 +789,7 @@ class lexer
case 0xF2:
case 0xF3:
{
if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
if (HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
{
return token_type::parse_error;
}
@ -798,7 +799,7 @@ class lexer
// U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
case 0xF4:
{
if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
if (HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
{
return token_type::parse_error;
}
@ -815,16 +816,19 @@ class lexer
}
}
HEDLEY_NON_NULL(2)
static void strtof(float& f, const char* str, char** endptr) noexcept
{
f = std::strtof(str, endptr);
}
HEDLEY_NON_NULL(2)
static void strtof(double& f, const char* str, char** endptr) noexcept
{
f = std::strtod(str, endptr);
}
HEDLEY_NON_NULL(2)
static void strtof(long double& f, const char* str, char** endptr) noexcept
{
f = std::strtold(str, endptr);
@ -1200,13 +1204,14 @@ scan_number_done:
@param[in] length the length of the passed literal text
@param[in] return_type the token type to return on success
*/
HEDLEY_NON_NULL(2)
token_type scan_literal(const char* literal_text, const std::size_t length,
token_type return_type)
{
assert(current == literal_text[0]);
for (std::size_t i = 1; i < length; ++i)
{
if (JSON_UNLIKELY(get() != literal_text[i]))
if (HEDLEY_UNLIKELY(get() != literal_text[i]))
{
error_message = "invalid literal";
return token_type::parse_error;
@ -1252,7 +1257,7 @@ scan_number_done:
current = ia->get_character();
}
if (JSON_LIKELY(current != std::char_traits<char>::eof()))
if (HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
{
token_string.push_back(std::char_traits<char>::to_char_type(current));
}
@ -1293,7 +1298,7 @@ scan_number_done:
--position.chars_read_current_line;
}
if (JSON_LIKELY(current != std::char_traits<char>::eof()))
if (HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
{
assert(not token_string.empty());
token_string.pop_back();
@ -1372,6 +1377,7 @@ scan_number_done:
}
/// return syntax error message
HEDLEY_RETURNS_NON_NULL
constexpr const char* get_error_message() const noexcept
{
return error_message;

View file

@ -147,6 +147,7 @@ class parser
}
template <typename SAX>
HEDLEY_NON_NULL(2)
bool sax_parse(SAX* sax, const bool strict = true)
{
(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
@ -166,6 +167,7 @@ class parser
private:
template <typename SAX>
HEDLEY_NON_NULL(2)
bool sax_parse_internal(SAX* sax)
{
// stack to remember the hierarchy of structured values we are parsing
@ -183,7 +185,7 @@ class parser
{
case token_type::begin_object:
{
if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
if (HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
{
return false;
}
@ -191,7 +193,7 @@ class parser
// closing } -> we are done
if (get_token() == token_type::end_object)
{
if (JSON_UNLIKELY(not sax->end_object()))
if (HEDLEY_UNLIKELY(not sax->end_object()))
{
return false;
}
@ -199,20 +201,20 @@ class parser
}
// parse key
if (JSON_UNLIKELY(last_token != token_type::value_string))
if (HEDLEY_UNLIKELY(last_token != token_type::value_string))
{
return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::value_string, "object key")));
}
if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
if (HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
{
return false;
}
// parse separator (:)
if (JSON_UNLIKELY(get_token() != token_type::name_separator))
if (HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
{
return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(),
@ -230,7 +232,7 @@ class parser
case token_type::begin_array:
{
if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
if (HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
{
return false;
}
@ -238,7 +240,7 @@ class parser
// closing ] -> we are done
if (get_token() == token_type::end_array)
{
if (JSON_UNLIKELY(not sax->end_array()))
if (HEDLEY_UNLIKELY(not sax->end_array()))
{
return false;
}
@ -256,14 +258,14 @@ class parser
{
const auto res = m_lexer.get_number_float();
if (JSON_UNLIKELY(not std::isfinite(res)))
if (HEDLEY_UNLIKELY(not std::isfinite(res)))
{
return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(),
out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
}
if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
if (HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
{
return false;
}
@ -273,7 +275,7 @@ class parser
case token_type::literal_false:
{
if (JSON_UNLIKELY(not sax->boolean(false)))
if (HEDLEY_UNLIKELY(not sax->boolean(false)))
{
return false;
}
@ -282,7 +284,7 @@ class parser
case token_type::literal_null:
{
if (JSON_UNLIKELY(not sax->null()))
if (HEDLEY_UNLIKELY(not sax->null()))
{
return false;
}
@ -291,7 +293,7 @@ class parser
case token_type::literal_true:
{
if (JSON_UNLIKELY(not sax->boolean(true)))
if (HEDLEY_UNLIKELY(not sax->boolean(true)))
{
return false;
}
@ -300,7 +302,7 @@ class parser
case token_type::value_integer:
{
if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
if (HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
{
return false;
}
@ -309,7 +311,7 @@ class parser
case token_type::value_string:
{
if (JSON_UNLIKELY(not sax->string(m_lexer.get_string())))
if (HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string())))
{
return false;
}
@ -318,7 +320,7 @@ class parser
case token_type::value_unsigned:
{
if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
if (HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
{
return false;
}
@ -366,9 +368,9 @@ class parser
}
// closing ]
if (JSON_LIKELY(last_token == token_type::end_array))
if (HEDLEY_LIKELY(last_token == token_type::end_array))
{
if (JSON_UNLIKELY(not sax->end_array()))
if (HEDLEY_UNLIKELY(not sax->end_array()))
{
return false;
}
@ -394,7 +396,7 @@ class parser
if (get_token() == token_type::value_separator)
{
// parse key
if (JSON_UNLIKELY(get_token() != token_type::value_string))
if (HEDLEY_UNLIKELY(get_token() != token_type::value_string))
{
return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(),
@ -402,13 +404,13 @@ class parser
exception_message(token_type::value_string, "object key")));
}
if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
if (HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
{
return false;
}
// parse separator (:)
if (JSON_UNLIKELY(get_token() != token_type::name_separator))
if (HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
{
return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(),
@ -422,9 +424,9 @@ class parser
}
// closing }
if (JSON_LIKELY(last_token == token_type::end_object))
if (HEDLEY_LIKELY(last_token == token_type::end_object))
{
if (JSON_UNLIKELY(not sax->end_object()))
if (HEDLEY_UNLIKELY(not sax->end_object()))
{
return false;
}