feat: Add ability to remove bytes (#531)
Co-authored-by: Dmitry Polshakov <dmitry.polshakov@dsr-corporation.com>
This commit is contained in:
parent
f6ddb3c5e7
commit
662d80abea
@ -35,6 +35,7 @@ namespace hex::prv {
|
|||||||
|
|
||||||
virtual void resize(size_t newSize);
|
virtual void resize(size_t newSize);
|
||||||
virtual void insert(u64 offset, size_t size);
|
virtual void insert(u64 offset, size_t size);
|
||||||
|
virtual void remove(u64 offset, size_t size);
|
||||||
|
|
||||||
virtual void save();
|
virtual void save();
|
||||||
virtual void saveAs(const std::fs::path &path);
|
virtual void saveAs(const std::fs::path &path);
|
||||||
|
@ -63,6 +63,22 @@ namespace hex::prv {
|
|||||||
patches.insert({ address + size, value });
|
patches.insert({ address + size, value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Provider::remove(u64 offset, size_t size) {
|
||||||
|
auto &patches = getPatches();
|
||||||
|
|
||||||
|
std::vector<std::pair<u64, u8>> patchesToMove;
|
||||||
|
|
||||||
|
for (auto &[address, value] : patches) {
|
||||||
|
if (address > offset)
|
||||||
|
patchesToMove.emplace_back(address, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &[address, value] : patchesToMove)
|
||||||
|
patches.erase(address);
|
||||||
|
for (const auto &[address, value] : patchesToMove)
|
||||||
|
patches.insert({ address - size, value });
|
||||||
|
}
|
||||||
|
|
||||||
void Provider::applyOverlays(u64 offset, void *buffer, size_t size) {
|
void Provider::applyOverlays(u64 offset, void *buffer, size_t size) {
|
||||||
for (auto &overlay : this->m_overlays) {
|
for (auto &overlay : this->m_overlays) {
|
||||||
auto overlayOffset = overlay->getAddress();
|
auto overlayOffset = overlay->getAddress();
|
||||||
|
@ -32,6 +32,7 @@ namespace hex::plugin::builtin::prv {
|
|||||||
|
|
||||||
void resize(size_t newSize) override;
|
void resize(size_t newSize) override;
|
||||||
void insert(u64 offset, size_t size) override;
|
void insert(u64 offset, size_t size) override;
|
||||||
|
void remove(u64 offset, size_t size) override;
|
||||||
|
|
||||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||||
void writeRaw(u64 offset, const void *buffer, size_t size) override;
|
void writeRaw(u64 offset, const void *buffer, size_t size) override;
|
||||||
|
@ -123,7 +123,7 @@ namespace hex::plugin::builtin::prv {
|
|||||||
|
|
||||||
auto position = oldSize;
|
auto position = oldSize;
|
||||||
while (position > offset) {
|
while (position > offset) {
|
||||||
size_t readSize = (position >= (offset + buffer.size())) ? buffer.size() : (position - offset);
|
const auto readSize = std::min<size_t>(position - offset, buffer.size());
|
||||||
|
|
||||||
position -= readSize;
|
position -= readSize;
|
||||||
|
|
||||||
@ -135,6 +135,28 @@ namespace hex::plugin::builtin::prv {
|
|||||||
Provider::insert(offset, size);
|
Provider::insert(offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileProvider::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);
|
||||||
|
}
|
||||||
|
|
||||||
size_t FileProvider::getRealTimeSize() {
|
size_t FileProvider::getRealTimeSize() {
|
||||||
#if defined(OS_LINUX)
|
#if defined(OS_LINUX)
|
||||||
if (struct stat newStats; (this->m_fileStatsValid = fstat(this->m_file, &newStats) == 0)) {
|
if (struct stat newStats; (this->m_fileStatsValid = fstat(this->m_file, &newStats) == 0)) {
|
||||||
|
@ -328,6 +328,37 @@ namespace hex::plugin::builtin {
|
|||||||
u64 m_size;
|
u64 m_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PopupRemove : public ViewHexEditor::Popup {
|
||||||
|
public:
|
||||||
|
PopupRemove(u64 address, size_t size) : m_address(address), m_size(size) {}
|
||||||
|
|
||||||
|
void draw(ViewHexEditor *editor) override {
|
||||||
|
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.remove"_lang);
|
||||||
|
|
||||||
|
ImGui::InputHexadecimal("hex.common.address"_lang, &this->m_address);
|
||||||
|
ImGui::InputHexadecimal("hex.common.size"_lang, &this->m_size);
|
||||||
|
|
||||||
|
View::confirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
|
||||||
|
[&, this]{
|
||||||
|
remove(this->m_address, static_cast<size_t>(this->m_size));
|
||||||
|
editor->closePopup();
|
||||||
|
},
|
||||||
|
[&]{
|
||||||
|
editor->closePopup();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void remove(u64 address, size_t size) {
|
||||||
|
if (ImHexApi::Provider::isValid())
|
||||||
|
ImHexApi::Provider::get()->remove(address, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
u64 m_address;
|
||||||
|
u64 m_size;
|
||||||
|
};
|
||||||
|
|
||||||
ViewHexEditor::ViewHexEditor() : View("hex.builtin.view.hex_editor.name") {
|
ViewHexEditor::ViewHexEditor() : View("hex.builtin.view.hex_editor.name") {
|
||||||
this->m_currDataVisualizer = ContentRegistry::HexEditor::impl::getVisualizers()["hex.builtin.visualizer.hexadecimal.8bit"];
|
this->m_currDataVisualizer = ContentRegistry::HexEditor::impl::getVisualizers()["hex.builtin.visualizer.hexadecimal.8bit"];
|
||||||
|
|
||||||
@ -1373,6 +1404,10 @@ namespace hex::plugin::builtin {
|
|||||||
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.insert"_lang, nullptr, false, providerValid && provider->isResizable())) {
|
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.insert"_lang, nullptr, false, providerValid && provider->isResizable())) {
|
||||||
this->openPopup<PopupInsert>(this->getSelection().getStartAddress(), 0x00);
|
this->openPopup<PopupInsert>(this->getSelection().getStartAddress(), 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.remove"_lang, nullptr, false, providerValid && provider->isResizable())) {
|
||||||
|
this->openPopup<PopupRemove>(this->getSelection().getStartAddress(), 0x00);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,6 +278,7 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.builtin.view.hex_editor.menu.edit.set_base", "Set base address" },
|
{ "hex.builtin.view.hex_editor.menu.edit.set_base", "Set base address" },
|
||||||
{ "hex.builtin.view.hex_editor.menu.edit.resize", "Resize..." },
|
{ "hex.builtin.view.hex_editor.menu.edit.resize", "Resize..." },
|
||||||
{ "hex.builtin.view.hex_editor.menu.edit.insert", "Insert..." },
|
{ "hex.builtin.view.hex_editor.menu.edit.insert", "Insert..." },
|
||||||
|
{ "hex.builtin.view.hex_editor.menu.edit.remove", "Remove..." },
|
||||||
|
|
||||||
{ "hex.builtin.view.information.name", "Data Information" },
|
{ "hex.builtin.view.information.name", "Data Information" },
|
||||||
{ "hex.builtin.view.information.control", "Control" },
|
{ "hex.builtin.view.information.control", "Control" },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user