use crate::Region;
pub struct OverlapIterator<'a, R, I>
where
R: Region,
I: Iterator<Item = R>,
{
memory: &'a [u8],
regions: I,
base_address: u32,
}
pub trait IterableByOverlaps<'a, R, I>
where
R: Region,
I: Iterator<Item = R>,
{
fn overlaps(self, memory: &'a [u8], base_address: u32) -> OverlapIterator<R, I>;
}
impl<'a, R, I> Iterator for OverlapIterator<'a, R, I>
where
R: Region,
I: Iterator<Item = R>,
{
type Item = (&'a [u8], R, u32);
fn next(&mut self) -> Option<Self::Item> {
while let Some(region) = self.regions.next() {
let mut block_range = (0..self.memory.len())
.skip_while(|index| !region.contains(self.base_address + *index as u32))
.take_while(|index| region.contains(self.base_address + *index as u32));
if let Some(start) = block_range.next() {
let end = block_range.last().unwrap_or(start) + 1;
return Some((
&self.memory[start..end],
region,
self.base_address + start as u32,
));
}
}
None
}
}
impl<'a, R, I> IterableByOverlaps<'a, R, I> for I
where
R: Region,
I: Iterator<Item = R>,
{
fn overlaps(self, memory: &'a [u8], base_address: u32) -> OverlapIterator<R, I> {
OverlapIterator {
memory,
regions: self,
base_address,
}
}
}