bmatcher_core/target.rs
1/// A trait for targets that can be matched against a binary pattern.
2///
3/// Implementing this trait allows matching against data sources that may not be
4/// continuous (e.g., fragmented data or packed representations), offering greater flexibility
5/// compared to directly using a `u8` slice.
6///
7/// By default a `u8` slice does implement this trait.
8pub trait MatchTarget {
9 /// Returns the total length of the data which will be scaned when matching a binary pattern.
10 fn match_length(&self) -> usize;
11
12 /// Retrieves a subrange of the data, starting at the specified offset and spanning the given number of bytes.
13 ///
14 /// # Parameters
15 /// - `offset`: The starting position within the data.
16 /// - `byte_count`: The number of bytes to include in the subrange.
17 ///
18 /// # Returns
19 /// An `Option` containing a slice of the data if the range is valid; otherwise, `None`.
20 fn subrange(&self, offset: usize, byte_count: usize) -> Option<&[u8]>;
21
22 /// Translates an absolute address to an index within the matchable data.
23 ///
24 /// # Parameters
25 /// - `address`: The absolute address to translate.
26 ///
27 /// # Returns
28 /// An `Option` containing the translated index if the address is valid; otherwise, `None`.
29 fn translate_absolute_address(&self, address: u64) -> Option<usize>;
30}
31
32impl MatchTarget for &[u8] {
33 fn match_length(&self) -> usize {
34 self.len()
35 }
36
37 fn subrange(&self, offset: usize, byte_count: usize) -> Option<&[u8]> {
38 if offset + byte_count > self.len() {
39 return None;
40 }
41
42 Some(&self[offset..offset + byte_count])
43 }
44
45 fn translate_absolute_address(&self, address: u64) -> Option<usize> {
46 let own_address = self.as_ptr() as u64;
47 if own_address < address || address >= own_address + self.len() as u64 {
48 None
49 } else {
50 Some((address - own_address) as usize)
51 }
52 }
53}