1
0
mirror of synced 2025-02-20 04:01:01 +01:00

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

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -13,10 +13,15 @@ SET(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -mwindows)
add_executable(ImHex WIN32
source/main.cpp
source/window.cpp
source/utils.cpp
source/parser/lexer.cpp
source/parser/parser.cpp
source/views/view_hexeditor.cpp
source/views/view_pattern.cpp
source/views/view_pattern_data.cpp
libs/glad/source/glad.c
libs/ImGui/source/imgui.cpp

View File

@ -10,42 +10,6 @@
namespace hex {
std::optional<std::string> openFileDialog() {
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr)) {
IFileOpenDialog *pFileOpen;
hr = CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_ALL, IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr)) {
hr = pFileOpen->Show(nullptr);
if (SUCCEEDED(hr)) {
IShellItem *pItem;
hr = pFileOpen->GetResult(&pItem);
if (SUCCEEDED(hr)) {
PWSTR pszFilePath;
hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
if (SUCCEEDED(hr)) {
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
std::string result = converter.to_bytes(pszFilePath);
CoTaskMemFree(pszFilePath);
return result;
}
pItem->Release();
}
}
pFileOpen->Release();
}
CoUninitialize();
}
return { };
}
std::optional<std::string> openFileDialog();
}

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;
};
}

View File

@ -18,8 +18,8 @@ namespace hex {
void loop();
template<std::derived_from<View> T, typename ... Args>
T* addView(Args& ... args) {
this->m_views.emplace_back(new T(args...));
T* addView(Args&& ... args) {
this->m_views.emplace_back(new T(std::forward<Args>(args)...));
return static_cast<T*>(this->m_views.back());
}

View File

@ -1,13 +1,24 @@
#include "window.hpp"
#include "views/highlight.hpp"
#include "views/view_hexeditor.hpp"
#include "views/view_pattern.hpp"
#include "views/view_pattern_data.hpp"
#include <tuple>
#include <vector>
int main() {
hex::Window window;
auto* hexEditor = window.addView<hex::ViewHexEditor>();
window.addView<hex::ViewPattern>(hexEditor);
// Shared Data
std::vector<hex::Highlight> highlights;
FILE *file = nullptr;
// Create views
window.addView<hex::ViewHexEditor>(file, highlights);
window.addView<hex::ViewPattern>(highlights);
window.addView<hex::ViewPatternData>(file, highlights);
window.loop();

43
source/utils.cpp Normal file
View File

@ -0,0 +1,43 @@
#include "utils.hpp"
namespace hex {
std::optional<std::string> openFileDialog() {
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr)) {
IFileOpenDialog *pFileOpen;
hr = CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_ALL, IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr)) {
hr = pFileOpen->Show(nullptr);
if (SUCCEEDED(hr)) {
IShellItem *pItem;
hr = pFileOpen->GetResult(&pItem);
if (SUCCEEDED(hr)) {
PWSTR pszFilePath;
hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
if (SUCCEEDED(hr)) {
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
std::string result = converter.to_bytes(pszFilePath);
CoTaskMemFree(pszFilePath);
return result;
}
pItem->Release();
}
}
pFileOpen->Release();
}
CoUninitialize();
}
return { };
}
}

View File

@ -0,0 +1,85 @@
#include "views/view_hexeditor.hpp"
namespace hex {
ViewHexEditor::ViewHexEditor(FILE *&file, std::vector<Highlight> &highlights)
: View(), m_file(file), m_highlights(highlights) {
this->m_memoryEditor.ReadFn = [](const ImU8 *data, size_t off) -> ImU8 {
ViewHexEditor *_this = (ViewHexEditor *) data;
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, name] : _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;
};
}
ViewHexEditor::~ViewHexEditor() {}
void ViewHexEditor::createView() {
this->m_memoryEditor.DrawWindow("Hex Editor", this, this->m_file == nullptr ? 0x00 : this->m_fileSize);
}
void ViewHexEditor::createMenu() {
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();
}
}
}

View File

