🔨 some cleanup

This commit is contained in:
Niels Lohmann 2017-03-28 20:08:08 +02:00
parent 1e495945f1
commit 6a6fbea62c
No known key found for this signature in database
GPG key ID: 7F3CEA63AE251B69

View file

@ -10443,7 +10443,7 @@ class basic_json
std::string read(size_t offset, size_t length) override std::string read(size_t offset, size_t length) override
{ {
// avoid reading too many characters // avoid reading too many characters
const size_t max_length = static_cast<size_t>(limit-start); const size_t max_length = static_cast<size_t>(limit - start);
return std::string(start + offset, std::min({length, max_length})); return std::string(start + offset, std::min({length, max_length}));
} }
@ -10462,9 +10462,9 @@ class basic_json
literal_false, ///< the `false` literal literal_false, ///< the `false` literal
literal_null, ///< the `null` literal literal_null, ///< the `null` literal
value_string, ///< a string -- use get_string() for actual value value_string, ///< a string -- use get_string() for actual value
value_unsigned, ///< an unsigned integer -- use get_number() for actual value value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
value_integer, ///< a signed integer -- use get_number() for actual value value_integer, ///< a signed integer -- use get_number_integer() for actual value
value_float, ///< an floating point number -- use get_number() for actual value value_float, ///< an floating point number -- use get_number_float() for actual value
begin_array, ///< the character for array begin `[` begin_array, ///< the character for array begin `[`
begin_object, ///< the character for object begin `{` begin_object, ///< the character for object begin `{`
end_array, ///< the character for array end `]` end_array, ///< the character for array end `]`
@ -10476,7 +10476,7 @@ class basic_json
}; };
/// return name of values of type token_type (only used for errors) /// return name of values of type token_type (only used for errors)
static std::string token_type_name(const token_type t) static const char* token_type_name(const token_type t) noexcept
{ {
switch (t) switch (t)
{ {
@ -10563,6 +10563,7 @@ class basic_json
int codepoint = 0; int codepoint = 0;
// check the next 4 bytes
for (size_t i = 0; i < 4; ++i) for (size_t i = 0; i < 4; ++i)
{ {
const int8_t digit = ascii_to_hex[static_cast<unsigned char>(get())]; const int8_t digit = ascii_to_hex[static_cast<unsigned char>(get())];
@ -10575,6 +10576,7 @@ class basic_json
codepoint += digit; codepoint += digit;
} }
// except the last byte, result must be multiplied by 16
if (i != 3) if (i != 3)
{ {
codepoint <<= 4; codepoint <<= 4;
@ -10895,7 +10897,7 @@ class basic_json
} }
// check if code point is a high surrogate // check if code point is a high surrogate
if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF) if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
{ {
// expect next \uxxxx entry // expect next \uxxxx entry
if (JSON_LIKELY(get() == '\\' and get() == 'u')) if (JSON_LIKELY(get() == '\\' and get() == 'u'))
@ -10909,7 +10911,7 @@ class basic_json
} }
// check if codepoint2 is a low surrogate // check if codepoint2 is a low surrogate
if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF) if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
{ {
codepoint = codepoint =
// high surrogate occupies the most significant 22 bits // high surrogate occupies the most significant 22 bits
@ -10935,7 +10937,7 @@ class basic_json
} }
else else
{ {
if (JSON_UNLIKELY(codepoint1 >= 0xDC00 and codepoint1 <= 0xDFFF)) if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
{ {
error_message = "invalid string: missing high surrogate"; error_message = "invalid string: missing high surrogate";
return token_type::parse_error; return token_type::parse_error;
@ -10993,6 +10995,7 @@ class basic_json
// end // end
case 16: case 16:
{ {
// terminate yytext
add('\0'); add('\0');
--yylen; --yylen;
return token_type::value_string; return token_type::value_string;
@ -11108,15 +11111,13 @@ class basic_json
add('\0'); add('\0');
--yylen; --yylen;
// the conversion
char* endptr = nullptr;
// try to parse integers first and fall back to floats // try to parse integers first and fall back to floats
if (not has_exp and not has_point) if (not has_exp and not has_point)
{ {
errno = 0; errno = 0;
if (has_sign) if (has_sign)
{ {
char* endptr = nullptr;
const auto x = std::strtoll(yytext.data(), &endptr, 10); const auto x = std::strtoll(yytext.data(), &endptr, 10);
value_integer = static_cast<number_integer_t>(x); value_integer = static_cast<number_integer_t>(x);
if (JSON_LIKELY(errno == 0 and endptr == yytext.data() + yylen and value_integer == x)) if (JSON_LIKELY(errno == 0 and endptr == yytext.data() + yylen and value_integer == x))
@ -11126,6 +11127,7 @@ class basic_json
} }
else else
{ {
char* endptr = nullptr;
const auto x = std::strtoull(yytext.data(), &endptr, 10); const auto x = std::strtoull(yytext.data(), &endptr, 10);
value_unsigned = static_cast<number_unsigned_t>(x); value_unsigned = static_cast<number_unsigned_t>(x);
if (JSON_LIKELY(errno == 0 and endptr == yytext.data() + yylen and value_unsigned == x)) if (JSON_LIKELY(errno == 0 and endptr == yytext.data() + yylen and value_unsigned == x))
@ -11218,11 +11220,26 @@ class basic_json
} }
public: public:
constexpr size_t get_position() const constexpr size_t get_position() const noexcept
{ {
return chars_read; return chars_read;
} }
constexpr number_integer_t get_number_integer() const noexcept
{
return value_integer;
}
constexpr number_unsigned_t get_number_unsigned() const noexcept
{
return value_unsigned;
}
constexpr number_float_t get_number_float() const noexcept
{
return value_float;
}
const std::string get_string() const std::string get_string()
{ {
return std::string(yytext.data(), yylen); return std::string(yytext.data(), yylen);
@ -11252,49 +11269,11 @@ class basic_json
return ss.str(); return ss.str();
} }
const std::string& get_error_message() const const std::string& get_error_message() const noexcept
{ {
return error_message; return error_message;
} }
bool get_number(basic_json& result, const token_type token) const
{
switch (token)
{
case lexer::token_type::value_unsigned:
{
result.m_type = value_t::number_unsigned;
result.m_value = value_unsigned;
return true;
}
case lexer::token_type::value_integer:
{
result.m_type = value_t::number_integer;
result.m_value = value_integer;
return true;
}
case lexer::token_type::value_float:
{
// throw in case of infinity or NAN
if (not std::isfinite(value_float))
{
JSON_THROW(out_of_range::create(406, "number overflow parsing '" + get_token_string() + "'"));
}
result.m_type = value_t::number_float;
result.m_value = value_float;
return true;
}
default:
{
return false;
}
}
}
token_type scan() token_type scan()
{ {
// read next character and ignore whitespace // read next character and ignore whitespace
@ -11602,8 +11581,8 @@ class basic_json
case lexer::token_type::literal_null: case lexer::token_type::literal_null:
{ {
get_token();
result.m_type = value_t::null; result.m_type = value_t::null;
get_token();
break; break;
} }
@ -11616,25 +11595,47 @@ class basic_json
case lexer::token_type::literal_true: case lexer::token_type::literal_true:
{ {
get_token();
result.m_type = value_t::boolean; result.m_type = value_t::boolean;
result.m_value = true; result.m_value = true;
get_token();
break; break;
} }
case lexer::token_type::literal_false: case lexer::token_type::literal_false:
{ {
get_token();
result.m_type = value_t::boolean; result.m_type = value_t::boolean;
result.m_value = false; result.m_value = false;
get_token();
break; break;
} }
case lexer::token_type::value_unsigned: case lexer::token_type::value_unsigned:
{
result.m_type = value_t::number_unsigned;
result.m_value = m_lexer.get_number_unsigned();
get_token();
break;
}
case lexer::token_type::value_integer: case lexer::token_type::value_integer:
{
result.m_type = value_t::number_integer;
result.m_value = m_lexer.get_number_integer();
get_token();
break;
}
case lexer::token_type::value_float: case lexer::token_type::value_float:
{ {
m_lexer.get_number(result, last_token); result.m_type = value_t::number_float;
result.m_value = m_lexer.get_number_float();
// throw in case of infinity or NAN
if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float)))
{
JSON_THROW(out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
}
get_token(); get_token();
break; break;
} }
@ -11674,10 +11675,10 @@ class basic_json
} }
else else
{ {
error_msg += "unexpected " + lexer::token_type_name(last_token); error_msg += "unexpected " + std::string(lexer::token_type_name(last_token));
} }
error_msg += "; expected " + lexer::token_type_name(t); error_msg += "; expected " + std::string(lexer::token_type_name(t));
JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg)); JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
} }
} }
@ -11696,7 +11697,7 @@ class basic_json
} }
else else
{ {
error_msg += "unexpected " + lexer::token_type_name(last_token); error_msg += "unexpected " + std::string(lexer::token_type_name(last_token));
} }
JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg)); JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));