sys: Added support for providers with unreadable regions

This commit is contained in:
WerWolv
2022-08-10 09:26:48 +02:00
parent 19a0dc80db
commit 5c13cf9dbf
8 changed files with 111 additions and 18 deletions

View File

@@ -21,11 +21,11 @@ namespace hex {
size_t size;
[[nodiscard]] constexpr bool isWithin(const Region &other) const {
return (this->getStartAddress() >= other.getStartAddress()) && (this->getEndAddress() <= other.getEndAddress());
return (this->getStartAddress() >= other.getStartAddress()) && (this->getEndAddress() <= other.getEndAddress()) && *this != Invalid() && other != Invalid();
}
[[nodiscard]] constexpr bool overlaps(const Region &other) const {
return (this->getEndAddress() >= other.getStartAddress()) && (this->getStartAddress() < other.getEndAddress());
return (this->getEndAddress() >= other.getStartAddress()) && (this->getStartAddress() < other.getEndAddress()) && *this != Invalid() && other != Invalid();
}
[[nodiscard]] constexpr u64 getStartAddress() const {
@@ -39,6 +39,14 @@ namespace hex {
[[nodiscard]] constexpr size_t getSize() const {
return this->size;
}
constexpr bool operator==(const Region &other) const {
return this->address == other.address && this->size == other.size;
}
constexpr static Region Invalid() {
return { 0, 0 };
}
};
}

View File

@@ -99,6 +99,8 @@ namespace hex::prv {
void markDirty(bool dirty = true) { this->m_dirty = dirty; }
[[nodiscard]] bool isDirty() const { return this->m_dirty; }
virtual std::pair<Region, bool> getRegionValidity(u64 address) const;
protected:
u32 m_currPage = 0;
u64 m_baseAddress = 0;

View File

@@ -244,9 +244,11 @@ namespace hex {
std::unique_ptr<pl::PatternLanguage> createDefaultRuntime(prv::Provider *provider) {
auto runtime = std::make_unique<pl::PatternLanguage>();
runtime->setDataSource([provider](u64 offset, u8 *buffer, size_t size) {
provider->read(offset, buffer, size);
}, 0, 0);
if (provider != nullptr) {
runtime->setDataSource([provider](u64 offset, u8 *buffer, size_t size) {
provider->read(offset, buffer, size);
}, provider->getBaseAddress(), provider->getActualSize());
}
runtime->setIncludePaths(fs::getDefaultPaths(fs::ImHexPath::PatternsInclude));

View File

@@ -254,4 +254,36 @@ namespace hex::prv {
this->m_currPage = settings["currPage"];
}
std::pair<Region, bool> Provider::getRegionValidity(u64 address) const {
if (address > this->getActualSize())
return { Region::Invalid(), false };
bool insideValidRegion = false;
std::optional<u64> nextRegionAddress;
for (const auto &overlay : this->m_overlays) {
Region overlayRegion = { overlay->getAddress(), overlay->getSize() };
if (!nextRegionAddress.has_value() || overlay->getAddress() < nextRegionAddress) {
nextRegionAddress = overlayRegion.getStartAddress();
}
if (Region { address, 1 }.overlaps(overlayRegion)) {
insideValidRegion = true;
}
}
for (const auto &[patchAddress, value] : this->m_patches.back()) {
if (!nextRegionAddress.has_value() || patchAddress < nextRegionAddress)
nextRegionAddress = patchAddress;
if (address == patchAddress)
insideValidRegion = true;
}
if (!nextRegionAddress.has_value())
return { Region { address, this->getActualSize() - address }, true };
else
return { Region { address, *nextRegionAddress - address }, insideValidRegion };
}
}