Refactor, added a pattern data display

This commit is contained in:
WerWolv
2020-11-10 21:31:04 +01:00
parent 01b4ac8661
commit 35946564a6
13 changed files with 481 additions and 317 deletions

View File

@@ -0,0 +1,20 @@
#pragma once
#include <hex.hpp>
#include <string>
namespace hex {
struct Highlight {
Highlight(u64 offset, size_t size, u32 color, std::string name)
: offset(offset), size(size), color(color), name(name) {
}
u64 offset;
size_t size;
u32 color;
std::string name;
};
}

View File

@@ -12,106 +12,25 @@
#include <random>
#include <vector>
#include "views/highlight.hpp"
namespace hex {
class ViewHexEditor : public View {
public:
ViewHexEditor() : View() {
this->m_memoryEditor.ReadFn = [](const ImU8* data, size_t off) -> ImU8 {
ViewHexEditor *_this = (ViewHexEditor*)data;
ViewHexEditor(FILE* &file, std::vector<Highlight> &highlights);
virtual ~ViewHexEditor();
if (_this->m_file == nullptr)
return 0x00;
fseek(_this->m_file, off, SEEK_SET);
ImU8 byte;
fread(&byte, sizeof(ImU8), 1, _this->m_file);
return byte;
};
this->m_memoryEditor.WriteFn = [](ImU8* data, size_t off, ImU8 d) -> void {
ViewHexEditor *_this = (ViewHexEditor*)data;
if (_this->m_file == nullptr)
return;
fseek(_this->m_file, off, SEEK_SET);
fwrite(&d, sizeof(ImU8), 1, _this->m_file);
};
this->m_memoryEditor.HighlightFn = [](const ImU8* data, size_t off, bool next) -> bool {
ViewHexEditor *_this = (ViewHexEditor*)data;
for (auto& [offset, size, color] : _this->m_highlights) {
if (next && off == (offset + size)) {
return false;
}
if (off >= offset && off < (offset + size)) {
_this->m_memoryEditor.HighlightColor = color;
return true;
}
}
_this->m_memoryEditor.HighlightColor = 0x50C08080;
return false;
};
}
virtual ~ViewHexEditor() { }
virtual void createView() override {
this->m_memoryEditor.DrawWindow("Hex Editor", this, this->m_file == nullptr ? 0x00 : this->m_fileSize);
}
virtual void createMenu() override {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Open File...")) {
auto filePath = openFileDialog();
if (filePath.has_value()) {
if (this->m_file != nullptr)
fclose(this->m_file);
this->m_file = fopen(filePath->c_str(), "r+b");
fseek(this->m_file, 0, SEEK_END);
this->m_fileSize = ftell(this->m_file);
rewind(this->m_file);
}
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Window")) {
ImGui::MenuItem("Hex View", "", &this->m_memoryEditor.Open);
ImGui::EndMenu();
}
}
void setHighlight(u64 offset, size_t size, u32 color = 0) {
if (color == 0)
color = std::mt19937(std::random_device()())();
color |= 0xFF00'0000;
this->m_highlights.emplace_back(offset, size, color);
}
void clearHighlights() {
this->m_highlights.clear();
}
virtual void createView() override;
virtual void createMenu() override;
private:
MemoryEditor m_memoryEditor;
FILE *m_file = nullptr;
FILE* &m_file;
size_t m_fileSize = 0;
std::vector<std::tuple<u64, size_t, u32>> m_highlights;
std::vector<Highlight> &m_highlights;
};
}

View File

