mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-13 07:03:25 +00:00
improved scanner interface
This commit is contained in:
@@ -5,9 +5,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <expected>
|
#include <expected>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <span>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <span>
|
|
||||||
|
|
||||||
// ReSharper disable once CppInconsistentNaming
|
// ReSharper disable once CppInconsistentNaming
|
||||||
class unit_test_pattern_scan_read_test_Test;
|
class unit_test_pattern_scan_read_test_Test;
|
||||||
@@ -20,7 +20,6 @@ class unit_test_pattern_scan_corner_case_3_Test;
|
|||||||
// ReSharper disable once CppInconsistentNaming
|
// ReSharper disable once CppInconsistentNaming
|
||||||
class unit_test_pattern_scan_corner_case_4_Test;
|
class unit_test_pattern_scan_corner_case_4_Test;
|
||||||
|
|
||||||
|
|
||||||
namespace omath
|
namespace omath
|
||||||
{
|
{
|
||||||
enum class PatternScanError
|
enum class PatternScanError
|
||||||
@@ -34,10 +33,42 @@ namespace omath
|
|||||||
friend unit_test_pattern_scan_corner_case_2_Test;
|
friend unit_test_pattern_scan_corner_case_2_Test;
|
||||||
friend unit_test_pattern_scan_corner_case_3_Test;
|
friend unit_test_pattern_scan_corner_case_3_Test;
|
||||||
friend unit_test_pattern_scan_corner_case_4_Test;
|
friend unit_test_pattern_scan_corner_case_4_Test;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
static std::optional<std::span<std::byte>::const_iterator>
|
static std::optional<std::span<std::byte>::const_iterator> scan_for_pattern(const std::span<std::byte>& range,
|
||||||
scan_for_pattern(const std::string_view& pattern, const std::span<std::byte>& range);
|
const std::string_view& pattern);
|
||||||
|
|
||||||
|
template<class IteratorType>
|
||||||
|
static IteratorType scan_for_pattern(const IteratorType& begin, const IteratorType& end,
|
||||||
|
const std::string_view& pattern)
|
||||||
|
{
|
||||||
|
const auto parsed_pattern = parse_pattern(pattern);
|
||||||
|
|
||||||
|
if (!parsed_pattern) [[unlikely]]
|
||||||
|
return end;
|
||||||
|
|
||||||
|
const auto whole_range_size = static_cast<std::ptrdiff_t>(std::distance(begin, end));
|
||||||
|
|
||||||
|
const std::ptrdiff_t scan_size = whole_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>(parsed_pattern->size()); j++)
|
||||||
|
{
|
||||||
|
found = parsed_pattern->at(j) == std::nullopt || parsed_pattern->at(j) == *(begin + i + j);
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
return begin + i;
|
||||||
|
}
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
static std::expected<std::vector<std::optional<std::byte>>, PatternScanError>
|
static std::expected<std::vector<std::optional<std::byte>>, PatternScanError>
|
||||||
|
|||||||
@@ -8,31 +8,14 @@ namespace omath
|
|||||||
{
|
{
|
||||||
|
|
||||||
std::optional<std::span<std::byte>::const_iterator>
|
std::optional<std::span<std::byte>::const_iterator>
|
||||||
PatternScanner::scan_for_pattern(const std::string_view& pattern, const std::span<std::byte>& range)
|
PatternScanner::scan_for_pattern(const std::span<std::byte>& range, const std::string_view& pattern)
|
||||||
{
|
{
|
||||||
const auto parsed_pattern = parse_pattern(pattern);
|
auto result = scan_for_pattern(range.begin(), range.end(), pattern);
|
||||||
|
|
||||||
if (!parsed_pattern) [[unlikely]]
|
if (result == range.end())
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
const std::ptrdiff_t scan_size =
|
return result;
|
||||||
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>(parsed_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>
|
std::expected<std::vector<std::optional<std::byte>>, PatternScanError>
|
||||||
PatternScanner::parse_pattern(const std::string_view& pattern_string)
|
PatternScanner::parse_pattern(const std::string_view& pattern_string)
|
||||||
|
|||||||
Reference in New Issue
Block a user