1
0
mirror of synced 2024-11-28 17:40:51 +01:00

sys: Massively improve string search memory usage

This commit is contained in:
WerWolv 2021-09-06 22:45:55 +02:00
parent ee7c6a91a7
commit 680587e050
2 changed files with 38 additions and 22 deletions

View File

@ -10,7 +10,6 @@ namespace hex {
namespace prv { class Provider; } namespace prv { class Provider; }
struct FoundString { struct FoundString {
std::string string;
u64 offset; u64 offset;
size_t size; size_t size;
}; };
@ -27,8 +26,9 @@ namespace hex {
bool m_searching = false; bool m_searching = false;
std::vector<FoundString> m_foundStrings; std::vector<FoundString> m_foundStrings;
std::vector<size_t> m_filterIndices;
int m_minimumLength = 5; int m_minimumLength = 5;
std::vector<char> m_filter; std::string m_filter;
std::string m_selectedString; std::string m_selectedString;
std::string m_demangledName; std::string m_demangledName;

View File

@ -17,18 +17,25 @@ namespace hex {
this->m_foundStrings.clear(); this->m_foundStrings.clear();
}); });
this->m_filter.resize(0xFFFF, 0x00); this->m_filter.reserve(0xFFFF);
std::memset(this->m_filter.data(), 0x00, this->m_filter.capacity());
} }
ViewStrings::~ViewStrings() { ViewStrings::~ViewStrings() {
EventManager::unsubscribe<EventDataChanged>(this); EventManager::unsubscribe<EventDataChanged>(this);
} }
std::string readString(const FoundString &foundString) {
std::string string(foundString.size + 1, '\0');
SharedData::currentProvider->read(foundString.offset, string.data(), foundString.size);
return string;
}
void ViewStrings::createStringContextMenu(const FoundString &foundString) { void ViewStrings::createStringContextMenu(const FoundString &foundString) {
if (ImGui::TableGetColumnFlags(2) == ImGuiTableColumnFlags_IsHovered && ImGui::IsMouseReleased(1) && ImGui::IsItemHovered()) { if (ImGui::TableGetColumnFlags(2) == ImGuiTableColumnFlags_IsHovered && ImGui::IsMouseReleased(1) && ImGui::IsItemHovered()) {
ImGui::OpenPopup("StringContextMenu"); ImGui::OpenPopup("StringContextMenu");
this->m_selectedString = foundString.string; this->m_selectedString = readString(foundString);
} }
if (ImGui::BeginPopup("StringContextMenu")) { if (ImGui::BeginPopup("StringContextMenu")) {
if (ImGui::MenuItem("hex.view.strings.copy"_lang)) { if (ImGui::MenuItem("hex.view.strings.copy"_lang)) {
@ -46,6 +53,7 @@ namespace hex {
void ViewStrings::searchStrings() { void ViewStrings::searchStrings() {
this->m_foundStrings.clear(); this->m_foundStrings.clear();
this->m_filterIndices.clear();
this->m_searching = true; this->m_searching = true;
std::thread([this] { std::thread([this] {
@ -59,19 +67,17 @@ namespace hex {
provider->readRelative(offset, buffer.data(), readSize); provider->readRelative(offset, buffer.data(), readSize);
for (u32 i = 0; i < readSize; i++) { for (u32 i = 0; i < readSize; i++) {
if (buffer[i] >= 0x20 && buffer[i] <= 0x7E) if (buffer[i] >= ' ' && buffer[i] <= '~' && offset < provider->getSize() - 1)
foundCharacters++; foundCharacters++;
else { else {
if (foundCharacters >= this->m_minimumLength) { if (foundCharacters >= this->m_minimumLength) {
FoundString foundString; FoundString foundString = {
offset + i - foundCharacters + provider->getBaseAddress(),
foundString.offset = offset + i - foundCharacters + provider->getBaseAddress(); foundCharacters
foundString.size = foundCharacters; };
foundString.string.reserve(foundCharacters);
foundString.string.resize(foundCharacters);
provider->read(foundString.offset, foundString.string.data(), foundCharacters);
this->m_foundStrings.push_back(foundString); this->m_foundStrings.push_back(foundString);
this->m_filterIndices.push_back(this->m_foundStrings.size() - 1);
} }
foundCharacters = 0; foundCharacters = 0;
@ -93,7 +99,19 @@ namespace hex {
if (ImGui::InputInt("hex.view.strings.min_length"_lang, &this->m_minimumLength, 1, 0)) if (ImGui::InputInt("hex.view.strings.min_length"_lang, &this->m_minimumLength, 1, 0))
this->m_foundStrings.clear(); this->m_foundStrings.clear();
ImGui::InputText("hex.view.strings.filter"_lang, this->m_filter.data(), this->m_filter.size()); ImGui::InputText("hex.view.strings.filter"_lang, this->m_filter.data(), this->m_filter.capacity(), ImGuiInputTextFlags_CallbackEdit, [](ImGuiInputTextCallbackData *data) {
auto &view = *static_cast<ViewStrings*>(data->UserData);
view.m_filter.resize(data->BufTextLen);
view.m_filterIndices.clear();
for (u64 i = 0; i < view.m_foundStrings.size(); i++) {
if (readString(view.m_foundStrings[i]).find(data->Buf) != std::string::npos)
view.m_filterIndices.push_back(i);
}
return 0;
}, this);
if (ImGui::Button("hex.view.strings.extract"_lang)) if (ImGui::Button("hex.view.strings.extract"_lang))
this->searchStrings(); this->searchStrings();
}, this->m_searching); }, this->m_searching);
@ -132,9 +150,9 @@ namespace hex {
return left.size < right.size; return left.size < right.size;
} else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("string")) { } else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("string")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending) if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left.string > right.string; return readString(left) > readString(right);
else else
return left.string < right.string; return readString(left) < readString(right);
} }
return false; return false;
@ -146,15 +164,12 @@ namespace hex {
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
ImGuiListClipper clipper; ImGuiListClipper clipper;
clipper.Begin(this->m_foundStrings.size()); clipper.Begin(this->m_filterIndices.size());
while (clipper.Step()) { while (clipper.Step()) {
for (u64 i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) { for (u64 i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
auto &foundString = this->m_foundStrings[i]; auto &foundString = this->m_foundStrings[this->m_filterIndices[i]];
auto string = readString(foundString);
if (strlen(this->m_filter.data()) != 0 &&
foundString.string.find(this->m_filter.data()) == std::string::npos)
continue;
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
@ -169,7 +184,8 @@ namespace hex {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("0x%04lx", foundString.size); ImGui::Text("0x%04lx", foundString.size);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%s", foundString.string.c_str());
ImGui::Text("%s", string.c_str());
} }
} }
clipper.End(); clipper.End();