mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 08:18:11 +00:00
AK: Allow exponents in JSON double values
This is required for ECMA-404 compliance, but probably not for serenity itself.
This commit is contained in:
parent
68c6161f25
commit
75ebcf6b4a
2 changed files with 55 additions and 8 deletions
|
@ -190,6 +190,7 @@ ErrorOr<JsonValue> JsonParser::parse_number()
|
||||||
JsonValue value;
|
JsonValue value;
|
||||||
Vector<char, 128> number_buffer;
|
Vector<char, 128> number_buffer;
|
||||||
Vector<char, 128> fraction_buffer;
|
Vector<char, 128> fraction_buffer;
|
||||||
|
Vector<char, 128> exponent_buffer;
|
||||||
|
|
||||||
bool is_double = false;
|
bool is_double = false;
|
||||||
bool all_zero = true;
|
bool all_zero = true;
|
||||||
|
@ -231,6 +232,30 @@ ErrorOr<JsonValue> JsonParser::parse_number()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef KERNEL
|
||||||
|
if (peek() == 'e' || peek() == 'E') {
|
||||||
|
// Force it to be a double
|
||||||
|
is_double = true;
|
||||||
|
++m_index;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
char ch = peek();
|
||||||
|
if (ch == '.')
|
||||||
|
return Error::from_string_literal("JsonParser: Error while parsing number");
|
||||||
|
if (ch == '-' || ch == '+' || (ch >= '0' && ch <= '9')) {
|
||||||
|
exponent_buffer.append(ch);
|
||||||
|
|
||||||
|
++m_index;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exponent_buffer.is_empty())
|
||||||
|
return Error::from_string_literal("JsonParser: Error while parsing number");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
StringView number_string(number_buffer.data(), number_buffer.size());
|
StringView number_string(number_buffer.data(), number_buffer.size());
|
||||||
|
|
||||||
#ifndef KERNEL
|
#ifndef KERNEL
|
||||||
|
@ -250,16 +275,29 @@ ErrorOr<JsonValue> JsonParser::parse_number()
|
||||||
return Error::from_string_literal("JsonParser: Error while parsing number");
|
return Error::from_string_literal("JsonParser: Error while parsing number");
|
||||||
whole = number.value();
|
whole = number.value();
|
||||||
}
|
}
|
||||||
|
double number_value = whole;
|
||||||
|
|
||||||
StringView fraction_string(fraction_buffer.data(), fraction_buffer.size());
|
if (!fraction_buffer.is_empty()) {
|
||||||
auto fraction_string_uint = fraction_string.to_uint<u64>();
|
StringView fraction_string(fraction_buffer.data(), fraction_buffer.size());
|
||||||
if (!fraction_string_uint.has_value())
|
auto fraction_string_uint = fraction_string.to_uint<u64>();
|
||||||
return Error::from_string_literal("JsonParser: Error while parsing number");
|
if (!fraction_string_uint.has_value())
|
||||||
auto fraction = static_cast<double>(fraction_string_uint.value());
|
return Error::from_string_literal("JsonParser: Error while parsing number");
|
||||||
double sign = (whole < 0) ? -1 : 1;
|
auto fraction = static_cast<double>(fraction_string_uint.value());
|
||||||
|
double sign = (whole < 0) ? -1 : 1;
|
||||||
|
auto divider = pow(10.0, static_cast<double>(fraction_buffer.size()));
|
||||||
|
number_value += sign * (fraction / divider);
|
||||||
|
}
|
||||||
|
|
||||||
auto divider = pow(10.0, static_cast<double>(fraction_buffer.size()));
|
if (exponent_buffer.size() > 0) {
|
||||||
value = JsonValue((double)whole + sign * (fraction / divider));
|
StringView exponent_string(exponent_buffer.data(), exponent_buffer.size());
|
||||||
|
auto exponent_string_uint = exponent_string.to_int();
|
||||||
|
if (!exponent_string_uint.has_value())
|
||||||
|
return Error::from_string_literal("JsonParser: Error while parsing number");
|
||||||
|
double exponent = pow(10.0, static_cast<double>(exponent_string_uint.value()));
|
||||||
|
number_value *= exponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = JsonValue(number_value);
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
auto to_unsigned_result = number_string.to_uint<u64>();
|
auto to_unsigned_result = number_string.to_uint<u64>();
|
||||||
|
|
|
@ -134,3 +134,12 @@ TEST_CASE(json_parse_long_decimals)
|
||||||
auto value = JsonValue::from_string("1644452550.6489999294281"sv);
|
auto value = JsonValue::from_string("1644452550.6489999294281"sv);
|
||||||
EXPECT_EQ(value.value().as_double(), 1644452550.6489999294281);
|
EXPECT_EQ(value.value().as_double(), 1644452550.6489999294281);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(json_parse_number_with_exponent)
|
||||||
|
{
|
||||||
|
auto value_without_fraction = JsonValue::from_string("10e5"sv);
|
||||||
|
EXPECT_EQ(value_without_fraction.value().as_double(), 1000000.0);
|
||||||
|
|
||||||
|
auto value_with_fraction = JsonValue::from_string("10.5e5"sv);
|
||||||
|
EXPECT_EQ(value_with_fraction.value().as_double(), 1050000.0);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue