mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-04-02 13:37:42 -05:00
build: Replace old interval tree in favour of custom libwolv one
This commit is contained in:
@@ -29,11 +29,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||
void writeRaw(u64 offset, const void *buffer, size_t size) override;
|
||||
/**
|
||||
* @brief closes the file streams used to read the file.
|
||||
* Need to be called on file write, see https://github.com/WerWolv/ImHex/issues/988
|
||||
*/
|
||||
void invalidateFiles();
|
||||
|
||||
[[nodiscard]] size_t getActualSize() const override;
|
||||
|
||||
void save() override;
|
||||
@@ -60,20 +56,16 @@ namespace hex::plugin::builtin {
|
||||
|
||||
[[nodiscard]] std::pair<Region, bool> getRegionValidity(u64 address) const override;
|
||||
|
||||
private:
|
||||
wolv::io::File& getFile();
|
||||
|
||||
protected:
|
||||
std::fs::path m_path;
|
||||
wolv::io::File m_file;
|
||||
size_t m_fileSize = 0;
|
||||
|
||||
wolv::io::File m_sizeFile;
|
||||
std::map<std::thread::id, wolv::io::File> m_files;
|
||||
std::atomic<u32> m_mapCounter = 0;
|
||||
|
||||
std::optional<struct stat> m_fileStats;
|
||||
|
||||
bool m_readable = false, m_writable = false;
|
||||
|
||||
std::mutex m_fileAccessMutex, m_writeMutex;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <IITree.h>
|
||||
#include <wolv/container/interval_tree.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace hex::plugin::builtin {
|
||||
protected:
|
||||
bool m_dataValid = false;
|
||||
size_t m_dataSize = 0x00;
|
||||
IITree<u64, std::vector<u8>> m_data;
|
||||
wolv::container::IntervalTree<std::vector<u8>, u64, 0> m_data;
|
||||
|
||||
std::fs::path m_sourceFilePath;
|
||||
};
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
|
||||
#include "ui/hex_editor.hpp"
|
||||
|
||||
#include <IITree.h>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class ViewDiff : public View {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
#include <IITree.h>
|
||||
#include <wolv/container/interval_tree.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
} m_searchSettings, m_decodeSettings;
|
||||
|
||||
using OccurrenceTree = IITree<u64, Occurrence>;
|
||||
using OccurrenceTree = wolv::container::IntervalTree<Occurrence, u64, 0>;
|
||||
|
||||
PerProvider<std::vector<Occurrence>> m_foundOccurrences, m_sortedOccurrences;
|
||||
PerProvider<OccurrenceTree> m_occurrenceTree;
|
||||
|
||||
@@ -86,9 +86,6 @@ namespace hex::plugin::builtin {
|
||||
this->close();
|
||||
}
|
||||
);
|
||||
|
||||
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape)))
|
||||
this->close();
|
||||
}
|
||||
|
||||
[[nodiscard]] ImGuiWindowFlags getFlags() const override {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
#include <hex/api/project_file_manager.hpp>
|
||||
|
||||
@@ -60,24 +59,28 @@ namespace hex::plugin::builtin {
|
||||
if (offset > (this->getActualSize() - size) || buffer == nullptr || size == 0)
|
||||
return;
|
||||
|
||||
auto &file = this->getFile();
|
||||
file.seek(offset);
|
||||
file.readBuffer(reinterpret_cast<u8*>(buffer), size);
|
||||
/*auto currSize = std::fs::file_size(this->m_path);
|
||||
if (this->m_fileSize != currSize) [[unlikely]] {
|
||||
this->m_fileSize = currSize;
|
||||
this->m_file.unmap();
|
||||
this->m_file.map();
|
||||
}*/
|
||||
|
||||
std::memcpy(buffer, this->m_file.getMapping() + offset, size);
|
||||
}
|
||||
|
||||
void FileProvider::writeRaw(u64 offset, const void *buffer, size_t size) {
|
||||
if ((offset + size) > this->getActualSize() || buffer == nullptr || size == 0)
|
||||
return;
|
||||
|
||||
std::scoped_lock lock(this->m_writeMutex);
|
||||
wolv::io::File writeFile(this->m_path, wolv::io::File::Mode::Write);
|
||||
if (!writeFile.isValid())
|
||||
return;
|
||||
|
||||
writeFile.seek(offset);
|
||||
writeFile.writeBuffer(reinterpret_cast<const u8*>(buffer), size);
|
||||
auto currSize = std::fs::file_size(this->m_path);
|
||||
if (this->m_fileSize != currSize) [[unlikely]] {
|
||||
this->m_fileSize = currSize;
|
||||
this->m_file.unmap();
|
||||
this->m_file.map();
|
||||
}
|
||||
|
||||
this->invalidateFiles();
|
||||
std::memcpy(this->m_file.getMapping() + offset, buffer, size);
|
||||
}
|
||||
|
||||
void FileProvider::save() {
|
||||
@@ -125,13 +128,6 @@ namespace hex::plugin::builtin {
|
||||
Provider::insert(offset, size);
|
||||
}
|
||||
|
||||
void FileProvider::invalidateFiles() {
|
||||
for(auto & [threadId, file] : this->m_files){
|
||||
file.close();
|
||||
}
|
||||
this->m_files.clear();
|
||||
}
|
||||
|
||||
void FileProvider::remove(u64 offset, size_t size) {
|
||||
auto oldSize = this->getActualSize();
|
||||
this->resize(oldSize + size);
|
||||
@@ -156,7 +152,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
size_t FileProvider::getActualSize() const {
|
||||
return this->m_sizeFile.getSize();
|
||||
return this->m_fileSize;
|
||||
}
|
||||
|
||||
std::string FileProvider::getName() const {
|
||||
@@ -220,9 +216,10 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
this->m_fileStats = file.getFileInfo();
|
||||
this->m_sizeFile = file.clone();
|
||||
this->m_file = std::move(file);
|
||||
|
||||
this->m_files.emplace(std::this_thread::get_id(), std::move(file));
|
||||
this->m_file.map();
|
||||
this->m_fileSize = this->m_file.getSize();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -231,18 +228,6 @@ namespace hex::plugin::builtin {
|
||||
|
||||
}
|
||||
|
||||
wolv::io::File& FileProvider::getFile() {
|
||||
|
||||
auto threadId = std::this_thread::get_id();
|
||||
if (!this->m_files.contains(threadId)) {
|
||||
std::scoped_lock lock(this->m_fileAccessMutex);
|
||||
if (!this->m_files.contains(threadId))
|
||||
this->m_files.emplace(threadId, this->m_sizeFile.clone());
|
||||
}
|
||||
|
||||
return this->m_files[threadId];
|
||||
}
|
||||
|
||||
void FileProvider::loadSettings(const nlohmann::json &settings) {
|
||||
Provider::loadSettings(settings);
|
||||
|
||||
|
||||
@@ -161,37 +161,25 @@ namespace hex::plugin::builtin {
|
||||
void IntelHexProvider::setBaseAddress(u64 address) {
|
||||
auto oldBase = this->getBaseAddress();
|
||||
|
||||
std::vector<size_t> indices;
|
||||
this->m_data.overlap(oldBase, oldBase + this->getActualSize(), indices);
|
||||
auto regions = this->m_data.overlapping({ oldBase, oldBase + this->getActualSize() });
|
||||
|
||||
IITree<u64, std::vector<u8>> intervals;
|
||||
for (auto &index : indices) {
|
||||
intervals.add(
|
||||
(this->m_data.start(index) - oldBase) + address,
|
||||
(this->m_data.end(index) - oldBase) + address,
|
||||
this->m_data.data(index)
|
||||
);
|
||||
decltype(this->m_data) newIntervals;
|
||||
for (auto &[interval, data] : regions) {
|
||||
newIntervals.insert({ interval.start - oldBase + address, interval.end - oldBase + address }, *data);
|
||||
}
|
||||
|
||||
this->m_data = std::move(intervals);
|
||||
this->m_data.index();
|
||||
this->m_data = newIntervals;
|
||||
|
||||
Provider::setBaseAddress(address);
|
||||
}
|
||||
|
||||
void IntelHexProvider::readRaw(u64 offset, void *buffer, size_t size) {
|
||||
std::vector<size_t> indices;
|
||||
this->m_data.overlap(offset, (offset + size) - 1, indices);
|
||||
auto intervals = this->m_data.overlapping({ offset, (offset + size) - 1 });
|
||||
|
||||
std::memset(buffer, 0x00, size);
|
||||
auto bytes = reinterpret_cast<u8*>(buffer);
|
||||
for (const auto &index : indices) {
|
||||
auto start = this->m_data.start(index);
|
||||
auto end = this->m_data.end(index);
|
||||
auto data = this->m_data.data(index);
|
||||
|
||||
for (u32 i = std::max(start, offset); i <= end && (i - offset) < size; i++) {
|
||||
bytes[i - offset] = data[i - start];
|
||||
for (const auto &[interval, data] : intervals) {
|
||||
for (u32 i = std::max(interval.start, offset); i <= interval.end && (i - offset) < size; i++) {
|
||||
bytes[i - offset] = (*data)[i - interval.start];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,12 +204,11 @@ namespace hex::plugin::builtin {
|
||||
u64 maxAddress = 0x00;
|
||||
for (auto &[address, bytes] : data) {
|
||||
auto endAddress = (address + bytes.size()) - 1;
|
||||
this->m_data.add(address, endAddress, std::move(bytes));
|
||||
this->m_data.emplace({ address, endAddress }, std::move(bytes));
|
||||
|
||||
if (endAddress > maxAddress)
|
||||
maxAddress = endAddress;
|
||||
}
|
||||
this->m_data.index();
|
||||
|
||||
this->m_dataSize = maxAddress + 1;
|
||||
this->m_dataValid = true;
|
||||
@@ -265,22 +252,18 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
std::pair<Region, bool> IntelHexProvider::getRegionValidity(u64 address) const {
|
||||
std::vector<size_t> indices;
|
||||
this->m_data.overlap(address, address, indices);
|
||||
if (indices.empty()) {
|
||||
auto intervals = this->m_data.overlapping({ address, address });
|
||||
if (intervals.empty()) {
|
||||
return Provider::getRegionValidity(address);
|
||||
}
|
||||
|
||||
auto closestIndex = indices.front();
|
||||
for (const auto &index : indices) {
|
||||
if (this->m_data.start(index) < this->m_data.start(closestIndex))
|
||||
closestIndex = index;
|
||||
decltype(this->m_data)::Interval closestInterval = { 0, 0 };
|
||||
for (const auto &[interval, data] : intervals) {
|
||||
if (interval.start < closestInterval.end)
|
||||
closestInterval = interval;
|
||||
}
|
||||
return { Region { closestInterval.start, (closestInterval.end - closestInterval.start) + 1}, true };
|
||||
|
||||
auto start = this->m_data.start(closestIndex);
|
||||
auto end = this->m_data.end(closestIndex);
|
||||
|
||||
return { Region { start, (end - start) + 1 }, true };
|
||||
}
|
||||
|
||||
void IntelHexProvider::loadSettings(const nlohmann::json &settings) {
|
||||
|
||||
@@ -182,12 +182,11 @@ namespace hex::plugin::builtin {
|
||||
u64 maxAddress = 0x00;
|
||||
for (auto &[address, bytes] : data) {
|
||||
auto endAddress = (address + bytes.size()) - 1;
|
||||
this->m_data.add(address, endAddress, std::move(bytes));
|
||||
this->m_data.emplace({ address, endAddress }, std::move(bytes));
|
||||
|
||||
if (endAddress > maxAddress)
|
||||
maxAddress = endAddress;
|
||||
}
|
||||
this->m_data.index();
|
||||
|
||||
this->m_dataSize = maxAddress + 1;
|
||||
this->m_dataValid = true;
|
||||
|
||||
@@ -22,8 +22,7 @@ namespace hex::plugin::builtin {
|
||||
if (this->m_searchTask.isRunning())
|
||||
return { };
|
||||
|
||||
std::vector<size_t> occurrences;
|
||||
if (this->m_occurrenceTree->overlap(address, address, occurrences))
|
||||
if (!this->m_occurrenceTree->overlapping({ address, address }).empty())
|
||||
return HighlightColor();
|
||||
else
|
||||
return std::nullopt;
|
||||
@@ -35,8 +34,8 @@ namespace hex::plugin::builtin {
|
||||
if (this->m_searchTask.isRunning())
|
||||
return;
|
||||
|
||||
std::vector<size_t> occurrences;
|
||||
if (!this->m_occurrenceTree->overlap(address, address, occurrences))
|
||||
auto occurrences = this->m_occurrenceTree->overlapping({ address, address });
|
||||
if (occurrences.empty())
|
||||
return;
|
||||
|
||||
ImGui::BeginTooltip();
|
||||
@@ -48,10 +47,8 @@ namespace hex::plugin::builtin {
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
{
|
||||
auto start = this->m_occurrenceTree->start(occurrence);
|
||||
auto end = this->m_occurrenceTree->end(occurrence) - 1;
|
||||
const auto &bytes = this->m_occurrenceTree->data(occurrence);
|
||||
const auto value = this->decodeValue(ImHexApi::Provider::get(), bytes, 256);
|
||||
auto region = occurrence.value.region;
|
||||
const auto value = this->decodeValue(ImHexApi::Provider::get(), occurrence.value, 256);
|
||||
|
||||
ImGui::ColorButton("##color", ImColor(HighlightColor()));
|
||||
ImGui::SameLine(0, 10);
|
||||
@@ -65,7 +62,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}: ", "hex.builtin.common.region"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("[ 0x{:08X} - 0x{:08X} ]", start, end);
|
||||
ImGui::TextFormatted("[ 0x{:08X} - 0x{:08X} ]", region.getStartAddress(), region.getEndAddress());
|
||||
|
||||
auto demangledValue = llvm::demangle(value);
|
||||
|
||||
@@ -513,8 +510,7 @@ namespace hex::plugin::builtin {
|
||||
this->m_sortedOccurrences.get(provider) = this->m_foundOccurrences.get(provider);
|
||||
|
||||
for (const auto &occurrence : this->m_foundOccurrences.get(provider))
|
||||
this->m_occurrenceTree->add(occurrence.region.getStartAddress(), occurrence.region.getEndAddress() + 1, occurrence);
|
||||
this->m_occurrenceTree->index();
|
||||
this->m_occurrenceTree->insert({ occurrence.region.getStartAddress(), occurrence.region.getEndAddress() }, occurrence);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user