mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 12:12:45 +00:00 
			
		
		
		
	AK+Everywhere: Consolidate String::index_of() and String::find()
We had two functions for doing mostly the same thing. Combine both of them into String::find() and use that everywhere. Also add some tests to cover basic behavior.
This commit is contained in:
		
							parent
							
								
									875a2cbb71
								
							
						
					
					
						commit
						de395a3df2
					
				
					 12 changed files with 36 additions and 30 deletions
				
			
		|  | @ -286,18 +286,6 @@ bool String::contains(const StringView& needle, CaseSensitivity case_sensitivity | |||
|     return StringUtils::contains(*this, needle, case_sensitivity); | ||||
| } | ||||
| 
 | ||||
| Optional<size_t> String::index_of(const String& needle, size_t start) const | ||||
| { | ||||
|     if (is_null() || needle.is_null()) | ||||
|         return {}; | ||||
| 
 | ||||
|     const char* self_characters = characters(); | ||||
|     const char* result = strstr(self_characters + start, needle.characters()); | ||||
|     if (!result) | ||||
|         return {}; | ||||
|     return Optional<size_t> { result - self_characters }; | ||||
| } | ||||
| 
 | ||||
| bool String::equals_ignoring_case(const StringView& other) const | ||||
| { | ||||
|     return StringUtils::equals_ignoring_case(view(), other); | ||||
|  | @ -491,14 +479,17 @@ String String::vformatted(StringView fmtstr, TypeErasedFormatParams params) | |||
|     return builder.to_string(); | ||||
| } | ||||
| 
 | ||||
| Optional<size_t> String::find(char c) const | ||||
| Optional<size_t> String::find(char c, size_t start) const | ||||
| { | ||||
|     return find(StringView { &c, 1 }); | ||||
|     return find(StringView { &c, 1 }, start); | ||||
| } | ||||
| 
 | ||||
| Optional<size_t> String::find(const StringView& view) const | ||||
| Optional<size_t> String::find(StringView const& view, size_t start) const | ||||
| { | ||||
|     return StringUtils::find(*this, view); | ||||
|     auto index = StringUtils::find(substring_view(start), view); | ||||
|     if (!index.has_value()) | ||||
|         return {}; | ||||
|     return index.value() + start; | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -127,13 +127,12 @@ public: | |||
|     [[nodiscard]] bool equals_ignoring_case(const StringView&) const; | ||||
| 
 | ||||
|     [[nodiscard]] bool contains(const StringView&, CaseSensitivity = CaseSensitivity::CaseSensitive) const; | ||||
|     [[nodiscard]] Optional<size_t> index_of(const String&, size_t start = 0) const; | ||||
| 
 | ||||
|     [[nodiscard]] Vector<String> split_limit(char separator, size_t limit, bool keep_empty = false) const; | ||||
|     [[nodiscard]] Vector<String> split(char separator, bool keep_empty = false) const; | ||||
| 
 | ||||
|     [[nodiscard]] Optional<size_t> find(char) const; | ||||
|     [[nodiscard]] Optional<size_t> find(const StringView&) const; | ||||
|     [[nodiscard]] Optional<size_t> find(char, size_t start = 0) const; | ||||
|     [[nodiscard]] Optional<size_t> find(StringView const&, size_t start = 0) const; | ||||
| 
 | ||||
|     [[nodiscard]] String substring(size_t start) const; | ||||
|     [[nodiscard]] String substring(size_t start, size_t length) const; | ||||
|  |  | |||
|  | @ -255,3 +255,19 @@ TEST_CASE(sprintf) | |||
|     EXPECT_EQ(String(buf1), String("+12")); | ||||
|     EXPECT_EQ(String(buf2), String("-12")); | ||||
| } | ||||
| 
 | ||||
| TEST_CASE(find) | ||||
| { | ||||
|     String a = "foobarbar"; | ||||
|     EXPECT_EQ(a.find("bar"sv), Optional<size_t> { 3 }); | ||||
|     EXPECT_EQ(a.find("baz"sv), Optional<size_t> {}); | ||||
|     EXPECT_EQ(a.find("bar"sv, 4), Optional<size_t> { 6 }); | ||||
|     EXPECT_EQ(a.find("bar"sv, 9), Optional<size_t> {}); | ||||
| 
 | ||||
|     EXPECT_EQ(a.find('f'), Optional<size_t> { 0 }); | ||||
|     EXPECT_EQ(a.find('x'), Optional<size_t> {}); | ||||
|     EXPECT_EQ(a.find('f', 1), Optional<size_t> {}); | ||||
|     EXPECT_EQ(a.find('b'), Optional<size_t> { 3 }); | ||||
|     EXPECT_EQ(a.find('b', 4), Optional<size_t> { 6 }); | ||||
|     EXPECT_EQ(a.find('b', 9), Optional<size_t> {}); | ||||
| } | ||||
|  |  | |||
|  | @ -278,7 +278,7 @@ String Emulator::create_backtrace_line(FlatPtr address) | |||
|     const auto* region = find_text_region(address); | ||||
|     if (!region) | ||||
|         return minimal; | ||||
|     auto separator_index = region->name().index_of(":"); | ||||
|     auto separator_index = region->name().find(':'); | ||||
|     if (!separator_index.has_value()) | ||||
|         return minimal; | ||||
| 
 | ||||
