Files
imhex/plugins/builtin/source/content/differing_byte_searcher.cpp
Artem Garmash de7d549fc6 feat: Added skipping sequences of repeating bytes (#2228)
This PR implements a neat little feature I missed - the ability to jump
to the next/previous differing byte, skipping the chunk of repeating
bytes. Very useful when you analyze a raw flash dump and want to skip
the large sections of `0x00`s/`0xFF`s.

Some implementation details worth validating:
- I wasn't sure what is the correct place to put the new menu entries
into. The possible candidates were `File -> Go to address...` and `Edit
-> Follow selection`. I chose the former, although the latter may be a
better fit since it already states that the action is related to the
selection. Overall, it may be a good moment to refine these menu entries
in general.
- I didn't add any tests since I'm not sure what is the project's policy
for those. Please let me know if I need to add some!
- I added the machine-generated translations for the new menu entries
which may be considered a questionable thing. Please let me know if
you're unhappy with those, I'll drop the commit.
 
Also, thanks for such a nice tool, I use it a lot and was glad to build
a new feature for it!
2025-08-09 19:40:04 +02:00

52 lines
1.7 KiB
C++

#include <content/differing_byte_searcher.hpp>
#include <hex/api/imhex_api.hpp>
namespace hex::plugin::builtin {
void findNextDifferingByte(
const std::function< u64(prv::Provider*) >& lastValidAddressProvider,
const std::function< bool(u64, u64) >& addressComparator,
const std::function< void(u64*) >& addressStepper,
bool *didFindNextValue,
bool *didReachEndAddress,
u64* foundAddress
) {
auto provider = ImHexApi::Provider::get();
if (provider == nullptr)
return;
const auto selection = ImHexApi::HexEditor::getSelection();
if (!selection.has_value())
return;
if (selection->getSize() != 1)
return;
auto currentAddress = selection->getStartAddress();
u8 givenValue = 0;
provider->read(currentAddress, &givenValue, 1);
u8 currentValue = 0;
*didFindNextValue = false;
*didReachEndAddress = false;
auto endAddress = lastValidAddressProvider(provider);
while (addressComparator(currentAddress, endAddress)) {
addressStepper(&currentAddress);
if (currentAddress == endAddress) {
*didReachEndAddress = true;
}
provider->read(currentAddress, &currentValue, 1);
if (currentValue != givenValue) {
*didFindNextValue = true;
*foundAddress = currentAddress;
break;
}
}
}
bool canSearchForDifferingByte() {
return ImHexApi::Provider::isValid() && ImHexApi::HexEditor::isSelectionValid() && ImHexApi::HexEditor::getSelection()->getSize() == 1;
}
}