1
0
mirror of synced 2025-02-21 12:29:47 +01:00

sys: Improved searching behaviour

This commit is contained in:
WerWolv 2022-08-24 00:31:34 +02:00
parent 4f1f9a718c
commit e86ca29b8c

View File

@ -143,6 +143,17 @@ namespace hex::plugin::builtin {
class PopupFind : public ViewHexEditor::Popup { class PopupFind : public ViewHexEditor::Popup {
public: public:
PopupFind() {
EventManager::subscribe<EventRegionSelected>(this, [this](Region region) {
this->m_searchPosition = this->m_nextSearchPosition.value_or(region.getStartAddress());
this->m_nextSearchPosition.reset();
});
}
~PopupFind() override {
EventManager::unsubscribe<EventRegionSelected>(this);
}
void draw(ViewHexEditor *editor) override { void draw(ViewHexEditor *editor) override {
std::vector<u8> searchSequence; std::vector<u8> searchSequence;
@ -221,6 +232,7 @@ namespace hex::plugin::builtin {
this->m_shouldSearch = true; this->m_shouldSearch = true;
this->m_backwards = false; this->m_backwards = false;
this->m_searchPosition.reset(); this->m_searchPosition.reset();
this->m_nextSearchPosition.reset();
} }
ImGui::BeginDisabled(!this->m_searchPosition.has_value()); ImGui::BeginDisabled(!this->m_searchPosition.has_value());
@ -244,10 +256,7 @@ namespace hex::plugin::builtin {
std::optional<Region> findSequence(ViewHexEditor *editor, const std::vector<u8> &sequence, bool backwards) { std::optional<Region> findSequence(ViewHexEditor *editor, const std::vector<u8> &sequence, bool backwards) {
hex::prv::BufferedReader reader(ImHexApi::Provider::get()); hex::prv::BufferedReader reader(ImHexApi::Provider::get());
if (!editor->isSelectionValid()) reader.seek(this->m_searchPosition.value_or(0x00));
reader.seek(this->m_searchPosition.value_or(0x00));
else
reader.seek(this->m_searchPosition.value_or(editor->getSelection().getStartAddress()));
constexpr static auto searchFunction = [](const auto &haystackBegin, const auto &haystackEnd, const auto &needleBegin, const auto &needleEnd) { constexpr static auto searchFunction = [](const auto &haystackBegin, const auto &haystackEnd, const auto &needleBegin, const auto &needleEnd) {
return std::search(haystackBegin, haystackEnd, std::boyer_moore_horspool_searcher(needleBegin, needleEnd)); return std::search(haystackBegin, haystackEnd, std::boyer_moore_horspool_searcher(needleBegin, needleEnd));
@ -256,16 +265,16 @@ namespace hex::plugin::builtin {
if (!backwards) { if (!backwards) {
auto occurrence = searchFunction(reader.begin(), reader.end(), sequence.begin(), sequence.end()); auto occurrence = searchFunction(reader.begin(), reader.end(), sequence.begin(), sequence.end());
if (occurrence != reader.end()) { if (occurrence != reader.end()) {
this->m_searchPosition = occurrence.getAddress() + sequence.size(); this->m_nextSearchPosition = occurrence.getAddress() + sequence.size();
return Region { occurrence.getAddress(), sequence.size() }; return Region { occurrence.getAddress(), sequence.size() };
} }
} else { } else {
auto occurrence = searchFunction(reader.rbegin(), reader.rend(), sequence.begin(), sequence.end()); auto occurrence = searchFunction(reader.rbegin(), reader.rend(), sequence.begin(), sequence.end());
if (occurrence != reader.rend()) { if (occurrence != reader.rend()) {
if (occurrence.getAddress() < sequence.size()) if (occurrence.getAddress() < sequence.size())
this->m_searchPosition = 0x00; this->m_nextSearchPosition = 0x00;
else else
this->m_searchPosition = occurrence.getAddress() - sequence.size(); this->m_nextSearchPosition = occurrence.getAddress() - sequence.size();
return Region { occurrence.getAddress(), sequence.size() }; return Region { occurrence.getAddress(), sequence.size() };
} }
@ -275,7 +284,7 @@ namespace hex::plugin::builtin {
} }
std::string m_input; std::string m_input;
std::optional<u64> m_searchPosition; std::optional<u64> m_searchPosition, m_nextSearchPosition;
bool m_requestFocus = true; bool m_requestFocus = true;
std::atomic<bool> m_shouldSearch = false; std::atomic<bool> m_shouldSearch = false;
@ -1345,6 +1354,12 @@ namespace hex::plugin::builtin {
}); });
EventManager::subscribe<RequestSelectionChange>(this, [this](Region region) { EventManager::subscribe<RequestSelectionChange>(this, [this](Region region) {
if (region == Region::Invalid()) {
this->m_selectionStart = InvalidSelection;
this->m_selectionEnd = InvalidSelection;
return;
}
auto provider = ImHexApi::Provider::get(); auto provider = ImHexApi::Provider::get();
auto page = provider->getPageOfAddress(region.getStartAddress()); auto page = provider->getPageOfAddress(region.getStartAddress());