summaryrefslogtreecommitdiff
path: root/AK
diff options
context:
space:
mode:
authorXavier Defrang <xavier.defrang@gmail.com>2021-12-20 21:06:54 +0100
committerBrian Gianforcaro <b.gianfo@gmail.com>2021-12-21 13:13:04 -0800
commit9e97823ff8bf884c1be73f46345feafbec86b0a5 (patch)
treebcaf67e0f82a1de792604e61d7a56a92382e17cf /AK
parent6ca34f56474bd2aeb401d71ae17e4842da6d1585 (diff)
downloadserenity-9e97823ff8bf884c1be73f46345feafbec86b0a5.zip
AK: Add convert_to_uint_from_octal
Diffstat (limited to 'AK')
-rw-r--r--AK/StringUtils.cpp35
-rw-r--r--AK/StringUtils.h2
2 files changed, 37 insertions, 0 deletions
diff --git a/AK/StringUtils.cpp b/AK/StringUtils.cpp
index d62499f45e..31b2216d47 100644
--- a/AK/StringUtils.cpp
+++ b/AK/StringUtils.cpp
@@ -191,6 +191,41 @@ 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;
+ const auto count = string.length();
+ const T 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);
+
bool equals_ignoring_case(StringView a, StringView b)
{
if (a.length() != b.length())
diff --git a/AK/StringUtils.h b/AK/StringUtils.h
index ca079cb82a..775e28ac6c 100644
--- a/AK/StringUtils.h
+++ b/AK/StringUtils.h
@@ -56,6 +56,8 @@ template<typename T = unsigned>
Optional<T> convert_to_uint(StringView, TrimWhitespace = TrimWhitespace::Yes);
template<typename T = unsigned>
Optional<T> convert_to_uint_from_hex(StringView, TrimWhitespace = TrimWhitespace::Yes);
+template<typename T = unsigned>
+Optional<T> convert_to_uint_from_octal(StringView, TrimWhitespace = TrimWhitespace::Yes);
bool equals_ignoring_case(StringView, StringView);
bool ends_with(StringView a, StringView b, CaseSensitivity);
bool starts_with(StringView, StringView, CaseSensitivity);