diff --git a/include/views/pattern_data.hpp b/include/views/pattern_data.hpp index 9422d8d98..1f5c2a5b9 100644 --- a/include/views/pattern_data.hpp +++ b/include/views/pattern_data.hpp @@ -47,6 +47,7 @@ namespace hex { [[nodiscard]] const std::string& getName() const { return this->m_name; } virtual std::string format(prv::Provider* &provider) = 0; + virtual std::string getTypeName() = 0; private: u64 m_offset; @@ -67,6 +68,17 @@ namespace hex { return hex::format("%lu (0x%08lx)", data, data); } + + std::string getTypeName() override { + switch (this->getSize()) { + case 1: return "u8"; + case 2: return "u16"; + case 4: return "u32"; + case 8: return "u64"; + case 16: return "u128"; + default: return "Unsigned data"; + } + } }; class PatternDataSigned : public PatternData { @@ -81,6 +93,17 @@ namespace hex { return hex::format("%ld (0x%08lx)", signedData, data); } + + std::string getTypeName() override { + switch (this->getSize()) { + case 1: return "s8"; + case 2: return "s16"; + case 4: return "s32"; + case 8: return "s64"; + case 16: return "s128"; + default: return "Signed data"; + } + } }; class PatternDataFloat : public PatternData { @@ -101,6 +124,14 @@ namespace hex { return hex::format("%f (0x%08lx)", formatData, formatData); } + + std::string getTypeName() override { + switch (this->getSize()) { + case 4: return "float"; + case 8: return "double"; + default: return "Floating point data"; + } + } }; class PatternDataCharacter : public PatternData { @@ -113,6 +144,10 @@ namespace hex { return hex::format("'%c'", character); } + + std::string getTypeName() override { + return "Character"; + } }; class PatternDataString : public PatternData { @@ -126,6 +161,10 @@ namespace hex { return hex::format("\"%s\"", makeDisplayable(buffer.data(), this->getSize()).c_str()); } + + std::string getTypeName() override { + return "String"; + } }; class PatternDataEnum : public PatternData { @@ -145,6 +184,10 @@ namespace hex { return hex::format("%lu (0x%08lx) : %s::???", value, value, this->m_enumName.c_str()); } + std::string getTypeName() override { + return "enum " + this->m_enumName; + } + private: std::string m_enumName; std::vector> m_enumValues; diff --git a/include/views/view_pattern_data.hpp b/include/views/view_pattern_data.hpp index 85c265b74..b8359302d 100644 --- a/include/views/view_pattern_data.hpp +++ b/include/views/view_pattern_data.hpp @@ -25,6 +25,7 @@ namespace hex { private: prv::Provider* &m_dataProvider; std::vector &m_patternData; + std::vector m_sortedPatternData; bool m_windowOpen = true; }; diff --git a/source/views/view_pattern.cpp b/source/views/view_pattern.cpp index bd5034cfb..fe592c0ad 100644 --- a/source/views/view_pattern.cpp +++ b/source/views/view_pattern.cpp @@ -113,6 +113,7 @@ namespace hex { static hex::lang::Parser parser; this->clearPatternData(); + this->postEvent(Events::PatternChanged); auto [lexResult, tokens] = lexer.lex(buffer); @@ -196,6 +197,7 @@ namespace hex { } for(auto &node : ast) delete node; + this->postEvent(Events::PatternChanged); } s32 ViewPattern::highlightUsingDecls(std::vector &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDecl, u64 offset, std::string name) { @@ -205,11 +207,11 @@ namespace hex { size_t size = (static_cast(currTypeDeclNode->getAssignedType()) >> 4); if (isUnsigned(currTypeDeclNode->getAssignedType())) - this->addPatternData(new PatternDataUnsigned(offset, size, currTypeDeclNode->getTypeName())); + this->addPatternData(new PatternDataUnsigned(offset, size, name)); else if (isSigned(currTypeDeclNode->getAssignedType())) - this->addPatternData(new PatternDataSigned(offset, size, currTypeDeclNode->getTypeName())); + this->addPatternData(new PatternDataSigned(offset, size, name)); else if (isFloatingPoint(currTypeDeclNode->getAssignedType())) - this->addPatternData(new PatternDataFloat(offset, size, currTypeDeclNode->getTypeName())); + this->addPatternData(new PatternDataFloat(offset, size, name)); offset += size; } else { diff --git a/source/views/view_pattern_data.cpp b/source/views/view_pattern_data.cpp index f527fad58..0da14385c 100644 --- a/source/views/view_pattern_data.cpp +++ b/source/views/view_pattern_data.cpp @@ -2,17 +2,18 @@ #include "providers/provider.hpp" -#include - namespace hex { ViewPatternData::ViewPatternData(prv::Provider* &dataProvider, std::vector &patternData) : View(), m_dataProvider(dataProvider), m_patternData(patternData) { + this->subscribeEvent(Events::PatternChanged, [this](auto data) { + this->m_sortedPatternData.clear(); + }); } ViewPatternData::~ViewPatternData() { - + this->unsubscribeEvent(Events::PatternChanged); } void ViewPatternData::createView() { @@ -24,12 +25,83 @@ namespace hex { if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) { - for (auto& patternData : this->m_patternData) { - ImGui::LabelText(patternData->getName().c_str(), "[0x%08lx:0x%08lx] %s", - patternData->getOffset(), - patternData->getOffset() + patternData->getSize(), - patternData->format(this->m_dataProvider).c_str()); + if (ImGui::BeginTable("##patterndatatable", 5, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg)) { + ImGui::TableSetupColumn("Name", 0, -1, ImGui::GetID("name")); + ImGui::TableSetupColumn("Position", 0, -1, ImGui::GetID("position")); + ImGui::TableSetupColumn("Size", 0, -1, ImGui::GetID("size")); + ImGui::TableSetupColumn("Type", 0, -1, ImGui::GetID("type")); + ImGui::TableSetupColumn("Value", 0, -1, ImGui::GetID("value")); + + auto sortSpecs = ImGui::TableGetSortSpecs(); + + if (sortSpecs->SpecsDirty || this->m_sortedPatternData.empty()) { + this->m_sortedPatternData = this->m_patternData; + + std::sort(this->m_sortedPatternData.begin(), this->m_sortedPatternData.end(), [this, &sortSpecs](PatternData* left, PatternData* right) -> bool { + if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("name")) { + if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending) + return left->getName() > right->getName(); + else + return left->getName() < right->getName(); + } + else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("position")) { + if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending) + return left->getOffset() > right->getOffset(); + else + return left->getOffset() < right->getOffset(); + } + else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("size")) { + if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending) + return left->getSize() > right->getSize(); + else + return left->getSize() < right->getSize(); + } + else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("value")) { + size_t biggerSize = std::max(left->getSize(), right->getSize()); + std::vector leftBuffer(biggerSize, 0x00), rightBuffer(biggerSize, 0x00); + + this->m_dataProvider->read(left->getOffset(), leftBuffer.data(), left->getSize()); + this->m_dataProvider->read(right->getOffset(), rightBuffer.data(), right->getSize()); + + if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending) + return leftBuffer > rightBuffer; + else + return leftBuffer < rightBuffer; + } + else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("type")) { + if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending) + return left->getTypeName() > right->getTypeName(); + else + return left->getTypeName() < right->getTypeName(); + } + + return false; + }); + + sortSpecs->SpecsDirty = false; + } + + ImGui::TableHeadersRow(); + u32 rowCount = 0; + for (auto& patternData : this->m_sortedPatternData) { + ImGui::TableNextRow(ImGuiTableRowFlags_Headers); + ImGui::TableNextColumn(); + ImGui::Text("%s", patternData->getName().c_str()); + ImGui::TableNextColumn(); + ImGui::Text("0x%08lx : 0x%08lx", patternData->getOffset(), patternData->getOffset() + patternData->getSize()); + ImGui::TableNextColumn(); + ImGui::Text("0x%08lx", patternData->getSize()); + ImGui::TableNextColumn(); + ImGui::Text("%s", patternData->getTypeName().c_str()); + ImGui::TableNextColumn(); + ImGui::Text("%s", patternData->format(this->m_dataProvider).c_str()); + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, ((rowCount % 2) == 0) ? 0xFF101010 : 0xFF303030); + rowCount++; + } + + ImGui::EndTable(); } + } ImGui::EndChild();