sigscan 0.1.1

a `#[no_std]` sigscanning crate
Documentation
#![no_std]

/// Macro for generating a pattern to use with `scan` as writing out `Some(x)` and `None` can be quite tedious
#[macro_export]
macro_rules! pattern {
    [$($item:tt) *] => {
        &[$(
            $crate::__pattern_inner!($item),
        )*]
    };
}

#[macro_export]
macro_rules! __pattern_inner {
    (?) => {
        None
    };
    ($x:expr) => {
        Some($x)
    };
}

/// Scan for a pattern, where `None` is a wildcard
pub fn scan<P: AsRef<[Option<u8>]>, B: AsRef<[u8]>>(pattern: P, bytes: B) -> Option<usize> {
    let bytes = bytes.as_ref();
    let pattern = pattern.as_ref();

    for (i, window) in bytes.windows(pattern.len()).enumerate() {
        // go through each byte in the pattern
        let mut matches = true;
        for j in 0..pattern.len() {
            // if we find a byte that doesn't match we don't need to check the rest of the bytes
            if pattern[j] != None && pattern[j] != Some(window[j]) {
                matches = false;
                break
            }
        }

        if matches {
            return Some(i);
        }
    }

    None
}