Kaynağa Gözat

HexEditor: Add find_all_strings() function

Brendan Coles 4 yıl önce
ebeveyn
işleme
90e9d1a0a1

+ 34 - 0
Userland/Applications/HexEditor/HexEditor.cpp

@@ -623,3 +623,37 @@ Vector<Match> HexEditor::find_all(ByteBuffer& needle, int start)
 
     return matches;
 }
+
+Vector<Match> HexEditor::find_all_strings(size_t min_length)
+{
+    if (m_buffer.is_empty())
+        return {};
+
+    Vector<Match> matches;
+
+    int offset = -1;
+    StringBuilder builder;
+    for (size_t i = 0; i < m_buffer.size(); i++) {
+        char c = m_buffer.bytes().at(i);
+        if (isprint(c)) {
+            if (offset == -1)
+                offset = i;
+            builder.append(c);
+        } else {
+            if (builder.length() >= min_length) {
+                dbgln("find_all_strings: relative_offset={} string={}", offset, builder.to_string());
+                matches.append({ offset, builder.to_string() });
+            }
+            builder.clear();
+            offset = -1;
+        }
+    }
+
+    if (matches.is_empty())
+        return {};
+
+    auto first_match = matches.at(0);
+    highlight(first_match.offset, first_match.offset + first_match.value.length());
+
+    return matches;
+}

+ 1 - 0
Userland/Applications/HexEditor/HexEditor.h

@@ -50,6 +50,7 @@ public:
     int find(ByteBuffer& needle, int start = 0);
     int find_and_highlight(ByteBuffer& needle, int start = 0);
     Vector<Match> find_all(ByteBuffer& needle, int start = 0);
+    Vector<Match> find_all_strings(size_t min_length = 4);
     Function<void(int, EditMode, int, int)> on_status_change; // position, edit mode, selection start, selection end
     Function<void()> on_change;
 

+ 15 - 0
Userland/Applications/HexEditor/HexEditorWidget.cpp

@@ -257,6 +257,21 @@ void HexEditorWidget::initialize_menubar(GUI::Menubar& menubar)
         m_editor->update();
         m_last_found_index = result;
     }));
+
+    edit_menu.add_action(GUI::Action::create("Find All &Strings", { Mod_Ctrl | Mod_Shift, Key_S }, Gfx::Bitmap::load_from_file("/res/icons/16x16/find.png"), [&](const GUI::Action&) {
+        int min_length = 4;
+        auto matches = m_editor->find_all_strings(min_length);
+        m_search_results->set_model(*new SearchResultsModel(move(matches)));
+        m_search_results->update();
+
+        if (matches.is_empty()) {
+            GUI::MessageBox::show(window(), "No strings found in this file", "Not found", GUI::MessageBox::Type::Warning);
+            return;
+        }
+
+        set_search_results_visible(true);
+        m_editor->update();
+    }));
     edit_menu.add_separator();
     edit_menu.add_action(*m_goto_offset_action);