diff --git a/include/hex.hpp b/include/hex.hpp index 7d95cf731..420a8d367 100644 --- a/include/hex.hpp +++ b/include/hex.hpp @@ -16,4 +16,10 @@ using s64 = std::int64_t; using s128 = __int128_t; #include "lang/result.hpp" -#include "lang/results.hpp" \ No newline at end of file +#include "lang/results.hpp" + +#if defined(__EMX__) || defined (WIN32) +#define MAGIC_PATH_SEPARATOR ";" +#else +#define MAGIC_PATH_SEPARATOR ":" +#endif \ No newline at end of file diff --git a/include/views/view_pattern.hpp b/include/views/view_pattern.hpp index f1dc50f17..d873150fb 100644 --- a/include/views/view_pattern.hpp +++ b/include/views/view_pattern.hpp @@ -9,7 +9,7 @@ #include #include - +#include #include "ImGuiFileBrowser.h" #include "TextEditor.h" @@ -27,11 +27,13 @@ namespace hex { private: std::vector &m_patternData; prv::Provider* &m_dataProvider; + std::filesystem::path m_possiblePatternFile; bool m_windowOpen = true; TextEditor m_textEditor; imgui_addons::ImGuiFileBrowser m_fileBrowser; + void loadPatternFile(std::string path); void clearPatternData(); void parsePattern(char *buffer); }; diff --git a/source/main.cpp b/source/main.cpp index 1eab4e95b..cf18ea344 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -21,7 +21,6 @@ int main() { // Shared Data std::vector patternData; hex::prv::Provider *dataProvider = nullptr; - // Create views window.addView(dataProvider, patternData); window.addView(dataProvider, patternData); diff --git a/source/views/view_information.cpp b/source/views/view_information.cpp index 3dc596115..bb474f142 100644 --- a/source/views/view_information.cpp +++ b/source/views/view_information.cpp @@ -12,16 +12,10 @@ #include - -#if defined(__EMX__) || defined (WIN32) -#define MAGIC_PATH_SEPARATOR ";" -#else -#define MAGIC_PATH_SEPARATOR ":" -#endif - namespace hex { - ViewInformation::ViewInformation(prv::Provider* &dataProvider) : View(), m_dataProvider(dataProvider) { + ViewInformation::ViewInformation(prv::Provider* &dataProvider) + : View(), m_dataProvider(dataProvider) { View::subscribeEvent(Events::DataChanged, [this](const void*) { this->m_shouldInvalidate = true; }); @@ -76,7 +70,7 @@ namespace hex { } { - std::vector buffer(this->m_dataProvider->getSize(), 0x00); + std::vector buffer(std::min(this->m_dataProvider->getSize(), size_t(0xFF'FFFF)), 0x00); this->m_dataProvider->read(0x00, buffer.data(), buffer.size()); this->m_fileDescription.clear(); @@ -95,12 +89,10 @@ namespace hex { { magic_t cookie = magic_open(MAGIC_NONE); - if (magic_load(cookie, magicFiles.c_str()) == -1) - goto skip_description; - - this->m_fileDescription = magic_buffer(cookie, buffer.data(), buffer.size()); - - skip_description: + if (magic_load(cookie, magicFiles.c_str()) != -1) + this->m_fileDescription = magic_buffer(cookie, buffer.data(), buffer.size()); + else + this->m_fileDescription = ""; magic_close(cookie); } @@ -108,12 +100,10 @@ namespace hex { { magic_t cookie = magic_open(MAGIC_MIME); - if (magic_load(cookie, magicFiles.c_str()) == -1) - goto skip_mime; - - this->m_mimeType = magic_buffer(cookie, buffer.data(), buffer.size()); - - skip_mime: + if (magic_load(cookie, magicFiles.c_str()) != -1) + this->m_mimeType = magic_buffer(cookie, buffer.data(), buffer.size()); + else + this->m_mimeType = ""; magic_close(cookie); } diff --git a/source/views/view_pattern.cpp b/source/views/view_pattern.cpp index dd091eff0..09d3982ea 100644 --- a/source/views/view_pattern.cpp +++ b/source/views/view_pattern.cpp @@ -7,6 +7,8 @@ #include "lang/evaluator.hpp" #include "utils.hpp" +#include + namespace hex { static const TextEditor::LanguageDefinition& PatternLanguage() { @@ -71,6 +73,66 @@ namespace hex { this->m_textEditor.SetLanguageDefinition(PatternLanguage()); this->m_textEditor.SetShowWhitespaces(false); + + View::subscribeEvent(Events::DataChanged, [this](const void* userData) { + lang::Preprocessor preprocessor; + + std::string magicFiles; + + std::error_code error; + for (const auto &entry : std::filesystem::directory_iterator("magic", error)) { + if (entry.is_regular_file() && entry.path().extension() == ".mgc") + magicFiles += entry.path().string() + MAGIC_PATH_SEPARATOR; + } + + std::vector buffer(this->m_dataProvider->getSize(), 0x00); + this->m_dataProvider->read(0, buffer.data(), buffer.size()); + + std::string mimeType; + + magic_t cookie = magic_open(MAGIC_MIME_TYPE); + if (magic_load(cookie, magicFiles.c_str()) != -1) + mimeType = magic_buffer(cookie, buffer.data(), buffer.size()); + + magic_close(cookie); + + bool foundCorrectType = false; + preprocessor.addPragmaHandler("MIME", [&mimeType, &foundCorrectType](std::string value) { + if (value == mimeType) { + foundCorrectType = true; + return true; + } + return !std::all_of(value.begin(), value.end(), isspace) && !value.ends_with('\n') && !value.ends_with('\r'); + }); + preprocessor.addDefaultPragramHandlers(); + + + for (auto &entry : std::filesystem::directory_iterator("patterns")) { + if (!entry.is_regular_file()) + continue; + + FILE *file = fopen(entry.path().string().c_str(), "r"); + + if (file == nullptr) + continue; + + fseek(file, 0, SEEK_END); + size_t size = ftell(file); + rewind(file); + + std::vector buffer( size + 1, 0x00); + fread(buffer.data(), 1, size, file); + fclose(file); + + preprocessor.preprocess(buffer.data()); + + if (foundCorrectType) { + this->m_possiblePatternFile = entry.path(); + ImGui::OpenPopup("Accept Pattern"); + ImGui::SetNextWindowSize(ImVec2(200, 100)); + } + } + }); } ViewPattern::~ViewPattern() { @@ -107,32 +169,54 @@ namespace hex { ImGui::End(); if (this->m_fileBrowser.showFileDialog("Open Hex Pattern", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ImVec2(0, 0), ".hexpat")) { + this->loadPatternFile(this->m_fileBrowser.selected_path); + } - FILE *file = fopen(this->m_fileBrowser.selected_path.c_str(), "rb"); + if (ImGui::BeginPopupModal("Accept Pattern", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove)) { + ImGui::TextUnformatted("A pattern compatible with this data type has been found:"); + ImGui::Text("%ls", this->m_possiblePatternFile.filename().c_str()); + ImGui::NewLine(); + ImGui::Text("Do you want to load it?"); + ImGui::NewLine(); - if (file != nullptr) { - char *buffer; - fseek(file, 0, SEEK_END); - size_t size = ftell(file); - rewind(file); - - buffer = new char[size + 1]; - - fread(buffer, size, 1, file); - buffer[size] = 0x00; - - - fclose(file); - - this->parsePattern(buffer); - this->m_textEditor.SetText(buffer); - - delete[] buffer; + if (ImGui::Button("Yes", ImVec2(40, 20))) { + this->loadPatternFile(this->m_possiblePatternFile.string()); + ImGui::CloseCurrentPopup(); } + ImGui::SameLine(); + if (ImGui::Button("No", ImVec2(40, 20))) { + ImGui::CloseCurrentPopup(); + } + + ImGui::EndPopup(); } } + void ViewPattern::loadPatternFile(std::string path) { + FILE *file = fopen(path.c_str(), "rb"); + + if (file != nullptr) { + char *buffer; + fseek(file, 0, SEEK_END); + size_t size = ftell(file); + rewind(file); + + buffer = new char[size + 1]; + + fread(buffer, size, 1, file); + buffer[size] = 0x00; + + + fclose(file); + + this->parsePattern(buffer); + this->m_textEditor.SetText(buffer); + + delete[] buffer; + } + } + void ViewPattern::clearPatternData() { for (auto &data : this->m_patternData) delete data; @@ -162,6 +246,8 @@ namespace hex { this->clearPatternData(); this->postEvent(Events::PatternChanged); + preprocessor.addDefaultPragramHandlers(); + auto [preprocessingResult, preprocesedCode] = preprocessor.preprocess(buffer); if (preprocessingResult.failed()) return;