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

@@ -0,0 +1,33 @@
#pragma once
#include <hex/providers/provider.hpp>
namespace hex::plugin::builtin::prv {
class NullProvider : public hex::prv::Provider {
public:
explicit NullProvider() = default;
~NullProvider() override = default;
[[nodiscard]] bool isAvailable() const override { return true; }
[[nodiscard]] bool isReadable() const override { return true; }
[[nodiscard]] bool isWritable() const override { return false; }
[[nodiscard]] bool isResizable() const override { return false; }
[[nodiscard]] bool isSavable() const override { return false; }
void readRaw(u64 offset, void *buffer, size_t size) override { hex::unused(offset, buffer, size); }
void writeRaw(u64 offset, const void *buffer, size_t size) override { hex::unused(offset, buffer, size); }
[[nodiscard]] size_t getActualSize() const override { return 0x00; }
[[nodiscard]] std::string getName() const override { return "None"; }
[[nodiscard]] std::vector<std::pair<std::string, std::string>> getDataInformation() const override { return { }; }
void loadSettings(const nlohmann::json &settings) override { hex::unused(settings); }
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override { return settings; }
[[nodiscard]] std::string getTypeName() const override {
return "hex.builtin.provider.null";
}
};
}

View File

@@ -2,6 +2,7 @@
#include "content/providers/gdb_provider.hpp"
#include "content/providers/file_provider.hpp"
#include "content/providers/null_provider.hpp"
#include "content/providers/disk_provider.hpp"
#include <hex/api/project_file_manager.hpp>
@@ -13,8 +14,9 @@ namespace hex::plugin::builtin {
void registerProviders() {
ContentRegistry::Provider::add<prv::FileProvider>(false);
ContentRegistry::Provider::add<prv::GDBProvider>();
ContentRegistry::Provider::add<prv::NullProvider>(false);
ContentRegistry::Provider::add<prv::DiskProvider>();
ContentRegistry::Provider::add<prv::GDBProvider>();
ProjectFile::registerHandler({
.basePath = "providers",
@@ -53,9 +55,7 @@ namespace hex::plugin::builtin {
}
tar.write(basePath / "providers.json",
nlohmann::json({
{"providers", providerIds}
}).dump(4)
nlohmann::json({ {"providers", providerIds } }).dump(4)
);
return true;

View File

@@ -728,6 +728,16 @@ namespace hex::plugin::builtin {
if (ImHexApi::Provider::isValid()) {
auto provider = ImHexApi::Provider::get();
std::pair<Region, bool> validRegion = { Region::Invalid(), false };
const auto isCurrRegionValid = [&validRegion, &provider](u64 address){
auto &[currRegion, currRegionValid] = validRegion;
if (!Region{ address, 1 }.isWithin(currRegion)) {
validRegion = provider->getRegionValidity(address);
}
return currRegionValid;
};
ImGuiListClipper clipper;
clipper.Begin(std::ceil(provider->getSize() / (long double)(this->m_bytesPerRow)), CharacterSize.y);
@@ -735,7 +745,7 @@ namespace hex::plugin::builtin {
this->m_visibleRowCount = clipper.DisplayEnd - clipper.DisplayStart;
// Loop over rows
for (i128 y = clipper.DisplayStart; y < u64(clipper.DisplayEnd); y++) {
for (u64 y = u64(clipper.DisplayStart); y < u64(clipper.DisplayEnd); y++) {
// Draw address column
ImGui::TableNextRow();
@@ -800,13 +810,14 @@ namespace hex::plugin::builtin {
if (x < std::ceil(float(validBytes) / bytesPerCell)) {
auto cellStartPos = getCellPosition();
auto cellSize = (CharacterSize * ImVec2(this->m_currDataVisualizer->getMaxCharsPerCell(), 1) + (ImVec2(3, 2) * ImGui::GetStyle().CellPadding) - ImVec2(1, 0) * ImGui::GetStyle().CellPadding) + ImVec2(1, 0);
auto maxCharsPerCell = this->m_currDataVisualizer->getMaxCharsPerCell();
auto [foregroundColor, backgroundColor] = cellColors[x];
if (isColumnSeparatorColumn(x + 1, columnCount) && selectionMax != x + y * columnCount) {
cellSize.x += SeparatorColumWidth + 1;
}
if (y == clipper.DisplayStart)
if (y == u64(clipper.DisplayStart))
cellSize.y -= (ImGui::GetStyle().CellPadding.y + 1);
// Draw highlights and selection
@@ -830,8 +841,11 @@ namespace hex::plugin::builtin {
// Draw cell content
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushItemWidth((CharacterSize * this->m_currDataVisualizer->getMaxCharsPerCell()).x);
this->drawCell(byteAddress, &bytes[x * bytesPerCell], bytesPerCell, cellHovered);
ImGui::PushItemWidth((CharacterSize * maxCharsPerCell).x);
if (isCurrRegionValid(byteAddress))
this->drawCell(byteAddress, &bytes[x * bytesPerCell], bytesPerCell, cellHovered);
else
ImGui::TextFormatted("{}", std::string(maxCharsPerCell, '?'));
ImGui::PopItemWidth();
ImGui::PopStyleVar();
@@ -875,7 +889,9 @@ namespace hex::plugin::builtin {
this->drawSelectionFrame(x, y, byteAddress, 1, cellStartPos, cellSize);
}
if (std::isprint(bytes[x]))
if (!isCurrRegionValid(byteAddress))
ImGui::TextFormatted("?");
else if (std::isprint(bytes[x]))
ImGui::TextFormatted("{:c}", bytes[x]);
else
ImGui::TextDisabled(".");
@@ -917,7 +933,7 @@ namespace hex::plugin::builtin {
const auto x = address % this->m_bytesPerRow;
if (x < validBytes) {
if (x < validBytes && isCurrRegionValid(address)) {
auto [foregroundColor, backgroundColor] = cellColors[x / bytesPerCell];
// Draw highlights and selection
@@ -951,13 +967,13 @@ namespace hex::plugin::builtin {
if ((ImGui::IsMouseDown(ImGuiMouseButton_Left) && this->m_selectionStart != this->m_selectionEnd)) {
auto fractionPerLine = 1.0 / (this->m_visibleRowCount + 1);
if (y == clipper.DisplayStart + 2) {
if (y == u64(clipper.DisplayStart + 2)) {
if (i128(this->m_selectionEnd - provider->getBaseAddress() - provider->getCurrentPageAddress()) <= (i64(clipper.DisplayStart + 2) * this->m_bytesPerRow)) {
this->m_shouldScrollToSelection = false;
ImGui::SetScrollHereY(fractionPerLine * 4);
}
} else if (y == (clipper.DisplayEnd - 2)) {
} else if (y == u64(clipper.DisplayEnd - 2)) {
if (i128(this->m_selectionEnd - provider->getBaseAddress() - provider->getCurrentPageAddress()) >= (i64(clipper.DisplayEnd - 2) * this->m_bytesPerRow)) {
this->m_shouldScrollToSelection = false;
ImGui::SetScrollHereY(fractionPerLine * (this->m_visibleRowCount - 1));