diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 000000000..94a25f7f4 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f10efcfbb..3df06bcd2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/include/utils.hpp b/include/utils.hpp index be66814ce..4d056f60f 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -10,42 +10,6 @@ namespace hex { - std::optional 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(&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, wchar_t> converter; - - std::string result = converter.to_bytes(pszFilePath); - - CoTaskMemFree(pszFilePath); - - return result; - } - pItem->Release(); - } - } - pFileOpen->Release(); - } - CoUninitialize(); - } - - return { }; - } + std::optional openFileDialog(); } \ No newline at end of file diff --git a/include/views/highlight.hpp b/include/views/highlight.hpp new file mode 100644 index 000000000..3c21fffb5 --- /dev/null +++ b/include/views/highlight.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +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; + }; + +} \ No newline at end of file diff --git a/include/views/view_hexeditor.hpp b/include/views/view_hexeditor.hpp index 51740cbf4..4c984f350 100644 --- a/include/views/view_hexeditor.hpp +++ b/include/views/view_hexeditor.hpp @@ -12,106 +12,25 @@ #include #include +#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 &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> m_highlights; + std::vector &m_highlights; }; } \ No newline at end of file diff --git a/include/views/view_pattern.hpp b/include/views/view_pattern.hpp index 7bc7d26ab..2c013b872 100644 --- a/include/views/view_pattern.hpp +++ b/include/views/view_pattern.hpp @@ -8,207 +8,30 @@ #include #include -#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 &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(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 &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::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(varNode->getVariableType()) >> 4); - } else { - for (auto &structNode : this->findNodes(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::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 T> - std::vector findNodes(const lang::ASTNode::Type type, const std::vector &nodes) const noexcept { - std::vector result; - - for (const auto & node : nodes) - if (node->getType() == type) - result.push_back(static_cast(node)); - - return result; - } - - s32 highlightUsingDecls(std::vector &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, u64 offset) { - if (currTypeDeclNode->getAssignedType() != lang::Token::TypeToken::Type::CustomType) { - size_t size = static_cast(currTypeDeclNode->getAssignedType()) >> 4; - - this->m_hexEditor->setHighlight(offset, size); - offset += size; - } else { - bool foundType = false; - for (auto &structNode : findNodes(lang::ASTNode::Type::Struct, ast)) - if (structNode->getName() == currTypeDeclNode->getAssignedCustomTypeName()) { - offset = this->highlightStruct(ast, structNode, offset); - foundType = true; - break; - } - - for (auto &typeDeclNode : findNodes(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 &ast, lang::ASTNodeStruct* currStructNode, u64 offset) { - u64 startOffset = offset; - - for (auto &node : currStructNode->getNodes()) { - auto var = static_cast(node); - - if (var->getVariableType() != lang::Token::TypeToken::Type::CustomType) { - size_t size = static_cast(var->getVariableType()) >> 4; - - this->m_hexEditor->setHighlight(offset, size); - offset += size; - } else { - bool foundType = false; - for (auto &structNode : findNodes(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::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 &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDec, u64 offset); + s32 highlightStruct(std::vector &ast, lang::ASTNodeStruct* currStructNode, u64 offset); }; } \ No newline at end of file diff --git a/include/views/view_pattern_data.hpp b/include/views/view_pattern_data.hpp new file mode 100644 index 000000000..91294ed0c --- /dev/null +++ b/include/views/view_pattern_data.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include "imgui.h" +#include "views/view.hpp" +#include "views/highlight.hpp" + +#include +#include +#include + +namespace hex { + + class ViewPatternData : public View { + public: + ViewPatternData(FILE* &file,std::vector &highlights); + virtual ~ViewPatternData(); + + virtual void createView() override; + virtual void createMenu() override; + + private: + FILE* &m_file; + std::vector &m_highlights; + bool m_windowOpen = true; + }; + +} \ No newline at end of file diff --git a/include/window.hpp b/include/window.hpp index 093caee11..8ade17b98 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -18,8 +18,8 @@ namespace hex { void loop(); template 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)...)); return static_cast(this->m_views.back()); } diff --git a/source/main.cpp b/source/main.cpp index 7d387eea0..6cfa41889 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -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 +#include int main() { hex::Window window; - auto* hexEditor = window.addView(); - window.addView(hexEditor); + // Shared Data + std::vector highlights; + FILE *file = nullptr; + + // Create views + window.addView(file, highlights); + window.addView(highlights); + window.addView(file, highlights); window.loop(); diff --git a/source/utils.cpp b/source/utils.cpp new file mode 100644 index 000000000..e5f3d519a --- /dev/null +++ b/source/utils.cpp @@ -0,0 +1,43 @@ +#include "utils.hpp" + +namespace hex { + + std::optional 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(&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, wchar_t> converter; + + std::string result = converter.to_bytes(pszFilePath); + + CoTaskMemFree(pszFilePath); + + return result; + } + pItem->Release(); + } + } + pFileOpen->Release(); + } + CoUninitialize(); + } + + return { }; + } + +} \ No newline at end of file diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp new file mode 100644 index 000000000..01d7aed6d --- /dev/null +++ b/source/views/view_hexeditor.cpp @@ -0,0 +1,85 @@ +#include "views/view_hexeditor.hpp" + +namespace hex { + + ViewHexEditor::ViewHexEditor(FILE *&file, std::vector &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(); + } + } + +} \ No newline at end of file diff --git a/source/views/view_pattern.cpp b/source/views/view_pattern.cpp new file mode 100644 index 000000000..f3568ee11 --- /dev/null +++ b/source/views/view_pattern.cpp @@ -0,0 +1,210 @@ +#include +#include "views/view_pattern.hpp" + +#include "utils.hpp" + +namespace hex { + + ViewPattern::ViewPattern(std::vector &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(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 T> + static std::vector findNodes(const lang::ASTNode::Type type, const std::vector &nodes) { + std::vector result; + + for (const auto & node : nodes) + if (node->getType() == type) + result.push_back(static_cast(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::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(varNode->getVariableType()) >> 4, varNode->getVariableName()); + } else { + for (auto &structNode : findNodes(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::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 &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDecl, u64 offset) { + if (currTypeDeclNode->getAssignedType() != lang::Token::TypeToken::Type::CustomType) { + size_t size = static_cast(currTypeDeclNode->getAssignedType()) >> 4; + + this->setHighlight(offset, size, currVarDecl->getVariableName()); + offset += size; + } else { + bool foundType = false; + for (auto &structNode : findNodes(lang::ASTNode::Type::Struct, ast)) + if (structNode->getName() == currTypeDeclNode->getAssignedCustomTypeName()) { + offset = this->highlightStruct(ast, structNode, offset); + foundType = true; + break; + } + + for (auto &typeDeclNode : findNodes(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 &ast, lang::ASTNodeStruct* currStructNode, u64 offset) { + u64 startOffset = offset; + + for (auto &node : currStructNode->getNodes()) { + auto var = static_cast(node); + + if (var->getVariableType() != lang::Token::TypeToken::Type::CustomType) { + size_t size = static_cast(var->getVariableType()) >> 4; + + this->setHighlight(offset, size, var->getVariableName()); + offset += size; + } else { + bool foundType = false; + for (auto &structNode : findNodes(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::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; + } + +} \ No newline at end of file diff --git a/source/views/view_pattern_data.cpp b/source/views/view_pattern_data.cpp new file mode 100644 index 000000000..b3129bc04 --- /dev/null +++ b/source/views/view_pattern_data.cpp @@ -0,0 +1,49 @@ +#include "views/view_pattern_data.hpp" + +#include + +namespace hex { + + ViewPatternData::ViewPatternData(FILE* &file, std::vector &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 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(); + } + } + +} \ No newline at end of file