@ -0,0 +1,210 @@
#include <random>
#include "views/view_pattern.hpp"
#include "utils.hpp"
namespace hex {
ViewPattern::ViewPattern(std::vector<Highlight> &highlights) : View(), m_highlights(highlights) {
this->m_buffer = new char[0xFFFFFF];
std::memset(this->m_buffer, 0x00, 0xFFFFFF);
}
ViewPattern::~ViewPattern() {
delete[] this->m_buffer;
}
void ViewPattern::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 ViewPattern::createView() {
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();
}
void ViewPattern::setHighlight(u64 offset, size_t size, std::string name, u32 color) {
if (color == 0)
color = std::mt19937(std::random_device()())();
color &= ~0xFF00'0000;
color |= 0x5000'0000;
this->m_highlights.emplace_back(offset, size, color, name);
}
template<std::derived_from<lang::ASTNode> T>
static std::vector<T*> findNodes(const lang::ASTNode::Type type, const std::vector<lang::ASTNode*> &nodes) {
std::vector<T*> result;
for (const auto & node : nodes)
if (node->getType() == type)
result.push_back(static_cast<T*>(node));
return result;
}
void ViewPattern::parsePattern(char *buffer) {
static hex::lang::Lexer lexer;
static hex::lang::Parser parser;
this->m_highlights.clear();
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 : 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->setHighlight(offset, static_cast<u32>(varNode->getVariableType()) >> 4, varNode->getVariableName());
} else {
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast))
if (varNode->getCustomVariableTypeName() == structNode->getName())
if (this->highlightStruct(ast, structNode, offset) == -1)
this->m_highlights.clear();
for (auto &usingNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast))
if (varNode->getCustomVariableTypeName() == usingNode->getTypeName())
if (this->highlightUsingDecls(ast, usingNode, varNode, offset) == -1)
this->m_highlights.clear();
}
}
for(auto &node : ast) delete node;
}
s32 ViewPattern::highlightUsingDecls(std::vector<lang::ASTNode*> &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDecl, u64 offset) {
if (currTypeDeclNode->getAssignedType() != lang::Token::TypeToken::Type::CustomType) {
size_t size = static_cast<u32>(currTypeDeclNode->getAssignedType()) >> 4;
this->setHighlight(offset, size, currVarDecl->getVariableName());
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, currVarDecl, offset);
foundType = true;
break;
}
if (!foundType)
return -1;
}
return offset;
}
s32 ViewPattern::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->setHighlight(offset, size, var->getVariableName());
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, var, offset);
if (size == -1)
return -1;
offset = size;
foundType = true;
break;
}
if (!foundType)
return -1;
}
}
return offset - startOffset;
}
}

View File

@ -0,0 +1,49 @@
#include "views/view_pattern_data.hpp"
#include <cstring>
namespace hex {
ViewPatternData::ViewPatternData(FILE* &file, std::vector<Highlight> &highlights)
: View(), m_file(file), m_highlights(highlights) {
}
ViewPatternData::~ViewPatternData() {
}
void ViewPatternData::createView() {
if (!this->m_windowOpen)
return;
if (ImGui::Begin("Pattern Data", &this->m_windowOpen)) {
ImGui::BeginChild("##scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav);
for (auto& [offset, size, color, name] : this->m_highlights) {
std::vector<u8> buffer(size + 1, 0x00);
u64 data = 0;
fseek(this->m_file, offset, SEEK_SET);
fread(buffer.data(), 1, size, this->m_file);
std::memcpy(&data, buffer.data(), size);
if (size <= 8)
ImGui::LabelText(name.c_str(), "[0x%08lx:0x%08lx] %lu (0x%lx) \"%s\"", offset, offset + size, data, data, buffer.data());
else
ImGui::LabelText(name.c_str(), "[0x%08lx:0x%08lx] [ ARRAY ]", offset, offset + size);
}
ImGui::EndChild();
ImGui::End();
}
}
void ViewPatternData::createMenu() {
if (ImGui::BeginMenu("Window")) {
ImGui::MenuItem("Data View", "", &this->m_windowOpen);
ImGui::EndMenu();
}
}
}