mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 09:00:22 +00:00
AK: Add case insensitive String::ends_with support
FileSystemPath::has_extension was jumping through hoops and allocating memory to do a case insensitive comparison needlessly. Extend the existing String::ends_with method to allow the caller to specify the case sensitivity required.
This commit is contained in:
parent
8e4b858b3f
commit
332f96e7ca
Notes:
sideshowbarker
2024-07-19 06:07:40 +09:00
Author: https://github.com/bgianfo Commit: https://github.com/SerenityOS/serenity/commit/332f96e7cab Pull-request: https://github.com/SerenityOS/serenity/pull/2387 Reviewed-by: https://github.com/awesomekling
7 changed files with 53 additions and 12 deletions
|
@ -105,11 +105,9 @@ void FileSystemPath::canonicalize()
|
||||||
m_string = builder.to_string();
|
m_string = builder.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystemPath::has_extension(StringView extension) const
|
bool FileSystemPath::has_extension(const StringView& extension) const
|
||||||
{
|
{
|
||||||
// FIXME: This is inefficient, expand StringView with enough functionality that we don't need to copy strings here.
|
return m_string.ends_with(extension, CaseSensitivity::CaseInsensitive);
|
||||||
String extension_string = extension;
|
|
||||||
return m_string.to_lowercase().ends_with(extension_string.to_lowercase());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String canonicalized_path(const StringView& path)
|
String canonicalized_path(const StringView& path)
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
|
|
||||||
const Vector<String>& parts() const { return m_parts; }
|
const Vector<String>& parts() const { return m_parts; }
|
||||||
|
|
||||||
bool has_extension(StringView) const;
|
bool has_extension(const StringView&) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void canonicalize();
|
void canonicalize();
|
||||||
|
|
|
@ -278,9 +278,9 @@ bool String::starts_with(char ch) const
|
||||||
return characters()[0] == ch;
|
return characters()[0] == ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool String::ends_with(const StringView& str) const
|
bool String::ends_with(const StringView& str, CaseSensitivity case_sensitivity) const
|
||||||
{
|
{
|
||||||
return StringUtils::ends_with(*this, str);
|
return StringUtils::ends_with(*this, str, case_sensitivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool String::ends_with(char ch) const
|
bool String::ends_with(char ch) const
|
||||||
|
|
|
@ -146,7 +146,7 @@ public:
|
||||||
ConstIterator end() const { return begin() + length(); }
|
ConstIterator end() const { return begin() + length(); }
|
||||||
|
|
||||||
bool starts_with(const StringView&) const;
|
bool starts_with(const StringView&) const;
|
||||||
bool ends_with(const StringView&) const;
|
bool ends_with(const StringView&, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
|
||||||
bool starts_with(char) const;
|
bool starts_with(char) const;
|
||||||
bool ends_with(char) const;
|
bool ends_with(char) const;
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ bool equals_ignoring_case(const StringView& a, const StringView& b)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ends_with(const StringView& str, const StringView& end)
|
bool ends_with(const StringView& str, const StringView& end, CaseSensitivity case_sensitivity)
|
||||||
{
|
{
|
||||||
if (end.is_empty())
|
if (end.is_empty())
|
||||||
return true;
|
return true;
|
||||||
|
@ -204,7 +204,19 @@ bool ends_with(const StringView& str, const StringView& end)
|
||||||
return false;
|
return false;
|
||||||
if (end.length() > str.length())
|
if (end.length() > str.length())
|
||||||
return false;
|
return false;
|
||||||
return !memcmp(str.characters_without_null_termination() + (str.length() - end.length()), end.characters_without_null_termination(), end.length());
|
|
||||||
|
if (case_sensitivity == CaseSensitivity::CaseSensitive)
|
||||||
|
return !memcmp(str.characters_without_null_termination() + (str.length() - end.length()), end.characters_without_null_termination(), end.length());
|
||||||
|
|
||||||
|
auto str_chars = str.characters_without_null_termination();
|
||||||
|
auto end_chars = end.characters_without_null_termination();
|
||||||
|
|
||||||
|
size_t si = str.length() - end.length();
|
||||||
|
for (size_t ei = 0; ei < end.length(); ++si, ++ei) {
|
||||||
|
if (to_lowercase(str_chars[si]) != to_lowercase(end_chars[ei]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,7 @@ int convert_to_int(const StringView&, bool& ok);
|
||||||
unsigned convert_to_uint(const StringView&, bool& ok);
|
unsigned convert_to_uint(const StringView&, bool& ok);
|
||||||
unsigned convert_to_uint_from_hex(const StringView&, bool& ok);
|
unsigned convert_to_uint_from_hex(const StringView&, bool& ok);
|
||||||
bool equals_ignoring_case(const StringView&, const StringView&);
|
bool equals_ignoring_case(const StringView&, const StringView&);
|
||||||
bool ends_with(const StringView& str, const StringView& end);
|
bool ends_with(const StringView& a, const StringView& b, CaseSensitivity);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,4 +85,36 @@ TEST_CASE(relative_paths)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(has_extension)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
FileSystemPath path("/tmp/simple.png");
|
||||||
|
EXPECT(path.has_extension(".png"));
|
||||||
|
EXPECT(path.has_extension(".pnG"));
|
||||||
|
EXPECT(path.has_extension(".PNG"));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
FileSystemPath path("/TMP/SIMPLE.PNG");
|
||||||
|
EXPECT(path.has_extension(".png"));
|
||||||
|
EXPECT(path.has_extension(".pnG"));
|
||||||
|
EXPECT(path.has_extension(".PNG"));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
FileSystemPath path(".png");
|
||||||
|
EXPECT(path.has_extension(".png"));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
FileSystemPath path;
|
||||||
|
EXPECT_EQ(path.has_extension(".png"), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
FileSystemPath path("png");
|
||||||
|
EXPECT_EQ(path.has_extension(".png"), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_MAIN(FileSystemPath)
|
TEST_MAIN(FileSystemPath)
|
||||||
|
|
Loading…
Reference in a new issue