Browse Source

AK: Add more StringView utilities for making substrings.

These two allow making a new substring view starting from,
or starting after, an existing substring view.

Also make use of one of them in the kernel.
Sergey Bugaev 6 years ago
parent
commit
1a697f70db
3 changed files with 38 additions and 4 deletions
  1. 18 0
      AK/StringView.cpp
  2. 19 0
      AK/StringView.h
  3. 1 4
      Kernel/FileSystem/VirtualFileSystem.cpp

+ 18 - 0
AK/StringView.cpp

@@ -42,6 +42,24 @@ StringView StringView::substring_view(int start, int length) const
     return { m_characters + start, length };
 }
 
+StringView StringView::substring_view_starting_from_substring(const StringView& substring) const
+{
+    const char* remaining_characters = substring.characters();
+    ASSERT(remaining_characters >= m_characters);
+    ASSERT(remaining_characters <= m_characters + m_length);
+    int remaining_length = m_length - (remaining_characters - m_characters);
+    return { remaining_characters, remaining_length };
+}
+
+StringView StringView::substring_view_starting_after_substring(const StringView& substring) const
+{
+    const char* remaining_characters = substring.characters() + substring.length();
+    ASSERT(remaining_characters >= m_characters);
+    ASSERT(remaining_characters <= m_characters + m_length);
+    int remaining_length = m_length - (remaining_characters - m_characters);
+    return { remaining_characters, remaining_length };
+}
+
 unsigned StringView::to_uint(bool& ok) const
 {
     unsigned value = 0;

+ 19 - 0
AK/StringView.h

@@ -40,6 +40,25 @@ public:
     Vector<StringView> split_view(char) const;
     unsigned to_uint(bool& ok) const;
 
+    // Create a new substring view of this string view, starting either at the beginning of
+    // the given substring view, or after its end, and continuing until the end of this string
+    // view (that is, for the remaining part of its length). For example,
+    //
+    //    StringView str { "foobar" };
+    //    StringView substr = str.substring_view(1, 2);  // "oo"
+    //    StringView substr_from = str.substring_view_starting_from_substring(subst);  // "oobar"
+    //    StringView substr_after = str.substring_view_starting_after_substring(subst);  // "bar"
+    //
+    // Note that this only works if the string view passed as an argument is indeed a substring
+    // view of this string view, such as one created by substring_view() and split_view(). It
+    // does not work for arbitrary strings; for example declaring substr in the example above as
+    //
+    //     StringView substr { "oo" };
+    //
+    // would not work.
+    StringView substring_view_starting_from_substring(const StringView& substring) const;
+    StringView substring_view_starting_after_substring(const StringView& substring) const;
+
     bool operator==(const char* cstring) const
     {
         if (is_null())

+ 1 - 4
Kernel/FileSystem/VirtualFileSystem.cpp

@@ -714,10 +714,7 @@ KResultOr<Retained<Custody>> VFS::resolve_path(StringView path, Custody& base, R
             if (!have_more_parts)
                 return symlink_target;
 
-            const char* remaining_path_chars = parts[i + 1].characters();
-            int remaining_path_length = path.length() - (remaining_path_chars - path.characters());
-            StringView remaining_path { remaining_path_chars, remaining_path_length };
-
+            StringView remaining_path = path.substring_view_starting_from_substring(parts[i + 1]);
             return resolve_path(remaining_path, *symlink_target.value(), parent_custody, options);
         }
     }