mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-13 07:03:25 +00:00
Adds pattern scanning functionality and corner case tests
Implements a pattern scanning feature that allows searching for byte patterns within a byte range. Adds `scan_for_pattern` method to `PatternScanner` to locate a pattern within a byte span. Adds corner case tests to verify functionality and handle invalid inputs.
This commit is contained in:
@@ -7,6 +7,33 @@
|
||||
namespace omath
|
||||
{
|
||||
|
||||
std::optional<std::span<std::byte>::const_iterator>
|
||||
PatternScanner::scan_for_pattern(const std::string_view& pattern, const std::span<std::byte>& range)
|
||||
{
|
||||
const auto parsed_pattern = parse_pattern(pattern);
|
||||
|
||||
if (!parsed_pattern)
|
||||
return std::nullopt;
|
||||
|
||||
const std::ptrdiff_t scan_size =
|
||||
static_cast<std::ptrdiff_t>(range.size()) - static_cast<std::ptrdiff_t>(pattern.size());
|
||||
|
||||
for (std::ptrdiff_t i = 0; i < scan_size; i++)
|
||||
{
|
||||
bool found = true;
|
||||
|
||||
for (std::ptrdiff_t j = 0; j < static_cast<std::ptrdiff_t>(pattern.size()); j++)
|
||||
{
|
||||
found = parsed_pattern->at(j) == std::nullopt || parsed_pattern->at(j) == *(range.data() + i + j);
|
||||
|
||||
if (!found)
|
||||
break;
|
||||
}
|
||||
if (found)
|
||||
return range.begin() + i;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
std::expected<std::vector<std::optional<std::byte>>, PatternScanError>
|
||||
PatternScanner::parse_pattern(const std::string_view& pattern_string)
|
||||
{
|
||||
@@ -39,14 +66,13 @@ namespace omath
|
||||
|
||||
std::uint8_t value = 0;
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto [_, error_code] = std::from_chars(byte_str.data(), byte_str.data()+byte_str.size(), value, 16);
|
||||
const auto [_, error_code] = std::from_chars(byte_str.data(), byte_str.data() + byte_str.size(), value, 16);
|
||||
|
||||
if (error_code != std::errc{})
|
||||
return std::unexpected(PatternScanError::INVALID_PATTERN_STRING);
|
||||
|
||||
pattern.emplace_back(static_cast<std::byte>(value));
|
||||
|
||||
|
||||
start = end != pattern_string.end() ? std::next(end) : end;
|
||||
}
|
||||
return pattern;
|
||||
|
||||
Reference in New Issue
Block a user