diff --git a/CMakeLists.txt b/CMakeLists.txt index ecb1595d2..2fc266f0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,7 @@ add_executable(imhex ${application_type} source/views/view_settings.cpp source/views/view_data_processor.cpp source/views/view_yara.cpp + source/views/view_constants.cpp ${imhex_icon} ) diff --git a/include/views/view_constants.hpp b/include/views/view_constants.hpp new file mode 100644 index 000000000..8505aab93 --- /dev/null +++ b/include/views/view_constants.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include + +#include +#include + +namespace hex { + + enum class ConstantType { + Int10, + Int16BigEndian, + Int16LittleEndian + }; + + struct Constant { + std::string name, description; + std::string category; + ConstantType type; + std::string value; + }; + + class ViewConstants : public View { + public: + explicit ViewConstants(); + ~ViewConstants() override; + + void drawContent() override; + void drawMenu() override; + + private: + void reloadConstants(); + + std::vector m_constants; + std::vector m_filteredConstants; + std::string m_search; + }; + +} \ No newline at end of file diff --git a/plugins/libimhex/include/hex/helpers/utils.hpp b/plugins/libimhex/include/hex/helpers/utils.hpp index ec151b348..a42b1f59b 100644 --- a/plugins/libimhex/include/hex/helpers/utils.hpp +++ b/plugins/libimhex/include/hex/helpers/utils.hpp @@ -229,7 +229,8 @@ namespace hex { Plugins, Yara, Config, - Resources + Resources, + Constants }; std::vector getPath(ImHexPath path); diff --git a/plugins/libimhex/source/helpers/utils.cpp b/plugins/libimhex/source/helpers/utils.cpp index ac5e50bbb..03aa0a1e8 100644 --- a/plugins/libimhex/source/helpers/utils.cpp +++ b/plugins/libimhex/source/helpers/utils.cpp @@ -222,6 +222,8 @@ namespace hex { return { (appDataDir / "imhex" / "config").string() }; case ImHexPath::Resources: return { (parentDir / "resources").string() }; + case ImHexPath::Constants: + return { (parentDir / "constants").string() }; default: __builtin_unreachable(); } #elif defined(OS_MACOS) @@ -268,6 +270,10 @@ namespace hex { std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "imhex" / "resources").string(); }); return result; + case ImHexPath::Constants: + std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), + [](auto p) { return (p / "imhex" / "constants").string(); }); + return result; default: __builtin_unreachable(); } #endif diff --git a/plugins/libimhex/source/helpers/utils_mac.mm b/plugins/libimhex/source/helpers/utils_mac.mm index 4ce16147c..568e0368c 100644 --- a/plugins/libimhex/source/helpers/utils_mac.mm +++ b/plugins/libimhex/source/helpers/utils_mac.mm @@ -43,6 +43,9 @@ case ImHexPath::Resources: result = [appSupportDir URLByAppendingPathComponent:@"imhex/resources"]; break; + case ImHexPath::Constants: + result = [appSupportDir URLByAppendingPathComponent:@"imhex/constants"]; + break; } if (result == nil) { diff --git a/source/init/tasks.cpp b/source/init/tasks.cpp index 7a28d4592..89cfd8681 100644 --- a/source/init/tasks.cpp +++ b/source/init/tasks.cpp @@ -20,6 +20,7 @@ #include "views/view_settings.hpp" #include "views/view_data_processor.hpp" #include "views/view_yara.hpp" +#include "views/view_constants.hpp" #include "helpers/plugin_manager.hpp" @@ -92,6 +93,7 @@ namespace hex::init { ContentRegistry::Views::add(); ContentRegistry::Views::add(); ContentRegistry::Views::add(); + ContentRegistry::Views::add(); return true; } diff --git a/source/views/view_constants.cpp b/source/views/view_constants.cpp new file mode 100644 index 000000000..54ee23789 --- /dev/null +++ b/source/views/view_constants.cpp @@ -0,0 +1,111 @@ +#include "views/view_constants.hpp" + +#include +#include +#include + +namespace hex { + + ViewConstants::ViewConstants() : View("hex.view.constants.name") { + this->reloadConstants(); + this->m_search.resize(0xFFF, 0x00); + } + + ViewConstants::~ViewConstants() { + + } + + void ViewConstants::reloadConstants() { + this->m_constants.clear(); + + for (auto &path : hex::getPath(ImHexPath::Constants)) { + if (!std::filesystem::exists(path)) continue; + + for (auto &file : std::filesystem::directory_iterator(path)) { + if (!file.is_regular_file()) continue; + + try { + nlohmann::json content; + std::ifstream(file.path()) >> content; + + for (auto value : content["values"]) { + Constant constant; + constant.category = content["name"]; + constant.name = value["name"]; + if (value.contains("desc")) + constant.description = value["desc"]; + constant.value = value["value"]; + + auto type = value["type"]; + if (type == "int10") + constant.type = ConstantType::Int10; + else if (type == "int16be") + constant.type = ConstantType::Int16BigEndian; + else if (type == "int16le") + constant.type = ConstantType::Int16LittleEndian; + else + throw std::runtime_error("Invalid type"); + + this->m_constants.push_back(constant); + } + } catch (...) { + log::info("Error"); + continue; + } + + + } + } + } + + void ViewConstants::drawContent() { + if (ImGui::Begin(View::toWindowName("hex.view.constants.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { + + if (ImGui::InputText("##search", this->m_search.data(), this->m_search.size())) { + this->m_filteredConstants.clear(); + for (auto &constant : this->m_constants) { + if (constant.value.starts_with(this->m_search.c_str()) || constant.name.starts_with(this->m_search.c_str()) || constant.description.starts_with(this->m_search.c_str())) + this->m_filteredConstants.push_back(&constant); + } + } + + if (ImGui::BeginTable("##strings", 4, + ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | + ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) { + ImGui::TableSetupScrollFreeze(0, 1); + ImGui::TableSetupColumn("hex.view.constants.category"_lang, 0, -1, ImGui::GetID("category")); + ImGui::TableSetupColumn("hex.view.constants.name"_lang, 0, -1, ImGui::GetID("name")); + ImGui::TableSetupColumn("hex.view.constants.desc"_lang, 0, -1, ImGui::GetID("desc")); + ImGui::TableSetupColumn("hex.view.constants.value"_lang, 0, -1, ImGui::GetID("value")); + + ImGui::TableHeadersRow(); + + ImGuiListClipper clipper; + clipper.Begin(this->m_filteredConstants.size()); + + while (clipper.Step()) { + for (u64 i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("%s", this->m_filteredConstants[i]->category.c_str()); + ImGui::TableNextColumn(); + ImGui::Text("%s", this->m_filteredConstants[i]->name.c_str()); + ImGui::TableNextColumn(); + ImGui::Text("%s", this->m_filteredConstants[i]->description.c_str()); + ImGui::TableNextColumn(); + ImGui::Text("%s", this->m_filteredConstants[i]->value.c_str()); + } + } + clipper.End(); + + ImGui::EndTable(); + } + } + ImGui::End(); + } + + void ViewConstants::drawMenu() { + + } + +} \ No newline at end of file