|  |  | |||
|  | @ -82,7 +82,7 @@ HunkLocation parse_hunk_location(const String& location_line) | |||
|         size_t length { 0 }; | ||||
|     }; | ||||
|     auto parse_start_and_length_pair = [](const String& raw) { | ||||
|         auto index_of_separator = raw.index_of(",").value(); | ||||
|         auto index_of_separator = raw.find(',').value(); | ||||
|         auto start = raw.substring(0, index_of_separator); | ||||
|         auto length = raw.substring(index_of_separator + 1, raw.length() - index_of_separator - 1); | ||||
|         auto res = StartAndLength { start.to_uint().value() - 1, length.to_uint().value() - 1 }; | ||||
|  |  | |||
|  | @ -297,7 +297,7 @@ Optional<Image::Symbol> Image::find_demangled_function(const String& name) const | |||
|         if (symbol.is_undefined()) | ||||
|             return IterationDecision::Continue; | ||||
|         auto demangled = demangle(symbol.name()); | ||||
|         auto index_of_paren = demangled.index_of("("); | ||||
|         auto index_of_paren = demangled.find('('); | ||||
|         if (index_of_paren.has_value()) { | ||||
|             demangled = demangled.substring(0, index_of_paren.value()); | ||||
|         } | ||||
|  |  | |||
|  | @ -240,7 +240,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::index_of) | |||
|     auto needle = vm.argument(0).to_string(global_object); | ||||
|     if (vm.exception()) | ||||
|         return {}; | ||||
|     return Value((i32)string.index_of(needle).value_or(-1)); | ||||
|     return Value((i32)string.find(needle).value_or(-1)); | ||||
| } | ||||
| 
 | ||||
| JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_lowercase) | ||||
|  | @ -692,7 +692,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace) | |||
|     auto search_string = search_value.to_string(global_object); | ||||
|     if (vm.exception()) | ||||
|         return {}; | ||||
|     Optional<size_t> position = string.index_of(search_string); | ||||
|     Optional<size_t> position = string.find(search_string); | ||||
|     if (!position.has_value()) | ||||
|         return js_string(vm, string); | ||||
| 
 | ||||
|  |  | |||
|  | @ -389,7 +389,7 @@ public: | |||
|     { | ||||
|         if (const auto start_pos = pseudo_name.find('('); start_pos.has_value()) { | ||||
|             const auto start = start_pos.value() + 1; | ||||
|             if (const auto end_pos = pseudo_name.index_of(")", start); end_pos.has_value()) { | ||||
|             if (const auto end_pos = pseudo_name.find(')', start); end_pos.has_value()) { | ||||
|                 return pseudo_name.substring_view(start, end_pos.value() - start).trim_whitespace(); | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -43,7 +43,7 @@ void Resource::for_each_client(Function<void(ResourceClient&)> callback) | |||
| 
 | ||||
| static Optional<String> encoding_from_content_type(const String& content_type) | ||||
| { | ||||
|     auto offset = content_type.index_of("charset="); | ||||
|     auto offset = content_type.find("charset="sv); | ||||
|     if (offset.has_value()) { | ||||
|         auto encoding = content_type.substring(offset.value() + 8, content_type.length() - offset.value() - 8).to_lowercase(); | ||||
|         if (encoding.length() >= 2 && encoding.starts_with('"') && encoding.ends_with('"')) | ||||
|  | @ -58,7 +58,7 @@ static Optional<String> encoding_from_content_type(const String& content_type) | |||
| 
 | ||||
| static String mime_type_from_content_type(const String& content_type) | ||||
| { | ||||
|     auto offset = content_type.index_of(";"); | ||||
|     auto offset = content_type.find(';'); | ||||
|     if (offset.has_value()) | ||||
|         return content_type.substring(0, offset.value()).to_lowercase(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -611,7 +611,7 @@ void BarewordLiteral::highlight_in_editor(Line::Editor& editor, Shell& shell, Hi | |||
|             return; | ||||
| 
 | ||||
|         if (m_text.starts_with("--")) { | ||||
|             auto index = m_text.index_of("=").value_or(m_text.length() - 1) + 1; | ||||
|             auto index = m_text.find('=').value_or(m_text.length() - 1) + 1; | ||||
|             editor.stylize({ m_position.start_offset, m_position.start_offset + index }, { Line::Style::Foreground(Line::Style::XtermColor::Cyan) }); | ||||
|         } else { | ||||
|             editor.stylize({ m_position.start_offset, m_position.end_offset }, { Line::Style::Foreground(Line::Style::XtermColor::Cyan) }); | ||||
|  |  | |||
|  | @ -1772,7 +1772,7 @@ RefPtr<AST::Node> Parser::parse_bareword() | |||
|         String username; | ||||
|         RefPtr<AST::Node> tilde, text; | ||||
| 
 | ||||
|         auto first_slash_index = string.index_of("/"); | ||||
|         auto first_slash_index = string.find('/'); | ||||
|         if (first_slash_index.has_value()) { | ||||
|             username = string.substring_view(1, first_slash_index.value() - 1); | ||||
|             string = string.substring_view(first_slash_index.value(), string.length() - first_slash_index.value()); | ||||
|  |  | |||
|  | @ -371,7 +371,7 @@ private: | |||
|         } | ||||
| 
 | ||||
|         if (m_op == StringOperation::Index) { | ||||
|             if (auto idx = m_str->string().index_of(m_pos_or_chars->string()); idx.has_value()) | ||||
|             if (auto idx = m_str->string().find(m_pos_or_chars->string()); idx.has_value()) | ||||
|                 return idx.value() + 1; | ||||
|             return 0; | ||||
|         } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling