Browse Source

AK+LibRegex: Partially implement case insensitive UTF-16 comparison

This will work for ASCII code points. Unicode case folding will be
needed for non-ASCII.
Timothy Flynn 4 years ago
parent
commit
0e6375558d
3 changed files with 24 additions and 0 deletions
  1. 17 0
      AK/Utf16View.cpp
  2. 2 0
      AK/Utf16View.h
  3. 5 0
      Userland/Libraries/LibRegex/RegexMatch.h

+ 17 - 0
AK/Utf16View.cpp

@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <AK/CharacterTypes.h>
 #include <AK/StringBuilder.h>
 #include <AK/StringView.h>
 #include <AK/Utf16View.h>
@@ -214,6 +215,22 @@ bool Utf16View::operator==(Utf16View const& other) const
     return true;
 }
 
+bool Utf16View::equals_ignoring_case(Utf16View const& other) const
+{
+    if (length_in_code_units() == 0)
+        return other.length_in_code_units() == 0;
+    if (length_in_code_units() != other.length_in_code_units())
+        return false;
+
+    for (size_t i = 0; i < length_in_code_units(); ++i) {
+        // FIXME: Handle non-ASCII case insensitive comparisons.
+        if (to_ascii_lowercase(m_code_units[i]) != to_ascii_lowercase(other.m_code_units[i]))
+            return false;
+    }
+
+    return true;
+}
+
 Utf16CodePointIterator& Utf16CodePointIterator::operator++()
 {
     size_t code_units = length_in_code_units();

+ 2 - 0
AK/Utf16View.h

@@ -104,6 +104,8 @@ public:
         return validate(valid_code_units);
     }
 
+    bool equals_ignoring_case(Utf16View const&) const;
+
 private:
     u16 const* begin_ptr() const { return m_code_units.data(); }
     u16 const* end_ptr() const { return begin_ptr() + m_code_units.size(); }

+ 5 - 0
Userland/Libraries/LibRegex/RegexMatch.h

@@ -335,6 +335,11 @@ public:
                     [&](StringView other_view) { return view.equals_ignoring_case(other_view); },
                     [](auto&) -> bool { TODO(); });
             },
+            [&](Utf16View view) {
+                return other.m_view.visit(
+                    [&](Utf16View other_view) { return view.equals_ignoring_case(other_view); },
+                    [](auto&) -> bool { TODO(); });
+            },
             [](auto&) -> bool { TODO(); });
     }