Use tables to display pattern data
This commit is contained in:
parent
30c0ce8d2c
commit
5b2dc51c07
@ -47,6 +47,7 @@ namespace hex {
|
|||||||
[[nodiscard]] const std::string& getName() const { return this->m_name; }
|
[[nodiscard]] const std::string& getName() const { return this->m_name; }
|
||||||
|
|
||||||
virtual std::string format(prv::Provider* &provider) = 0;
|
virtual std::string format(prv::Provider* &provider) = 0;
|
||||||
|
virtual std::string getTypeName() = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u64 m_offset;
|
u64 m_offset;
|
||||||
@ -67,6 +68,17 @@ namespace hex {
|
|||||||
|
|
||||||
return hex::format("%lu (0x%08lx)", data, data);
|
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 {
|
class PatternDataSigned : public PatternData {
|
||||||
@ -81,6 +93,17 @@ namespace hex {
|
|||||||
|
|
||||||
return hex::format("%ld (0x%08lx)", signedData, data);
|
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 {
|
class PatternDataFloat : public PatternData {
|
||||||
@ -101,6 +124,14 @@ namespace hex {
|
|||||||
|
|
||||||
return hex::format("%f (0x%08lx)", formatData, formatData);
|
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 {
|
class PatternDataCharacter : public PatternData {
|
||||||
@ -113,6 +144,10 @@ namespace hex {
|
|||||||
|
|
||||||
return hex::format("'%c'", character);
|
return hex::format("'%c'", character);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getTypeName() override {
|
||||||
|
return "Character";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PatternDataString : public PatternData {
|
class PatternDataString : public PatternData {
|
||||||
@ -126,6 +161,10 @@ namespace hex {
|
|||||||
|
|
||||||
return hex::format("\"%s\"", makeDisplayable(buffer.data(), this->getSize()).c_str());
|
return hex::format("\"%s\"", makeDisplayable(buffer.data(), this->getSize()).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getTypeName() override {
|
||||||
|
return "String";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PatternDataEnum : public PatternData {
|
class PatternDataEnum : public PatternData {
|
||||||
@ -145,6 +184,10 @@ namespace hex {
|
|||||||
return hex::format("%lu (0x%08lx) : %s::???", value, value, this->m_enumName.c_str());
|
return hex::format("%lu (0x%08lx) : %s::???", value, value, this->m_enumName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getTypeName() override {
|
||||||
|
return "enum " + this->m_enumName;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_enumName;
|
std::string m_enumName;
|
||||||
std::vector<std::pair<u64, std::string>> m_enumValues;
|
std::vector<std::pair<u64, std::string>> m_enumValues;
|
||||||
|
@ -25,6 +25,7 @@ namespace hex {
|
|||||||
private:
|
private:
|
||||||
prv::Provider* &m_dataProvider;
|
prv::Provider* &m_dataProvider;
|
||||||
std::vector<hex::PatternData*> &m_patternData;
|
std::vector<hex::PatternData*> &m_patternData;
|
||||||
|
std::vector<hex::PatternData*> m_sortedPatternData;
|
||||||
bool m_windowOpen = true;
|
bool m_windowOpen = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -113,6 +113,7 @@ namespace hex {
|
|||||||
static hex::lang::Parser parser;
|
static hex::lang::Parser parser;
|
||||||
|
|
||||||
this->clearPatternData();
|
this->clearPatternData();
|
||||||
|
this->postEvent(Events::PatternChanged);
|
||||||
|
|
||||||
auto [lexResult, tokens] = lexer.lex(buffer);
|
auto [lexResult, tokens] = lexer.lex(buffer);
|
||||||
|
|
||||||
@ -196,6 +197,7 @@ namespace hex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(auto &node : ast) delete node;
|
for(auto &node : ast) delete node;
|
||||||
|
this->postEvent(Events::PatternChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 ViewPattern::highlightUsingDecls(std::vector<lang::ASTNode*> &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDecl, u64 offset, std::string name) {
|
s32 ViewPattern::highlightUsingDecls(std::vector<lang::ASTNode*> &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDecl, u64 offset, std::string name) {
|
||||||
@ -205,11 +207,11 @@ namespace hex {
|
|||||||
size_t size = (static_cast<u32>(currTypeDeclNode->getAssignedType()) >> 4);
|
size_t size = (static_cast<u32>(currTypeDeclNode->getAssignedType()) >> 4);
|
||||||
|
|
||||||
if (isUnsigned(currTypeDeclNode->getAssignedType()))
|
if (isUnsigned(currTypeDeclNode->getAssignedType()))
|
||||||
this->addPatternData(new PatternDataUnsigned(offset, size, currTypeDeclNode->getTypeName()));
|
this->addPatternData(new PatternDataUnsigned(offset, size, name));
|
||||||
else if (isSigned(currTypeDeclNode->getAssignedType()))
|
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()))
|
else if (isFloatingPoint(currTypeDeclNode->getAssignedType()))
|
||||||
this->addPatternData(new PatternDataFloat(offset, size, currTypeDeclNode->getTypeName()));
|
this->addPatternData(new PatternDataFloat(offset, size, name));
|
||||||
|
|
||||||
offset += size;
|
offset += size;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,17 +2,18 @@
|
|||||||
|
|
||||||
#include "providers/provider.hpp"
|
#include "providers/provider.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
namespace hex {
|
namespace hex {
|
||||||
|
|
||||||
ViewPatternData::ViewPatternData(prv::Provider* &dataProvider, std::vector<hex::PatternData*> &patternData)
|
ViewPatternData::ViewPatternData(prv::Provider* &dataProvider, std::vector<hex::PatternData*> &patternData)
|
||||||
: View(), m_dataProvider(dataProvider), m_patternData(patternData) {
|
: View(), m_dataProvider(dataProvider), m_patternData(patternData) {
|
||||||
|
|
||||||
|
this->subscribeEvent(Events::PatternChanged, [this](auto data) {
|
||||||
|
this->m_sortedPatternData.clear();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewPatternData::~ViewPatternData() {
|
ViewPatternData::~ViewPatternData() {
|
||||||
|
this->unsubscribeEvent(Events::PatternChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewPatternData::createView() {
|
void ViewPatternData::createView() {
|
||||||
@ -24,12 +25,83 @@ namespace hex {
|
|||||||
|
|
||||||
if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) {
|
if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) {
|
||||||
|
|
||||||
for (auto& patternData : this->m_patternData) {
|
if (ImGui::BeginTable("##patterndatatable", 5, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg)) {
|
||||||
ImGui::LabelText(patternData->getName().c_str(), "[0x%08lx:0x%08lx] %s",
|
ImGui::TableSetupColumn("Name", 0, -1, ImGui::GetID("name"));
|
||||||
patternData->getOffset(),
|
ImGui::TableSetupColumn("Position", 0, -1, ImGui::GetID("position"));
|
||||||
patternData->getOffset() + patternData->getSize(),
|
ImGui::TableSetupColumn("Size", 0, -1, ImGui::GetID("size"));
|
||||||
patternData->format(this->m_dataProvider).c_str());
|
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<u8> 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();
|
ImGui::EndChild();
|
||||||
|
Loading…
Reference in New Issue
Block a user