From 83fa024fab8743376d9a8e0a29408c636e5f0f02 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Tue, 26 Dec 2023 23:42:22 +0100 Subject: [PATCH] feat: Added Base64 provider --- plugins/builtin/CMakeLists.txt | 1 + .../content/providers/base64_provider.hpp | 25 +++++++ plugins/builtin/romfs/lang/de_DE.json | 3 - plugins/builtin/romfs/lang/en_US.json | 4 +- plugins/builtin/romfs/lang/es_ES.json | 3 - plugins/builtin/romfs/lang/it_IT.json | 3 - plugins/builtin/romfs/lang/ja_JP.json | 3 - plugins/builtin/romfs/lang/ko_KR.json | 3 - plugins/builtin/romfs/lang/pt_BR.json | 3 - plugins/builtin/romfs/lang/zh_CN.json | 3 - plugins/builtin/romfs/lang/zh_TW.json | 3 - .../source/content/main_menu_items.cpp | 39 ----------- plugins/builtin/source/content/providers.cpp | 2 + .../content/providers/base64_provider.cpp | 65 +++++++++++++++++++ .../content/providers/file_provider.cpp | 3 +- 15 files changed, 95 insertions(+), 68 deletions(-) create mode 100644 plugins/builtin/include/content/providers/base64_provider.hpp create mode 100644 plugins/builtin/source/content/providers/base64_provider.cpp diff --git a/plugins/builtin/CMakeLists.txt b/plugins/builtin/CMakeLists.txt index a91a7abc7..a7cda908b 100644 --- a/plugins/builtin/CMakeLists.txt +++ b/plugins/builtin/CMakeLists.txt @@ -60,6 +60,7 @@ add_imhex_plugin( source/content/providers/motorola_srec_provider.cpp source/content/providers/memory_file_provider.cpp source/content/providers/process_memory_provider.cpp + source/content/providers/base64_provider.cpp source/content/tools/ascii_table.cpp source/content/tools/base_converter.cpp diff --git a/plugins/builtin/include/content/providers/base64_provider.hpp b/plugins/builtin/include/content/providers/base64_provider.hpp new file mode 100644 index 000000000..c58b938f4 --- /dev/null +++ b/plugins/builtin/include/content/providers/base64_provider.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +namespace hex::plugin::builtin { + + class Base64Provider : public FileProvider { + public: + explicit Base64Provider() = default; + ~Base64Provider() override = default; + + void readRaw(u64 offset, void *buffer, size_t size) override; + void writeRaw(u64 offset, const void *buffer, size_t size) override; + [[nodiscard]] u64 getActualSize() const override { return (3 * m_file.getSize()) / 4; } + + void resizeRaw(u64 newSize) override; + void insertRaw(u64 offset, u64 size) override; + void removeRaw(u64 offset, u64 size) override; + + [[nodiscard]] std::string getTypeName() const override { + return "hex.builtin.provider.base64"; + } + }; + +} \ No newline at end of file diff --git a/plugins/builtin/romfs/lang/de_DE.json b/plugins/builtin/romfs/lang/de_DE.json index 80cf5fbdb..568144a58 100644 --- a/plugins/builtin/romfs/lang/de_DE.json +++ b/plugins/builtin/romfs/lang/de_DE.json @@ -124,9 +124,6 @@ "hex.builtin.menu.file.export.popup.create": "Daten konnten nicht exportiert werden. Datei konnte nicht erstellt werden!", "hex.builtin.menu.file.export.title": "Datei exportieren", "hex.builtin.menu.file.import": "Importieren...", - "hex.builtin.menu.file.import.base64": "Base64 Datei", - "hex.builtin.menu.file.import.base64.popup.import_error": "Datei hat kein gültiges Base64 Format!", - "hex.builtin.menu.file.import.base64.popup.open_error": "Öffnen der Datei fehlgeschlagen!", "hex.builtin.menu.file.import.ips": "IPS Patch", "hex.builtin.menu.file.import.ips32": "IPS32 Patch", "hex.builtin.menu.file.import.modified_file": "Modifizierte Datei", diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index 1df4dcb0c..54a5f9cb4 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -140,9 +140,6 @@ "hex.builtin.menu.file.export.report.popup.export_error": "Failed to create new report file!", "hex.builtin.menu.file.export.title": "Export File", "hex.builtin.menu.file.import": "Import...", - "hex.builtin.menu.file.import.base64": "Base64 File", - "hex.builtin.menu.file.import.base64.popup.import_error": "File is not in a valid Base64 format!", - "hex.builtin.menu.file.import.base64.popup.open_error": "Failed to open file!", "hex.builtin.menu.file.import.ips": "IPS Patch", "hex.builtin.menu.file.import.ips32": "IPS32 Patch", "hex.builtin.menu.file.import.modified_file": "Modified File", @@ -375,6 +372,7 @@ "hex.builtin.popup.waiting_for_tasks.desc": "There are still tasks running in the background.\nImHex will close after they are finished.", "hex.builtin.provider.tooltip.show_more": "Hold SHIFT for more information", "hex.builtin.provider.error.open": "Failed to open provider: {}", + "hex.builtin.provider.base64": "Base64 Provider", "hex.builtin.provider.disk": "Raw Disk Provider", "hex.builtin.provider.disk.disk_size": "Disk Size", "hex.builtin.provider.disk.elevation": "Accessing raw disks most likely requires elevated privileges", diff --git a/plugins/builtin/romfs/lang/es_ES.json b/plugins/builtin/romfs/lang/es_ES.json index 105c79c32..61519b4d7 100644 --- a/plugins/builtin/romfs/lang/es_ES.json +++ b/plugins/builtin/romfs/lang/es_ES.json @@ -124,9 +124,6 @@ "hex.builtin.menu.file.export.popup.create": "No se pudieron exportar los datos. ¡Fallo al crear archivo!", "hex.builtin.menu.file.export.title": "Exportar Archivo", "hex.builtin.menu.file.import": "Importar...", - "hex.builtin.menu.file.import.base64": "Archivo Base64", - "hex.builtin.menu.file.import.base64.popup.import_error": "¡El archivo no tiene un formato Base64 válido!", - "hex.builtin.menu.file.import.base64.popup.open_error": "¡Fallo al abrir archivo!", "hex.builtin.menu.file.import.ips": "Parche IPS", "hex.builtin.menu.file.import.ips32": "Parche IPS32", "hex.builtin.menu.file.import.modified_file": "Archivo Modificado", diff --git a/plugins/builtin/romfs/lang/it_IT.json b/plugins/builtin/romfs/lang/it_IT.json index 232e4befd..bc7c0ab6b 100644 --- a/plugins/builtin/romfs/lang/it_IT.json +++ b/plugins/builtin/romfs/lang/it_IT.json @@ -124,9 +124,6 @@ "hex.builtin.menu.file.export.popup.create": "", "hex.builtin.menu.file.export.title": "Esporta File", "hex.builtin.menu.file.import": "Importa...", - "hex.builtin.menu.file.import.base64": "Base64 File", - "hex.builtin.menu.file.import.base64.popup.import_error": "", - "hex.builtin.menu.file.import.base64.popup.open_error": "", "hex.builtin.menu.file.import.ips": "IPS Patch", "hex.builtin.menu.file.import.ips32": "IPS32 Patch", "hex.builtin.menu.file.import.modified_file": "", diff --git a/plugins/builtin/romfs/lang/ja_JP.json b/plugins/builtin/romfs/lang/ja_JP.json index 5b3f69ec8..c8eceee21 100644 --- a/plugins/builtin/romfs/lang/ja_JP.json +++ b/plugins/builtin/romfs/lang/ja_JP.json @@ -124,9 +124,6 @@ "hex.builtin.menu.file.export.popup.create": "データをエクスポートできません。\nファイルの作成に失敗しました。", "hex.builtin.menu.file.export.title": "ファイルをエクスポート", "hex.builtin.menu.file.import": "インポート…", - "hex.builtin.menu.file.import.base64": "Base64ファイル", - "hex.builtin.menu.file.import.base64.popup.import_error": "有効なBase64形式ではありません。", - "hex.builtin.menu.file.import.base64.popup.open_error": "ファイルを開けません。", "hex.builtin.menu.file.import.ips": "IPSパッチ", "hex.builtin.menu.file.import.ips32": "IPS32パッチ", "hex.builtin.menu.file.import.modified_file": "", diff --git a/plugins/builtin/romfs/lang/ko_KR.json b/plugins/builtin/romfs/lang/ko_KR.json index 44379cead..ad196af41 100644 --- a/plugins/builtin/romfs/lang/ko_KR.json +++ b/plugins/builtin/romfs/lang/ko_KR.json @@ -124,9 +124,6 @@ "hex.builtin.menu.file.export.popup.create": "데이터를 내보낼 수 없습니다. 파일을 만들지 못했습니다!", "hex.builtin.menu.file.export.title": "파일 내보내기", "hex.builtin.menu.file.import": "가져오기...", - "hex.builtin.menu.file.import.base64": "Base64 파일", - "hex.builtin.menu.file.import.base64.popup.import_error": "파일이 올바른 Base64 형식이 아닙니다!", - "hex.builtin.menu.file.import.base64.popup.open_error": "파일을 열지 못했습니다!", "hex.builtin.menu.file.import.ips": "IPS 패치", "hex.builtin.menu.file.import.ips32": "IPS32 패치", "hex.builtin.menu.file.import.modified_file": "수정된 파일", diff --git a/plugins/builtin/romfs/lang/pt_BR.json b/plugins/builtin/romfs/lang/pt_BR.json index 336d0787e..00aba8814 100644 --- a/plugins/builtin/romfs/lang/pt_BR.json +++ b/plugins/builtin/romfs/lang/pt_BR.json @@ -124,9 +124,6 @@ "hex.builtin.menu.file.export.popup.create": "Não é possível exportar os dados. Falha ao criar arquivo!", "hex.builtin.menu.file.export.title": "Exportar Arquivo", "hex.builtin.menu.file.import": "Importar...", - "hex.builtin.menu.file.import.base64": "Arquivo Base64", - "hex.builtin.menu.file.import.base64.popup.import_error": "Esse arquivo não é baseado em um formato Base64 valido!", - "hex.builtin.menu.file.import.base64.popup.open_error": "Falha ao abrir o arquivo!", "hex.builtin.menu.file.import.ips": "IPS Patch", "hex.builtin.menu.file.import.ips32": "IPS32 Patch", "hex.builtin.menu.file.import.modified_file": "", diff --git a/plugins/builtin/romfs/lang/zh_CN.json b/plugins/builtin/romfs/lang/zh_CN.json index 805b253b1..cbff9ea04 100644 --- a/plugins/builtin/romfs/lang/zh_CN.json +++ b/plugins/builtin/romfs/lang/zh_CN.json @@ -124,9 +124,6 @@ "hex.builtin.menu.file.export.popup.create": "无法导出文件。文件创建失败!", "hex.builtin.menu.file.export.title": "导出文件", "hex.builtin.menu.file.import": "导入...", - "hex.builtin.menu.file.import.base64": "Base64 文件", - "hex.builtin.menu.file.import.base64.popup.import_error": "文件不是有效的 Base64 格式!", - "hex.builtin.menu.file.import.base64.popup.open_error": "打开文件失败!", "hex.builtin.menu.file.import.ips": "IPS 补丁", "hex.builtin.menu.file.import.ips32": "IPS32 补丁", "hex.builtin.menu.file.import.modified_file": "已修改", diff --git a/plugins/builtin/romfs/lang/zh_TW.json b/plugins/builtin/romfs/lang/zh_TW.json index b0eba8ace..4d24a0e87 100644 --- a/plugins/builtin/romfs/lang/zh_TW.json +++ b/plugins/builtin/romfs/lang/zh_TW.json @@ -124,9 +124,6 @@ "hex.builtin.menu.file.export.popup.create": "無法匯出資料。無法建立檔案!", "hex.builtin.menu.file.export.title": "匯出檔案", "hex.builtin.menu.file.import": "匯入...", - "hex.builtin.menu.file.import.base64": "Base64 檔案", - "hex.builtin.menu.file.import.base64.popup.import_error": "檔案並非有效的 Base64 格式!", - "hex.builtin.menu.file.import.base64.popup.open_error": "無法開啟檔案!", "hex.builtin.menu.file.import.ips": "IPS 修補檔案", "hex.builtin.menu.file.import.ips32": "IPS32 修補檔案", "hex.builtin.menu.file.import.modified_file": "已修改檔案", diff --git a/plugins/builtin/source/content/main_menu_items.cpp b/plugins/builtin/source/content/main_menu_items.cpp index c3afd9bb2..9a02616d0 100644 --- a/plugins/builtin/source/content/main_menu_items.cpp +++ b/plugins/builtin/source/content/main_menu_items.cpp @@ -73,37 +73,6 @@ namespace hex::plugin::builtin { // Import namespace { - void importBase64() { - fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) { - wolv::io::File inputFile(path, wolv::io::File::Mode::Read); - if (!inputFile.isValid()) { - ui::ToastError::open("hex.builtin.menu.file.import.base64.popup.open_error"_lang); - return; - } - - auto base64 = inputFile.readVector(); - - if (!base64.empty()) { - auto data = crypt::decode64(base64); - - if (data.empty()) - ui::ToastError::open("hex.builtin.menu.file.import.base64.popup.import_error"_lang); - else { - fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const std::fs::path &path) { - wolv::io::File outputFile(path, wolv::io::File::Mode::Create); - - if (!outputFile.isValid()) - ui::ToastError::open("hex.builtin.menu.file.import.base64.popup.import_error"_lang); - - outputFile.writeVector(data); - }); - } - } else { - ui::ToastError::open("hex.builtin.popup.file_open_error"_lang); - } - }); - } - void importIPSPatch() { fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) { TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [path](auto &task) { @@ -422,14 +391,6 @@ namespace hex::plugin::builtin { /* Import */ { - /* Base 64 */ - ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.base64" }, 2050, - Shortcut::None, - importBase64, - noRunningTaskAndWritableProvider); - - ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.file", "hex.builtin.menu.file.import" }, 2100); - /* IPS */ ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.ips"}, 2150, Shortcut::None, diff --git a/plugins/builtin/source/content/providers.cpp b/plugins/builtin/source/content/providers.cpp index 190c66333..ae19972ac 100644 --- a/plugins/builtin/source/content/providers.cpp +++ b/plugins/builtin/source/content/providers.cpp @@ -9,6 +9,7 @@ #include "content/providers/memory_file_provider.hpp" #include "content/providers/view_provider.hpp" #include +#include #include #include "content/helpers/notification.hpp" @@ -32,6 +33,7 @@ namespace hex::plugin::builtin { ContentRegistry::Provider::add(); ContentRegistry::Provider::add(); ContentRegistry::Provider::add(); + ContentRegistry::Provider::add(); ContentRegistry::Provider::add(false); ContentRegistry::Provider::add(false); diff --git a/plugins/builtin/source/content/providers/base64_provider.cpp b/plugins/builtin/source/content/providers/base64_provider.cpp new file mode 100644 index 000000000..e84ed48b7 --- /dev/null +++ b/plugins/builtin/source/content/providers/base64_provider.cpp @@ -0,0 +1,65 @@ +#include + +#include +#include + +namespace hex::plugin::builtin { + + void Base64Provider::readRaw(u64 offset, void *buffer, size_t size) { + const u64 base64Offset = 4 * (offset / 3); + const u64 base64Size = hex::alignTo(4 * (size / 3), 4) + 4; + + std::vector bytes(base64Size); + FileProvider::readRaw(base64Offset, bytes.data(), bytes.size()); + + auto decoded = crypt::decode64(bytes); + if (decoded.empty()) + return; + + u64 startOffset = offset % 3; + std::memcpy(buffer, decoded.data() + startOffset, std::min(decoded.size() - startOffset, size)); + } + + void Base64Provider::writeRaw(u64 offset, const void *buffer, size_t size) { + const u64 base64Offset = 4 * (offset / 3); + const u64 base64Size = hex::alignTo(4 * (size / 3), 4) + 4; + + std::vector bytes(base64Size); + FileProvider::readRaw(base64Offset, bytes.data(), bytes.size()); + + auto decoded = crypt::decode64(bytes); + if (decoded.empty()) + return; + + u64 startOffset = offset % 3; + std::memcpy(decoded.data() + startOffset, buffer, std::min(decoded.size() - startOffset, size)); + + auto encoded = crypt::encode64(decoded); + if (encoded.empty()) + return; + + FileProvider::writeRaw(base64Offset, encoded.data(), encoded.size()); + } + + void Base64Provider::resizeRaw(u64 newSize) { + u64 newFileLength = 4 * (newSize / 3); + FileProvider::resizeRaw(newFileLength); + } + + void Base64Provider::insertRaw(u64 offset, u64 size) { + u64 newFileLength = 4 * ((getActualSize() + size) / 3); + FileProvider::insertRaw(4 * (offset / 3), newFileLength); + + constexpr static auto NullByte = 0x00; + for (u64 i = 0; i < size; i++) + writeRaw(offset + i, &NullByte, 1); + } + + void Base64Provider::removeRaw(u64 offset, u64 size) { + u64 newFileLength = 4 * ((getActualSize() - size) / 3); + FileProvider::removeRaw(4 * (offset / 3), newFileLength); + } + + + +} diff --git a/plugins/builtin/source/content/providers/file_provider.cpp b/plugins/builtin/source/content/providers/file_provider.cpp index 537633ebe..0bf1c5ffe 100644 --- a/plugins/builtin/source/content/providers/file_provider.cpp +++ b/plugins/builtin/source/content/providers/file_provider.cpp @@ -43,8 +43,7 @@ namespace hex::plugin::builtin { } void FileProvider::readRaw(u64 offset, void *buffer, size_t size) { - auto actualSize = this->getActualSize(); - if (actualSize == 0 || (offset + size) > actualSize || buffer == nullptr || size == 0) + if (m_fileSize == 0 || (offset + size) > m_fileSize || buffer == nullptr || size == 0) return; std::memcpy(buffer, m_file.getMapping() + offset, size);