#include "content/providers/memory_file_provider.hpp" #include "content/providers/file_provider.hpp" #include #include #include #include #include namespace hex::plugin::builtin { 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(newProvider); fileProvider != nullptr && (fileProvider->setPath(path), !fileProvider->open())) ImHexApi::Provider::remove(newProvider); else { fileProvider->markDirty(false); EventManager::post(newProvider); ImHexApi::Provider::remove(this, true); } }); } 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 buffer(0x1000); const std::vector zeroBuffer(0x1000); auto position = oldSize; while (position > offset) { const auto readSize = std::min(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 buffer(0x1000); const auto newSize = oldSize - size; auto position = offset; while (position < newSize) { const auto readSize = std::min(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 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 }; } }