Files
imhex/plugins/builtin/include/content/providers/intel_hex_provider.hpp
sonorousfreq 96b27645d6 feat: Add region sidebar list to Intel Hex and Motorola SREC providers (#2417)
Add block list for intel hex and motorola srec

TEST: Load various hex and srec files
 - Test search capability
 - Test jump to section

### Problem description
The intel-hex/motorola formats can be loaded but not quite ideally,
including there is no list of segments/blocks that
can be extracted from file layout (metadata).

### Implementation description
I implemented similar feature as process monitor provider does, to
extract chunks while parsing the file and show
them as a sidebar list

### Screenshots
Looks like this:
<img width="1893" height="897" alt="image"
src="https://github.com/user-attachments/assets/c37d46cb-d129-4f9a-bb9a-d8969f397c6e"
/>



### Additional things
There are some improvements that could be made:
1. There is currently no API to jump to address, which would be useful
to jump to beginning of a hex/srec segment.
2. When jumping with setSelection, jumping backwards makes the first
visible line the jump address/line, however, when jumping forward, the
jump address is at the bottom (see image).
3. Unsure about convention for searches, should we search elements as
startsWith given user string, or contains or including 0x prefix or not,
whether to keep prefix zeros since the region size is 8 bytes, but
addresses should be <= 32 bits, etc.
2025-09-11 09:50:38 +00:00

73 lines
2.8 KiB
C++

#pragma once
#include <fonts/vscode_icons.hpp>
#include <hex/providers/provider.hpp>
#include <hex/ui/widgets.hpp>
#include <wolv/container/interval_tree.hpp>
#include <wolv/utils/expected.hpp>
namespace hex::plugin::builtin {
struct MemoryRegion {
Region region;
std::string name;
constexpr bool operator<(const MemoryRegion &other) const {
return this->region.getStartAddress() < other.region.getStartAddress();
}
};
class IntelHexProvider : public hex::prv::Provider,
public hex::prv::IProviderDataDescription,
public hex::prv::IProviderFilePicker,
public hex::prv::IProviderSidebarInterface {
public:
IntelHexProvider() = default;
~IntelHexProvider() override = default;
[[nodiscard]] bool isAvailable() const override { return m_dataValid; }
[[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 setBaseAddress(u64 address) override;
void drawSidebarInterface() override;
void readRaw(u64 offset, void *buffer, size_t size) override;
void writeRaw(u64 offset, const void *buffer, size_t size) override;
[[nodiscard]] u64 getActualSize() const override;
void processMemoryRegions(wolv::util::Expected<std::map<u64, std::vector<u8>>, std::string> data);
static bool memoryRegionFilter(const std::string &search, const MemoryRegion &memoryRegion);
bool open() override;
void close() override;
[[nodiscard]] std::string getName() const override;
[[nodiscard]] std::vector<Description> getDataDescription() const override;
void loadSettings(const nlohmann::json &settings) override;
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override;
[[nodiscard]] UnlocalizedString getTypeName() const override {
return "hex.builtin.provider.intel_hex";
}
[[nodiscard]] const char* getIcon() const override {
return ICON_VS_TABLE;
}
[[nodiscard]] bool handleFilePicker() override;
std::pair<Region, bool> getRegionValidity(u64 address) const override;
protected:
bool m_dataValid = false;
size_t m_dataSize = 0x00;
wolv::container::IntervalTree<std::vector<u8>> m_data;
ui::SearchableWidget<MemoryRegion> m_regionSearchWidget = ui::SearchableWidget<MemoryRegion>(memoryRegionFilter);
std::vector<MemoryRegion> m_memoryRegions;
std::fs::path m_sourceFilePath;
};
}