mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-09 01:29:17 +00:00
AK+Everywhere: Replace custom number parsers with fast_float
Some checks failed
CI / macOS, arm64, Sanitizer_CI, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers_CI, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer_CI, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer_CI, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Build Dev Container Image / build (push) Has been cancelled
Some checks failed
CI / macOS, arm64, Sanitizer_CI, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers_CI, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer_CI, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer_CI, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Build Dev Container Image / build (push) Has been cancelled
Our floating point number parser was based on the fast_float library: https://github.com/fastfloat/fast_float However, our implementation only supports 8-bit characters. To support UTF-16, we will need to be able to convert char16_t-based strings to numbers as well. This works out-of-the-box with fast_float. We can also use fast_float for integer parsing.
This commit is contained in:
parent
9fc3e72db2
commit
62d9a84b8d
Notes:
github-actions[bot]
2025-07-03 13:53:10 +00:00
Author: https://github.com/trflynn89
Commit: 62d9a84b8d
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5228
Reviewed-by: https://github.com/ADKaster ✅
Reviewed-by: https://github.com/shannonbooth
30 changed files with 413 additions and 3034 deletions
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include <AK/ByteString.h>
|
||||
#include <AK/CharacterTypes.h>
|
||||
#include <AK/FloatingPointStringConversions.h>
|
||||
#include <AK/MemMem.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/String.h>
|
||||
|
@ -86,167 +85,6 @@ bool matches(StringView str, StringView mask, CaseSensitivity case_sensitivity,
|
|||
return string_ptr == string_end && mask_ptr == mask_end;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Optional<T> convert_to_int(StringView str, TrimWhitespace trim_whitespace)
|
||||
{
|
||||
auto string = trim_whitespace == TrimWhitespace::Yes
|
||||
? str.trim_whitespace()
|
||||
: str;
|
||||
if (string.is_empty())
|
||||
return {};
|
||||
|
||||
T sign = 1;
|
||||
size_t i = 0;
|
||||
auto const characters = string.characters_without_null_termination();
|
||||
|
||||
if (characters[0] == '-' || characters[0] == '+') {
|
||||
if (string.length() == 1)
|
||||
return {};
|
||||
i++;
|
||||
if (characters[0] == '-')
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
T value = 0;
|
||||
for (; i < string.length(); i++) {
|
||||
if (characters[i] < '0' || characters[i] > '9')
|
||||
return {};
|
||||
|
||||
if (__builtin_mul_overflow(value, 10, &value))
|
||||
return {};
|
||||
|
||||
if (__builtin_add_overflow(value, sign * (characters[i] - '0'), &value))
|
||||
return {};
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
template Optional<i8> convert_to_int(StringView str, TrimWhitespace);
|
||||
template Optional<i16> convert_to_int(StringView str, TrimWhitespace);
|
||||
template Optional<i32> convert_to_int(StringView str, TrimWhitespace);
|
||||
template Optional<long> convert_to_int(StringView str, TrimWhitespace);
|
||||
template Optional<long long> convert_to_int(StringView str, TrimWhitespace);
|
||||
|
||||
template<typename T>
|
||||
Optional<T> convert_to_uint(StringView str, TrimWhitespace trim_whitespace)
|
||||
{
|
||||
auto string = trim_whitespace == TrimWhitespace::Yes
|
||||
? str.trim_whitespace()
|
||||
: str;
|
||||
if (string.is_empty())
|
||||
return {};
|
||||
|
||||
T value = 0;
|
||||
auto const characters = string.characters_without_null_termination();
|
||||
|
||||
for (size_t i = 0; i < string.length(); i++) {
|
||||
if (characters[i] < '0' || characters[i] > '9')
|
||||
return {};
|
||||
|
||||
if (__builtin_mul_overflow(value, 10, &value))
|
||||
return {};
|
||||
|
||||
if (__builtin_add_overflow(value, characters[i] - '0', &value))
|
||||
return {};
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
template Optional<u8> convert_to_uint(StringView str, TrimWhitespace);
|
||||
template Optional<u16> convert_to_uint(StringView str, TrimWhitespace);
|
||||
template Optional<u32> convert_to_uint(StringView str, TrimWhitespace);
|
||||
template Optional<unsigned long> convert_to_uint(StringView str, TrimWhitespace);
|
||||
template Optional<unsigned long long> convert_to_uint(StringView str, TrimWhitespace);
|
||||
|
||||
template<typename T>
|
||||
Optional<T> convert_to_uint_from_hex(StringView str, TrimWhitespace trim_whitespace)
|
||||
{
|
||||
auto string = trim_whitespace == TrimWhitespace::Yes
|
||||
? str.trim_whitespace()
|
||||
: str;
|
||||
if (string.is_empty())
|
||||
return {};
|
||||
|
||||
T value = 0;
|
||||
auto const count = string.length();
|
||||
T const upper_bound = NumericLimits<T>::max();
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
char digit = string[i];
|
||||
u8 digit_val;
|
||||
if (value > (upper_bound >> 4))
|
||||
return {};
|
||||
|
||||
if (digit >= '0' && digit <= '9') {
|
||||
digit_val = digit - '0';
|
||||
} else if (digit >= 'a' && digit <= 'f') {
|
||||
digit_val = 10 + (digit - 'a');
|
||||
} else if (digit >= 'A' && digit <= 'F') {
|
||||
digit_val = 10 + (digit - 'A');
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
|
||||
value = (value << 4) + digit_val;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
template Optional<u8> convert_to_uint_from_hex(StringView str, TrimWhitespace);
|
||||
template Optional<u16> convert_to_uint_from_hex(StringView str, TrimWhitespace);
|
||||
template Optional<u32> convert_to_uint_from_hex(StringView str, TrimWhitespace);
|
||||
template Optional<u64> convert_to_uint_from_hex(StringView str, TrimWhitespace);
|
||||
|
||||
template<typename T>
|
||||
Optional<T> convert_to_uint_from_octal(StringView str, TrimWhitespace trim_whitespace)
|
||||
{
|
||||
auto string = trim_whitespace == TrimWhitespace::Yes
|
||||
? str.trim_whitespace()
|
||||
: str;
|
||||
if (string.is_empty())
|
||||
return {};
|
||||
|
||||
T value = 0;
|
||||
auto const count = string.length();
|
||||
T const upper_bound = NumericLimits<T>::max();
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
char digit = string[i];
|
||||
u8 digit_val;
|
||||
if (value > (upper_bound >> 3))
|
||||
return {};
|
||||
|
||||
if (digit >= '0' && digit <= '7') {
|
||||
digit_val = digit - '0';
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
|
||||
value = (value << 3) + digit_val;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
template Optional<u8> convert_to_uint_from_octal(StringView str, TrimWhitespace);
|
||||
template Optional<u16> convert_to_uint_from_octal(StringView str, TrimWhitespace);
|
||||
template Optional<u32> convert_to_uint_from_octal(StringView str, TrimWhitespace);
|
||||
template Optional<u64> convert_to_uint_from_octal(StringView str, TrimWhitespace);
|
||||
|
||||
template<typename T>
|
||||
Optional<T> convert_to_floating_point(StringView str, TrimWhitespace trim_whitespace)
|
||||
{
|
||||
static_assert(IsSame<T, double> || IsSame<T, float>);
|
||||
auto string = trim_whitespace == TrimWhitespace::Yes
|
||||
? str.trim_whitespace()
|
||||
: str;
|
||||
|
||||
char const* start = string.characters_without_null_termination();
|
||||
return parse_floating_point_completely<T>(start, start + string.length());
|
||||
}
|
||||
|
||||
template Optional<double> convert_to_floating_point(StringView str, TrimWhitespace);
|
||||
template Optional<float> convert_to_floating_point(StringView str, TrimWhitespace);
|
||||
|
||||
bool equals_ignoring_ascii_case(StringView a, StringView b)
|
||||
{
|
||||
if (a.length() != b.length())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue