1 | use crate::Region; |
2 | |
3 | /// Iterator producing block-region pairs, where each memory block maps to each |
4 | /// region. |
5 | pub struct OverlapIterator<'a, R, I> |
6 | where |
7 | R: Region, |
8 | I: Iterator<Item = R>, |
9 | { |
10 | memory: &'a [u8], |
11 | regions: I, |
12 | base_address: u32, |
13 | } |
14 | |
15 | /// Trait allowing us to automatically add an `overlaps` function to all iterators over [`Region`] |
16 | pub trait IterableByOverlaps<'a, R, I> |
17 | where |
18 | R: Region, |
19 | I: Iterator<Item = R>, |
20 | { |
21 | /// Obtain an [`OverlapIterator`] over a subslice of `memory` that overlaps with the region in `self` |
22 | fn overlaps(self, memory: &'a [u8], base_address: u32) -> OverlapIterator<R, I>; |
23 | } |
24 | |
25 | impl<'a, R, I> Iterator for OverlapIterator<'a, R, I> |
26 | where |
27 | R: Region, |
28 | I: Iterator<Item = R>, |
29 | { |
30 | type Item = (&'a [u8], R, u32); |
31 | |
32 | fn next(&mut self) -> Option<Self::Item> { |
33 | while let Some(region: R) = self.regions.next() { |
34 | // TODO: This might be possible to do in a smarter way? |
35 | let mut block_range: impl Iterator = (0..self.memory.len()) |
36 | .skip_while(|index: &usize| !region.contains(self.base_address + *index as u32)) |
37 | .take_while(|index: &usize| region.contains(self.base_address + *index as u32)); |
38 | if let Some(start: usize) = block_range.next() { |
39 | let end: usize = block_range.last().unwrap_or(default:start) + 1; |
40 | return Some(( |
41 | &self.memory[start..end], |
42 | region, |
43 | self.base_address + start as u32, |
44 | )); |
45 | } |
46 | } |
47 | None |
48 | } |
49 | } |
50 | |
51 | /// Blanket implementation for all types implementing [`Iterator`] over [`Regions`] |
52 | impl<'a, R, I> IterableByOverlaps<'a, R, I> for I |
53 | where |
54 | R: Region, |
55 | I: Iterator<Item = R>, |
56 | { |
57 | fn overlaps(self, memory: &'a [u8], base_address: u32) -> OverlapIterator<R, I> { |
58 | OverlapIterator { |
59 | memory, |
60 | regions: self, |
61 | base_address, |
62 | } |
63 | } |
64 | } |
65 | |