parent
241b93aab5
commit
6a8611d98d
@ -30,6 +30,7 @@ add_library(${PROJECT_NAME} SHARED
|
||||
source/content/providers/disk_provider.cpp
|
||||
source/content/providers/intel_hex_provider.cpp
|
||||
source/content/providers/motorola_srec_provider.cpp
|
||||
source/content/providers/memory_file_provider.cpp
|
||||
|
||||
source/content/views/view_hex_editor.cpp
|
||||
source/content/views/view_pattern_editor.cpp
|
||||
|
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
namespace hex::plugin::builtin::prv {
|
||||
|
||||
class MemoryFileProvider : public hex::prv::Provider {
|
||||
public:
|
||||
explicit MemoryFileProvider() = default;
|
||||
~MemoryFileProvider() override = default;
|
||||
|
||||
[[nodiscard]] bool isAvailable() const override { return true; }
|
||||
[[nodiscard]] bool isReadable() const override { return true; }
|
||||
[[nodiscard]] bool isWritable() const override { return true; }
|
||||
[[nodiscard]] bool isResizable() const override { return true; }
|
||||
[[nodiscard]] bool isSavable() const override { return true; }
|
||||
|
||||
[[nodiscard]] bool open() override;
|
||||
void close() override { }
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||
void writeRaw(u64 offset, const void *buffer, size_t size) override;
|
||||
[[nodiscard]] size_t getActualSize() const override { return this->m_data.size(); }
|
||||
|
||||
void resize(size_t newSize) override;
|
||||
void insert(u64 offset, size_t size) override;
|
||||
void remove(u64 offset, size_t size) override;
|
||||
|
||||
void save() override;
|
||||
void saveAs(const std::fs::path &path) override;
|
||||
|
||||
[[nodiscard]] std::string getName() const override { return "hex.builtin.provider.mem_file.unsaved"; }
|
||||
[[nodiscard]] std::vector<std::pair<std::string, std::string>> getDataInformation() const override { return { }; }
|
||||
|
||||
[[nodiscard]] std::string getTypeName() const override {
|
||||
return "hex.builtin.provider.mem_file";
|
||||
}
|
||||
|
||||
[[nodiscard]] std::pair<Region, bool> getRegionValidity(u64 address) const override;
|
||||
|
||||
void loadSettings(const nlohmann::json &settings) override { hex::unused(settings); }
|
||||
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override { return settings; }
|
||||
|
||||
private:
|
||||
std::vector<u8> m_data;
|
||||
};
|
||||
|
||||
}
|
@ -21,7 +21,11 @@ namespace hex::plugin::builtin {
|
||||
bool taskRunning = TaskManager::getRunningTaskCount() > 0;
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.create_file"_lang, "CTRL + N", false, !taskRunning)) {
|
||||
EventManager::post<RequestOpenWindow>("Create File");
|
||||
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
|
||||
if (newProvider != nullptr && !newProvider->open())
|
||||
hex::ImHexApi::Provider::remove(newProvider);
|
||||
else
|
||||
EventManager::post<EventProviderOpened>(newProvider);
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.open_file"_lang, "CTRL + O", false, !taskRunning)) {
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "content/providers/disk_provider.hpp"
|
||||
#include "content/providers/intel_hex_provider.hpp"
|
||||
#include "content/providers/motorola_srec_provider.hpp"
|
||||
#include "content/providers/memory_file_provider.hpp"
|
||||
|
||||
#include <hex/api/project_file_manager.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
@ -21,6 +22,7 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::Provider::add<prv::GDBProvider>();
|
||||
ContentRegistry::Provider::add<prv::IntelHexProvider>();
|
||||
ContentRegistry::Provider::add<prv::MotorolaSRECProvider>();
|
||||
ContentRegistry::Provider::add<prv::MemoryFileProvider>(false);
|
||||
|
||||
ProjectFile::registerHandler({
|
||||
.basePath = "providers",
|
||||
|
@ -145,6 +145,7 @@ namespace hex::plugin::builtin::prv {
|
||||
this->resize(newSize);
|
||||
|
||||
Provider::insert(offset, size);
|
||||
Provider::remove(offset, size);
|
||||
}
|
||||
|
||||
size_t FileProvider::getActualSize() const {
|
||||
|
@ -0,0 +1,130 @@
|
||||
#include "content/providers/memory_file_provider.hpp"
|
||||
#include "content/providers/file_provider.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
|
||||
namespace hex::plugin::builtin::prv {
|
||||
|
||||
bool MemoryFileProvider::open() {
|
||||
this->m_data.resize(1);
|
||||
this->markDirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
void MemoryFileProvider::readRaw(u64 offset, void *buffer, size_t size) {
|
||||
if ((offset + size) > this->getActualSize() || buffer == nullptr || size == 0)
|
||||
return;
|
||||
|
||||
std::memcpy(buffer, &this->m_data.front() + offset, size);
|
||||
}
|
||||
|
||||
void MemoryFileProvider::writeRaw(u64 offset, const void *buffer, size_t size) {
|
||||
if ((offset + size) > this->getActualSize() || buffer == nullptr || size == 0)
|
||||
return;
|
||||
|
||||
std::memcpy(&this->m_data.front() + offset, buffer, size);
|
||||
}
|
||||
|
||||
void MemoryFileProvider::save() {
|
||||
fs::openFileBrowser(fs::DialogMode::Save, { }, [this](const std::fs::path &path) {
|
||||
if (path.empty())
|
||||
return;
|
||||
|
||||
this->saveAs(path);
|
||||
|
||||
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.file", true);
|
||||
|
||||
if (auto fileProvider = dynamic_cast<FileProvider*>(newProvider); fileProvider != nullptr && (fileProvider->setPath(path), !fileProvider->open()))
|
||||
ImHexApi::Provider::remove(newProvider);
|
||||
else {
|
||||
fileProvider->markDirty(false);
|
||||
EventManager::post<EventProviderOpened>(newProvider);
|
||||
ImHexApi::Provider::remove(this, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MemoryFileProvider::saveAs(const std::fs::path &path) {
|
||||
fs::File file(path, fs::File::Mode::Create);
|
||||
|
||||
if (file.isValid()) {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
std::vector<u8> buffer(std::min<size_t>(0xFF'FFFF, provider->getActualSize()), 0x00);
|
||||
size_t bufferSize = buffer.size();
|
||||
|
||||
for (u64 offset = 0; offset < provider->getActualSize(); offset += bufferSize) {
|
||||
if (bufferSize > provider->getActualSize() - offset)
|
||||
bufferSize = provider->getActualSize() - offset;
|
||||
|
||||
provider->read(offset + this->getBaseAddress(), buffer.data(), bufferSize);
|
||||
file.write(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryFileProvider::resize(size_t newSize) {
|
||||
this->m_data.resize(newSize);
|
||||
|
||||
Provider::resize(newSize);
|
||||
}
|
||||
|
||||
void MemoryFileProvider::insert(u64 offset, size_t size) {
|
||||
auto oldSize = this->getActualSize();
|
||||
this->resize(oldSize + size);
|
||||
|
||||
std::vector<u8> buffer(0x1000);
|
||||
const std::vector<u8> zeroBuffer(0x1000);
|
||||
|
||||
auto position = oldSize;
|
||||
while (position > offset) {
|
||||
const auto readSize = std::min<size_t>(position - offset, buffer.size());
|
||||
|
||||
position -= readSize;
|
||||
|
||||
this->readRaw(position, buffer.data(), readSize);
|
||||
this->writeRaw(position, zeroBuffer.data(), readSize);
|
||||
this->writeRaw(position + size, buffer.data(), readSize);
|
||||
}
|
||||
|
||||
Provider::insert(offset, size);
|
||||
}
|
||||
|
||||
void MemoryFileProvider::remove(u64 offset, size_t size) {
|
||||
auto oldSize = this->getActualSize();
|
||||
this->resize(oldSize + size);
|
||||
|
||||
std::vector<u8> buffer(0x1000);
|
||||
|
||||
const auto newSize = oldSize - size;
|
||||
auto position = offset;
|
||||
while (position < newSize) {
|
||||
const auto readSize = std::min<size_t>(newSize - position, buffer.size());
|
||||
|
||||
this->readRaw(position + size, buffer.data(), readSize);
|
||||
this->writeRaw(position, buffer.data(), readSize);
|
||||
|
||||
position += readSize;
|
||||
}
|
||||
|
||||
this->resize(newSize);
|
||||
|
||||
Provider::insert(offset, size);
|
||||
Provider::remove(offset, size);
|
||||
}
|
||||
|
||||
std::pair<Region, bool> MemoryFileProvider::getRegionValidity(u64 address) const {
|
||||
address -= this->getBaseAddress();
|
||||
|
||||
if (address < this->getActualSize())
|
||||
return { Region { this->getBaseAddress() + address, this->getActualSize() - address }, true };
|
||||
else
|
||||
return { Region::Invalid(), false };
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
#include <hex/ui/view.hpp>
|
||||
@ -303,8 +304,13 @@ namespace hex::plugin::builtin {
|
||||
ImGui::BeginDisabled(tasksRunning);
|
||||
{
|
||||
// Create new file
|
||||
if (ImGui::ToolBarButton(ICON_VS_FILE, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGray)))
|
||||
EventManager::post<RequestOpenWindow>("Create File");
|
||||
if (ImGui::ToolBarButton(ICON_VS_FILE, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGray))) {
|
||||
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
|
||||
if (newProvider != nullptr && !newProvider->open())
|
||||
hex::ImHexApi::Provider::remove(newProvider);
|
||||
else
|
||||
EventManager::post<EventProviderOpened>(newProvider);
|
||||
}
|
||||
|
||||
// Open file
|
||||
if (ImGui::ToolBarButton(ICON_VS_FOLDER_OPENED, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBrown)))
|
||||
|
@ -208,8 +208,13 @@ namespace hex::plugin::builtin {
|
||||
ImGui::UnderlinedText("hex.builtin.welcome.header.start"_lang);
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
|
||||
{
|
||||
if (ImGui::IconHyperlink(ICON_VS_NEW_FILE, "hex.builtin.welcome.start.create_file"_lang))
|
||||
EventManager::post<RequestOpenWindow>("Create File");
|
||||
if (ImGui::IconHyperlink(ICON_VS_NEW_FILE, "hex.builtin.welcome.start.create_file"_lang)) {
|
||||
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
|
||||
if (newProvider != nullptr && !newProvider->open())
|
||||
hex::ImHexApi::Provider::remove(newProvider);
|
||||
else
|
||||
EventManager::post<EventProviderOpened>(newProvider);
|
||||
}
|
||||
if (ImGui::IconHyperlink(ICON_VS_GO_TO_FILE, "hex.builtin.welcome.start.open_file"_lang))
|
||||
EventManager::post<RequestOpenWindow>("Open File");
|
||||
if (ImGui::IconHyperlink(ICON_VS_NOTEBOOK, "hex.builtin.welcome.start.open_project"_lang))
|
||||
|
@ -833,6 +833,8 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
|
||||
{ "hex.builtin.provider.motorola_srec", "Motorola SREC Provider" },
|
||||
{ "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
|
||||
{ "hex.builtin.provider.mem_file", "RAM Datei" },
|
||||
{ "hex.builtin.provider.mem_file.unsaved", "Ungespeicherte Datei" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "Standard" },
|
||||
|
||||
|
@ -837,6 +837,8 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
|
||||
{ "hex.builtin.provider.motorola_srec", "Motorola SREC Provider" },
|
||||
{ "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
|
||||
{ "hex.builtin.provider.mem_file", "Memory File" },
|
||||
{ "hex.builtin.provider.mem_file.unsaved", "Unsaved File" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "Default" },
|
||||
|
||||
|
@ -842,6 +842,8 @@ namespace hex::plugin::builtin {
|
||||
// { "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
|
||||
//{ "hex.builtin.provider.motorola_srec", "Motorola SREC Provider" },
|
||||
// { "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
|
||||
//{ "hex.builtin.provider.mem_file", "Memory File" },
|
||||
// { "hex.builtin.provider.mem_file.unsaved", "Unsaved File" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "Default" },
|
||||
|
||||
|
@ -839,6 +839,8 @@ namespace hex::plugin::builtin {
|
||||
// { "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
|
||||
//{ "hex.builtin.provider.motorola_srec", "Motorola SREC Provider" },
|
||||
// { "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
|
||||
//{ "hex.builtin.provider.mem_file", "Memory File" },
|
||||
// { "hex.builtin.provider.mem_file.unsaved", "Unsaved File" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "標準" },
|
||||
|
||||
|
@ -836,6 +836,8 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
|
||||
{ "hex.builtin.provider.motorola_srec", "Motorola SREC 공급자" },
|
||||
{ "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
|
||||
//{ "hex.builtin.provider.mem_file", "Memory File" },
|
||||
// { "hex.builtin.provider.mem_file.unsaved", "Unsaved File" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "기본 값" },
|
||||
|
||||
|
@ -835,6 +835,8 @@ namespace hex::plugin::builtin {
|
||||
// { "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
|
||||
//{ "hex.builtin.provider.motorola_srec", "Motorola SREC Provider" },
|
||||
// { "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
|
||||
//{ "hex.builtin.provider.mem_file", "Memory File" },
|
||||
// { "hex.builtin.provider.mem_file.unsaved", "Unsaved File" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "Default" },
|
||||
|
||||
|
@ -838,6 +838,8 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
|
||||
{ "hex.builtin.provider.motorola_srec", "Motorola SREC" },
|
||||
{ "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
|
||||
//{ "hex.builtin.provider.mem_file", "Memory File" },
|
||||
// { "hex.builtin.provider.mem_file.unsaved", "Unsaved File" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "默认" },
|
||||
|
||||
|
@ -835,6 +835,8 @@ namespace hex::plugin::builtin {
|
||||
// { "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
|
||||
//{ "hex.builtin.provider.motorola_srec", "Motorola SREC Provider" },
|
||||
// { "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
|
||||
//{ "hex.builtin.provider.mem_file", "Memory File" },
|
||||
// { "hex.builtin.provider.mem_file.unsaved", "Unsaved File" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "預設" },
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user