AK: Move trim_whitespace() into StringUtils and add it to StringView

No behaviour change; also patches use of `String::TrimMode` in LibJS.
This commit is contained in:
AnotherTest 2020-09-20 18:05:04 +04:30 committed by Andreas Kling
parent 50e9000b40
commit 5fbec2b003
Notes: sideshowbarker 2024-07-19 02:09:52 +09:00
6 changed files with 56 additions and 47 deletions

View file

@ -337,44 +337,6 @@ int String::replace(const String& needle, const String& replacement, bool all_oc
return positions.size(); return positions.size();
} }
String String::trim_whitespace(TrimMode mode) const
{
auto is_whitespace_character = [](char ch) -> bool {
return ch == '\t'
|| ch == '\n'
|| ch == '\v'
|| ch == '\f'
|| ch == '\r'
|| ch == ' ';
};
size_t substring_start = 0;
size_t substring_length = length();
if (mode == TrimMode::Left || mode == TrimMode::Both) {
for (size_t i = 0; i < length(); ++i) {
if (substring_length == 0)
return "";
if (!is_whitespace_character(characters()[i]))
break;
++substring_start;
--substring_length;
}
}
if (mode == TrimMode::Right || mode == TrimMode::Both) {
for (size_t i = length() - 1; i > 0; --i) {
if (substring_length == 0)
return "";
if (!is_whitespace_character(characters()[i]))
break;
--substring_length;
}
}
return substring(substring_start, substring_length);
}
String escape_html_entities(const StringView& html) String escape_html_entities(const StringView& html)
{ {
StringBuilder builder; StringBuilder builder;

View file

@ -119,12 +119,12 @@ public:
String to_lowercase() const; String to_lowercase() const;
String to_uppercase() const; String to_uppercase() const;
enum class TrimMode { #ifndef KERNEL
Left, String trim_whitespace(TrimMode mode = TrimMode::Both) const
Right, {
Both return StringUtils::trim_whitespace(StringView { characters(), length() }, mode);
}; }
String trim_whitespace(TrimMode mode = TrimMode::Both) const; #endif
bool equals_ignoring_case(const StringView&) const; bool equals_ignoring_case(const StringView&) const;

View file

@ -227,6 +227,43 @@ bool starts_with(const StringView& str, const StringView& start, CaseSensitivity
return true; return true;
} }
StringView trim_whitespace(const StringView& str, TrimMode mode)
{
auto is_whitespace_character = [](char ch) -> bool {
return ch == '\t'
|| ch == '\n'
|| ch == '\v'
|| ch == '\f'
|| ch == '\r'
|| ch == ' ';
};
size_t substring_start = 0;
size_t substring_length = str.length();
if (mode == TrimMode::Left || mode == TrimMode::Both) {
for (size_t i = 0; i < str.length(); ++i) {
if (substring_length == 0)
return "";
if (!is_whitespace_character(str[i]))
break;
++substring_start;
--substring_length;
}
}
if (mode == TrimMode::Right || mode == TrimMode::Both) {
for (size_t i = str.length() - 1; i > 0; --i) {
if (substring_length == 0)
return "";
if (!is_whitespace_character(str[i]))
break;
--substring_length;
}
}
return str.substring_view(substring_start, substring_length);
}
} }
} }

View file

@ -36,6 +36,12 @@ enum class CaseSensitivity {
CaseSensitive, CaseSensitive,
}; };
enum class TrimMode {
Left,
Right,
Both
};
namespace StringUtils { namespace StringUtils {
bool matches(const StringView& str, const StringView& mask, CaseSensitivity = CaseSensitivity::CaseInsensitive); bool matches(const StringView& str, const StringView& mask, CaseSensitivity = CaseSensitivity::CaseInsensitive);
@ -45,8 +51,10 @@ Optional<unsigned> convert_to_uint_from_hex(const StringView&);
bool equals_ignoring_case(const StringView&, const StringView&); bool equals_ignoring_case(const StringView&, const StringView&);
bool ends_with(const StringView& a, const StringView& b, CaseSensitivity); bool ends_with(const StringView& a, const StringView& b, CaseSensitivity);
bool starts_with(const StringView&, const StringView&, CaseSensitivity); bool starts_with(const StringView&, const StringView&, CaseSensitivity);
StringView trim_whitespace(const StringView&, TrimMode mode);
} }
} }
using AK::CaseSensitivity; using AK::CaseSensitivity;
using AK::TrimMode;

View file

@ -91,6 +91,8 @@ public:
bool contains(const StringView&) const; bool contains(const StringView&) const;
bool equals_ignoring_case(const StringView& other) const; bool equals_ignoring_case(const StringView& other) const;
StringView trim_whitespace(TrimMode mode = TrimMode::Both) const { return StringUtils::trim_whitespace(*this, mode); }
Optional<size_t> find_first_of(char) const; Optional<size_t> find_first_of(char) const;
Optional<size_t> find_first_of(const StringView&) const; Optional<size_t> find_first_of(const StringView&) const;

View file

@ -282,7 +282,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim)
auto string = ak_string_from(vm, global_object); auto string = ak_string_from(vm, global_object);
if (string.is_null()) if (string.is_null())
return {}; return {};
return js_string(vm, string.trim_whitespace(String::TrimMode::Both)); return js_string(vm, string.trim_whitespace(TrimMode::Both));
} }
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_start) JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_start)
@ -290,7 +290,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_start)
auto string = ak_string_from(vm, global_object); auto string = ak_string_from(vm, global_object);
if (string.is_null()) if (string.is_null())
return {}; return {};
return js_string(vm, string.trim_whitespace(String::TrimMode::Left)); return js_string(vm, string.trim_whitespace(TrimMode::Left));
} }
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_end) JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_end)
@ -298,7 +298,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_end)
auto string = ak_string_from(vm, global_object); auto string = ak_string_from(vm, global_object);
if (string.is_null()) if (string.is_null())
return {}; return {};
return js_string(vm, string.trim_whitespace(String::TrimMode::Right)); return js_string(vm, string.trim_whitespace(TrimMode::Right));
} }
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::concat) JS_DEFINE_NATIVE_FUNCTION(StringPrototype::concat)