mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
AK: Add a way to disable the trimming of whitespace in to_*int
This behavior might not always be desirable, and so this patch adds a way to disable it.
This commit is contained in:
parent
8be7bdaac3
commit
3abcfcc178
Notes:
sideshowbarker
2024-07-18 12:03:53 +09:00
Author: https://github.com/sin-ack Commit: https://github.com/SerenityOS/serenity/commit/3abcfcc1785 Pull-request: https://github.com/SerenityOS/serenity/pull/8112 Issue: https://github.com/SerenityOS/serenity/issues/7803 Reviewed-by: https://github.com/linusg Reviewed-by: https://github.com/trflynn89
6 changed files with 74 additions and 61 deletions
|
@ -74,26 +74,26 @@ FlyString::FlyString(StringView const& string)
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
Optional<T> FlyString::to_int() const
|
||||
Optional<T> FlyString::to_int(TrimWhitespace trim_whitespace) const
|
||||
{
|
||||
return StringUtils::convert_to_int<T>(view());
|
||||
return StringUtils::convert_to_int<T>(view(), trim_whitespace);
|
||||
}
|
||||
|
||||
template Optional<i8> FlyString::to_int() const;
|
||||
template Optional<i16> FlyString::to_int() const;
|
||||
template Optional<i32> FlyString::to_int() const;
|
||||
template Optional<i64> FlyString::to_int() const;
|
||||
template Optional<i8> FlyString::to_int(TrimWhitespace) const;
|
||||
template Optional<i16> FlyString::to_int(TrimWhitespace) const;
|
||||
template Optional<i32> FlyString::to_int(TrimWhitespace) const;
|
||||
template Optional<i64> FlyString::to_int(TrimWhitespace) const;
|
||||
|
||||
template<typename T>
|
||||
Optional<T> FlyString::to_uint() const
|
||||
Optional<T> FlyString::to_uint(TrimWhitespace trim_whitespace) const
|
||||
{
|
||||
return StringUtils::convert_to_uint<T>(view());
|
||||
return StringUtils::convert_to_uint<T>(view(), trim_whitespace);
|
||||
}
|
||||
|
||||
template Optional<u8> FlyString::to_uint() const;
|
||||
template Optional<u16> FlyString::to_uint() const;
|
||||
template Optional<u32> FlyString::to_uint() const;
|
||||
template Optional<u64> FlyString::to_uint() const;
|
||||
template Optional<u8> FlyString::to_uint(TrimWhitespace) const;
|
||||
template Optional<u16> FlyString::to_uint(TrimWhitespace) const;
|
||||
template Optional<u32> FlyString::to_uint(TrimWhitespace) const;
|
||||
template Optional<u64> FlyString::to_uint(TrimWhitespace) const;
|
||||
|
||||
bool FlyString::equals_ignoring_case(const StringView& other) const
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "AK/StringUtils.h"
|
||||
#include <AK/String.h>
|
||||
|
||||
namespace AK {
|
||||
|
@ -73,9 +74,9 @@ public:
|
|||
FlyString to_lowercase() const;
|
||||
|
||||
template<typename T = int>
|
||||
Optional<T> to_int() const;
|
||||
Optional<T> to_int(TrimWhitespace = TrimWhitespace::Yes) const;
|
||||
template<typename T = unsigned>
|
||||
Optional<T> to_uint() const;
|
||||
Optional<T> to_uint(TrimWhitespace = TrimWhitespace::Yes) const;
|
||||
|
||||
bool equals_ignoring_case(const StringView&) const;
|
||||
bool starts_with(const StringView&, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
|
||||
|
|
|
@ -180,26 +180,26 @@ ByteBuffer String::to_byte_buffer() const
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
Optional<T> String::to_int() const
|
||||
Optional<T> String::to_int(TrimWhitespace trim_whitespace) const
|
||||
{
|
||||
return StringUtils::convert_to_int<T>(view());
|
||||
return StringUtils::convert_to_int<T>(view(), trim_whitespace);
|
||||
}
|
||||
|
||||
template Optional<i8> String::to_int() const;
|
||||
template Optional<i16> String::to_int() const;
|
||||
template Optional<i32> String::to_int() const;
|
||||
template Optional<i64> String::to_int() const;
|
||||
template Optional<i8> String::to_int(TrimWhitespace) const;
|
||||
template Optional<i16> String::to_int(TrimWhitespace) const;
|
||||
template Optional<i32> String::to_int(TrimWhitespace) const;
|
||||
template Optional<i64> String::to_int(TrimWhitespace) const;
|
||||
|
||||
template<typename T>
|
||||
Optional<T> String::to_uint() const
|
||||
Optional<T> String::to_uint(TrimWhitespace trim_whitespace) const
|
||||
{
|
||||
return StringUtils::convert_to_uint<T>(view());
|
||||
return StringUtils::convert_to_uint<T>(view(), trim_whitespace);
|
||||
}
|
||||
|
||||
template Optional<u8> String::to_uint() const;
|
||||
template Optional<u16> String::to_uint() const;
|
||||
template Optional<u32> String::to_uint() const;
|
||||
template Optional<u64> String::to_uint() const;
|
||||
template Optional<u8> String::to_uint(TrimWhitespace) const;
|
||||
template Optional<u16> String::to_uint(TrimWhitespace) const;
|
||||
template Optional<u32> String::to_uint(TrimWhitespace) const;
|
||||
template Optional<u64> String::to_uint(TrimWhitespace) const;
|
||||
|
||||
bool String::starts_with(const StringView& str, CaseSensitivity case_sensitivity) const
|
||||
{
|
||||
|
|
|
@ -112,9 +112,9 @@ public:
|
|||
[[nodiscard]] bool matches(const StringView& mask, Vector<MaskSpan>&, CaseSensitivity = CaseSensitivity::CaseInsensitive) const;
|
||||
|
||||
template<typename T = int>
|
||||
[[nodiscard]] Optional<T> to_int() const;
|
||||
[[nodiscard]] Optional<T> to_int(TrimWhitespace = TrimWhitespace::Yes) const;
|
||||
template<typename T = unsigned>
|
||||
[[nodiscard]] Optional<T> to_uint() const;
|
||||
[[nodiscard]] Optional<T> to_uint(TrimWhitespace = TrimWhitespace::Yes) const;
|
||||
|
||||
[[nodiscard]] String to_lowercase() const;
|
||||
[[nodiscard]] String to_uppercase() const;
|
||||
|
|
|
@ -86,18 +86,20 @@ bool matches(const StringView& str, const StringView& mask, CaseSensitivity case
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
Optional<T> convert_to_int(const StringView& str)
|
||||
Optional<T> convert_to_int(const StringView& str, TrimWhitespace trim_whitespace)
|
||||
{
|
||||
auto str_trimmed = str.trim_whitespace();
|
||||
if (str_trimmed.is_empty())
|
||||
auto string = trim_whitespace == TrimWhitespace::Yes
|
||||
? str.trim_whitespace()
|
||||
: str;
|
||||
if (string.is_empty())
|
||||
return {};
|
||||
|
||||
T sign = 1;
|
||||
size_t i = 0;
|
||||
const auto characters = str_trimmed.characters_without_null_termination();
|
||||
const auto characters = string.characters_without_null_termination();
|
||||
|
||||
if (characters[0] == '-' || characters[0] == '+') {
|
||||
if (str_trimmed.length() == 1)
|
||||
if (string.length() == 1)
|
||||
return {};
|
||||
i++;
|
||||
if (characters[0] == '-')
|
||||
|
@ -105,7 +107,7 @@ Optional<T> convert_to_int(const StringView& str)
|
|||
}
|
||||
|
||||
T value = 0;
|
||||
for (; i < str_trimmed.length(); i++) {
|
||||
for (; i < string.length(); i++) {
|
||||
if (characters[i] < '0' || characters[i] > '9')
|
||||
return {};
|
||||
|
||||
|
@ -118,22 +120,24 @@ Optional<T> convert_to_int(const StringView& str)
|
|||
return value;
|
||||
}
|
||||
|
||||
template Optional<i8> convert_to_int(const StringView& str);
|
||||
template Optional<i16> convert_to_int(const StringView& str);
|
||||
template Optional<i32> convert_to_int(const StringView& str);
|
||||
template Optional<i64> convert_to_int(const StringView& str);
|
||||
template Optional<i8> convert_to_int(const StringView& str, TrimWhitespace);
|
||||
template Optional<i16> convert_to_int(const StringView& str, TrimWhitespace);
|
||||
template Optional<i32> convert_to_int(const StringView& str, TrimWhitespace);
|
||||
template Optional<i64> convert_to_int(const StringView& str, TrimWhitespace);
|
||||
|
||||
template<typename T>
|
||||
Optional<T> convert_to_uint(const StringView& str)
|
||||
Optional<T> convert_to_uint(const StringView& str, TrimWhitespace trim_whitespace)
|
||||
{
|
||||
auto str_trimmed = str.trim_whitespace();
|
||||
if (str_trimmed.is_empty())
|
||||
auto string = trim_whitespace == TrimWhitespace::Yes
|
||||
? str.trim_whitespace()
|
||||
: str;
|
||||
if (string.is_empty())
|
||||
return {};
|
||||
|
||||
T value = 0;
|
||||
const auto characters = str_trimmed.characters_without_null_termination();
|
||||
const auto characters = string.characters_without_null_termination();
|
||||
|
||||
for (size_t i = 0; i < str_trimmed.length(); i++) {
|
||||
for (size_t i = 0; i < string.length(); i++) {
|
||||
if (characters[i] < '0' || characters[i] > '9')
|
||||
return {};
|
||||
|
||||
|
@ -146,26 +150,28 @@ Optional<T> convert_to_uint(const StringView& str)
|
|||
return value;
|
||||
}
|
||||
|
||||
template Optional<u8> convert_to_uint(const StringView& str);
|
||||
template Optional<u16> convert_to_uint(const StringView& str);
|
||||
template Optional<u32> convert_to_uint(const StringView& str);
|
||||
template Optional<u64> convert_to_uint(const StringView& str);
|
||||
template Optional<long> convert_to_uint(const StringView& str);
|
||||
template Optional<long long> convert_to_uint(const StringView& str);
|
||||
template Optional<u8> convert_to_uint(const StringView& str, TrimWhitespace);
|
||||
template Optional<u16> convert_to_uint(const StringView& str, TrimWhitespace);
|
||||
template Optional<u32> convert_to_uint(const StringView& str, TrimWhitespace);
|
||||
template Optional<u64> convert_to_uint(const StringView& str, TrimWhitespace);
|
||||
template Optional<long> convert_to_uint(const StringView& str, TrimWhitespace);
|
||||
template Optional<long long> convert_to_uint(const StringView& str, TrimWhitespace);
|
||||
|
||||
template<typename T>
|
||||
Optional<T> convert_to_uint_from_hex(const StringView& str)
|
||||
Optional<T> convert_to_uint_from_hex(const StringView& str, TrimWhitespace trim_whitespace)
|
||||
{
|
||||
auto str_trimmed = str.trim_whitespace();
|
||||
if (str_trimmed.is_empty())
|
||||
auto string = trim_whitespace == TrimWhitespace::Yes
|
||||
? str.trim_whitespace()
|
||||
: str;
|
||||
if (string.is_empty())
|
||||
return {};
|
||||
|
||||
T value = 0;
|
||||
const auto count = str_trimmed.length();
|
||||
const auto count = string.length();
|
||||
const T upper_bound = NumericLimits<T>::max();
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
char digit = str_trimmed[i];
|
||||
char digit = string[i];
|
||||
u8 digit_val;
|
||||
if (value > (upper_bound >> 4))
|
||||
return {};
|
||||
|
@ -185,10 +191,10 @@ Optional<T> convert_to_uint_from_hex(const StringView& str)
|
|||
return value;
|
||||
}
|
||||
|
||||
template Optional<u8> convert_to_uint_from_hex(const StringView& str);
|
||||
template Optional<u16> convert_to_uint_from_hex(const StringView& str);
|
||||
template Optional<u32> convert_to_uint_from_hex(const StringView& str);
|
||||
template Optional<u64> convert_to_uint_from_hex(const StringView& str);
|
||||
template Optional<u8> convert_to_uint_from_hex(const StringView& str, TrimWhitespace);
|
||||
template Optional<u16> convert_to_uint_from_hex(const StringView& str, TrimWhitespace);
|
||||
template Optional<u32> convert_to_uint_from_hex(const StringView& str, TrimWhitespace);
|
||||
template Optional<u64> convert_to_uint_from_hex(const StringView& str, TrimWhitespace);
|
||||
|
||||
static inline char to_lowercase(char c)
|
||||
{
|
||||
|
|
|
@ -22,6 +22,11 @@ enum class TrimMode {
|
|||
Both
|
||||
};
|
||||
|
||||
enum class TrimWhitespace {
|
||||
Yes,
|
||||
No,
|
||||
};
|
||||
|
||||
struct MaskSpan {
|
||||
size_t start;
|
||||
size_t length;
|
||||
|
@ -40,11 +45,11 @@ namespace StringUtils {
|
|||
|
||||
bool matches(const StringView& str, const StringView& mask, CaseSensitivity = CaseSensitivity::CaseInsensitive, Vector<MaskSpan>* match_spans = nullptr);
|
||||
template<typename T = int>
|
||||
Optional<T> convert_to_int(const StringView&);
|
||||
Optional<T> convert_to_int(const StringView&, TrimWhitespace = TrimWhitespace::Yes);
|
||||
template<typename T = unsigned>
|
||||
Optional<T> convert_to_uint(const StringView&);
|
||||
Optional<T> convert_to_uint(const StringView&, TrimWhitespace = TrimWhitespace::Yes);
|
||||
template<typename T = unsigned>
|
||||
Optional<T> convert_to_uint_from_hex(const StringView&);
|
||||
Optional<T> convert_to_uint_from_hex(const StringView&, TrimWhitespace = TrimWhitespace::Yes);
|
||||
bool equals_ignoring_case(const StringView&, const StringView&);
|
||||
bool ends_with(const StringView& a, const StringView& b, CaseSensitivity);
|
||||
bool starts_with(const StringView&, const StringView&, CaseSensitivity);
|
||||
|
@ -61,3 +66,4 @@ String to_snakecase(const StringView&);
|
|||
|
||||
using AK::CaseSensitivity;
|
||||
using AK::TrimMode;
|
||||
using AK::TrimWhitespace;
|
||||
|
|
Loading…
Reference in a new issue