memflow 0.2.0-beta1

core components of the memflow physical memory introspection framework
Documentation
use crate::mem::mem_data::{MemData, MemoryRange, MemoryRangeCallback};
use crate::types::{imem, umem, Address};
use cglue::prelude::v1::*;
use std::prelude::v1::*;

pub struct GapRemover<'a> {
    set: rangemap::RangeSet<Address>,
    out: Option<MemoryRangeCallback<'a>>,
    gap_size: imem,
    start: Address,
    end: Address,
}

impl<'a> GapRemover<'a> {
    pub fn new(out: MemoryRangeCallback<'a>, gap_size: imem, start: Address, end: Address) -> Self {
        Self {
            set: Default::default(),
            out: Some(out),
            gap_size,
            start,
            end,
        }
    }

    pub fn push_range(&mut self, MemData(in_virtual, size): MemoryRange) {
        self.set.insert(in_virtual..(in_virtual + size));
    }
}

impl<'a> Drop for GapRemover<'a> {
    fn drop(&mut self) {
        self.set
            .gaps(&(self.start..self.end))
            .filter(|r| {
                assert!(r.end >= r.start);
                self.gap_size >= 0 && (r.end - r.start) as umem <= self.gap_size as umem
            })
            .collect::<Vec<_>>()
            .into_iter()
            .for_each(|r| self.set.insert(r));

        self.set
            .iter()
            .map(|r| {
                let address = r.start;
                assert!(r.end >= address);
                let size = r.end - address;
                MemData(address, size as umem)
            })
            .feed_into(self.out.take().unwrap());
    }
}

impl<'a> Extend<MemoryRange> for GapRemover<'a> {
    fn extend<T>(&mut self, iter: T)
    where
        T: IntoIterator<Item = MemoryRange>,
    {
        iter.into_iter().for_each(|r| self.push_range(r));
    }
}