diff options
-rw-r--r-- | AK/FlyString.cpp | 24 | ||||
-rw-r--r-- | AK/FlyString.h | 5 | ||||
-rw-r--r-- | AK/String.cpp | 24 | ||||
-rw-r--r-- | AK/String.h | 4 | ||||
-rw-r--r-- | AK/StringUtils.cpp | 66 | ||||
-rw-r--r-- | AK/StringUtils.h | 12 |
6 files changed, 74 insertions, 61 deletions
diff --git a/AK/FlyString.cpp b/AK/FlyString.cpp index 5ad1725d3a..aa6a3e79ca 100644 --- a/AK/FlyString.cpp +++ b/AK/FlyString.cpp @@ -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 { diff --git a/AK/FlyString.h b/AK/FlyString.h index 0e107053e0..d91e94c68b 100644 --- a/AK/FlyString.h +++ b/AK/FlyString.h @@ -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; diff --git a/AK/String.cpp b/AK/String.cpp index 17eb0ac745..79d849496f 100644 --- a/AK/String.cpp +++ b/AK/String.cpp @@ -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 { diff --git a/AK/String.h b/AK/String.h index 6f9b98fdde..a3e70ba803 100644 --- a/AK/String.h +++ b/AK/String.h @@ -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; diff --git a/AK/StringUtils.cpp b/AK/StringUtils.cpp index 18743b1521..5c5d5db10c 100644 --- a/AK/StringUtils.cpp +++ b/AK/StringUtils.cpp @@ -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) { diff --git a/AK/StringUtils.h b/AK/StringUtils.h index a7f7ac2881..fa7ae1902d 100644 --- a/AK/StringUtils.h +++ b/AK/StringUtils.h @@ -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; |