AK: Add convert_to_uint_from_octal

This commit is contained in:
Xavier Defrang 2021-12-20 21:06:54 +01:00 committed by Brian Gianforcaro
parent 6ca34f5647
commit 9e97823ff8
3 changed files with 91 additions and 0 deletions

View file

@ -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())

View file

@ -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);

View file

@ -226,6 +226,60 @@ TEST_CASE(convert_to_uint)
EXPECT(!actual_u64.has_value());
}
TEST_CASE(convert_to_uint_from_octal)
{
auto value = AK::StringUtils::convert_to_uint_from_octal<u16>(StringView());
EXPECT(!value.has_value());
value = AK::StringUtils::convert_to_uint_from_octal<u16>("");
EXPECT(!value.has_value());
value = AK::StringUtils::convert_to_uint_from_octal<u16>("a");
EXPECT(!value.has_value());
value = AK::StringUtils::convert_to_uint_from_octal<u16>("+");
EXPECT(!value.has_value());
value = AK::StringUtils::convert_to_uint_from_octal<u16>("-");
EXPECT(!value.has_value());
value = AK::StringUtils::convert_to_uint_from_octal<u16>("+1");
EXPECT(!value.has_value());
value = AK::StringUtils::convert_to_uint_from_octal<u16>("-1");
EXPECT(!value.has_value());
value = AK::StringUtils::convert_to_uint_from_octal<u16>("8");
EXPECT(!value.has_value());
auto actual = AK::StringUtils::convert_to_uint_from_octal<u16>("77777777");
EXPECT(!actual.has_value());
actual = AK::StringUtils::convert_to_uint_from_octal<u16>("0");
EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 0u);
actual = AK::StringUtils::convert_to_uint_from_octal<u16>("1");
EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 1u);
actual = AK::StringUtils::convert_to_uint_from_octal<u16>("0755");
EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 0755u);
actual = AK::StringUtils::convert_to_uint_from_octal<u16>("755");
EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 0755u);
actual = AK::StringUtils::convert_to_uint_from_octal<u16>(" \t644 \n\n");
EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 0644u);
actual = AK::StringUtils::convert_to_uint_from_octal<u16>("177777");
EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 0177777u);
}
TEST_CASE(ends_with)
{
String test_string = "ABCDEF";