@@ -8,207 +8,30 @@
#include <concepts>
#include <cstring>
#include "views/view_hexeditor.hpp"
#include "views/highlight.hpp"
namespace hex {
class ViewPattern : public View {
public:
ViewPattern(ViewHexEditor *hexEditor) : View(), m_hexEditor(hexEditor) {
this->m_buffer = new char[0xFFFFFF];
std::memset(this->m_buffer, 0x00, 0xFFFFFF);
}
virtual ~ViewPattern() {
delete[] this->m_buffer;
}
ViewPattern(std::vector<Highlight> &highlights);
virtual ~ViewPattern();
virtual void createMenu() {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Load pattern...")) {
auto filePath = openFileDialog();
if (filePath.has_value()) {
FILE *file = fopen(filePath->c_str(), "r+b");
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
rewind(file);
if (size > 0xFF'FFFF)
return;
fread(this->m_buffer, size, 1, file);
fclose(file);
this->parsePattern(this->m_buffer);
}
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Window")) {
ImGui::MenuItem("Pattern View", "", &this->m_windowOpen);
ImGui::EndMenu();
}
}
void createView() override {
if (!this->m_windowOpen)
return;
ImGui::Begin("Pattern", &this->m_windowOpen, ImGuiWindowFlags_None);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
auto size = ImGui::GetWindowSize();
size.y -= 50;
ImGui::InputTextMultiline("Pattern", this->m_buffer, 0xFFFF, size, ImGuiInputTextFlags_AllowTabInput | ImGuiInputTextFlags_CallbackEdit,
[](ImGuiInputTextCallbackData* data) -> int {
auto _this = static_cast<ViewPattern*>(data->UserData);
_this->parsePattern(data->Buf);
return 0;
}, this
);
ImGui::PopStyleVar(2);
ImGui::End();
}
virtual void createMenu() override;
virtual void createView() override;
private:
char *m_buffer;
ViewHexEditor *m_hexEditor;
std::vector<Highlight> &m_highlights;
bool m_windowOpen = true;
void parsePattern(char *buffer) {
static hex::lang::Lexer lexer;
static hex::lang::Parser parser;
this->m_hexEditor->clearHighlights();
void setHighlight(u64 offset, size_t size, std::string name, u32 color = 0);
void parsePattern(char *buffer);
auto [lexResult, tokens] = lexer.lex(buffer);
if (lexResult.failed()) {
return;
}
auto [parseResult, ast] = parser.parse(tokens);
if (parseResult.failed()) {
for(auto &node : ast) delete node;
return;
}
for (auto &varNode : this->findNodes<lang::ASTNodeVariableDecl>(lang::ASTNode::Type::VariableDecl, ast)) {
if (!varNode->getOffset().has_value())
continue;
u64 offset = varNode->getOffset().value();
if (varNode->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
this->m_hexEditor->setHighlight(offset, static_cast<u32>(varNode->getVariableType()) >> 4);
} else {
for (auto &structNode : this->findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast))
if (varNode->getCustomVariableTypeName() == structNode->getName())
if (this->highlightStruct(ast, structNode, offset) == -1)
this->m_hexEditor->clearHighlights();
for (auto &usingNode : this->findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast))
if (varNode->getCustomVariableTypeName() == usingNode->getTypeName())
if (this->highlightUsingDecls(ast, usingNode, offset) == -1)
this->m_hexEditor->clearHighlights();
}
}
for(auto &node : ast) delete node;
}
template<std::derived_from<lang::ASTNode> T>
std::vector<T*> findNodes(const lang::ASTNode::Type type, const std::vector<lang::ASTNode*> &nodes) const noexcept {
std::vector<T*> result;
for (const auto & node : nodes)
if (node->getType() == type)
result.push_back(static_cast<T*>(node));
return result;
}
s32 highlightUsingDecls(std::vector<lang::ASTNode*> &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, u64 offset) {
if (currTypeDeclNode->getAssignedType() != lang::Token::TypeToken::Type::CustomType) {
size_t size = static_cast<u32>(currTypeDeclNode->getAssignedType()) >> 4;
this->m_hexEditor->setHighlight(offset, size);
offset += size;
} else {
bool foundType = false;
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast))
if (structNode->getName() == currTypeDeclNode->getAssignedCustomTypeName()) {
offset = this->highlightStruct(ast, structNode, offset);
foundType = true;
break;
}
for (auto &typeDeclNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast))
if (typeDeclNode->getTypeName() == currTypeDeclNode->getAssignedCustomTypeName()) {
offset = this->highlightUsingDecls(ast, typeDeclNode, offset);
foundType = true;
break;
}
if (!foundType)
return -1;
}
return offset;
}
s32 highlightStruct(std::vector<lang::ASTNode*> &ast, lang::ASTNodeStruct* currStructNode, u64 offset) {
u64 startOffset = offset;
for (auto &node : currStructNode->getNodes()) {
auto var = static_cast<lang::ASTNodeVariableDecl*>(node);
if (var->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
size_t size = static_cast<u32>(var->getVariableType()) >> 4;
this->m_hexEditor->setHighlight(offset, size);
offset += size;
} else {
bool foundType = false;
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast))
if (structNode->getName() == var->getCustomVariableTypeName()) {
auto size = this->highlightStruct(ast, structNode, offset);
if (size == -1)
return -1;
offset += size;
foundType = true;
break;
}
for (auto &typeDeclNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast))
if (typeDeclNode->getTypeName() == var->getCustomVariableTypeName()) {
auto size = this->highlightUsingDecls(ast, typeDeclNode, offset);
if (size == -1)
return -1;
offset = size;
foundType = true;
break;
}
if (!foundType)
return -1;
}
}
return offset - startOffset;
}
s32 highlightUsingDecls(std::vector<lang::ASTNode*> &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDec, u64 offset);
s32 highlightStruct(std::vector<lang::ASTNode*> &ast, lang::ASTNodeStruct* currStructNode, u64 offset);
};
}

View File

@@ -0,0 +1,29 @@
#pragma once
#include <hex.hpp>
#include "imgui.h"
#include "views/view.hpp"
#include "views/highlight.hpp"
#include <vector>
#include <tuple>
#include <cstdio>
namespace hex {
class ViewPatternData : public View {
public:
ViewPatternData(FILE* &file,std::vector<Highlight> &highlights);
virtual ~ViewPatternData();
virtual void createView() override;
virtual void createMenu() override;
private:
FILE* &m_file;
std::vector<Highlight> &m_highlights;
bool m_windowOpen = true;
};
}