Skip to main content

embedded_storage_file/
backend_mmap.rs

1use crate::synhronous::{BufferBackend, Error, NorMemory};
2
3#[derive(Debug)]
4pub struct MmapFile {
5    pub file: std::fs::File,
6    pub mmap: memmap2::MmapMut,
7}
8
9pub type NorMemoryInFile<const READ_SIZE: usize, const WRITE_SIZE: usize, const ERASE_SIZE: usize> =
10    NorMemory<MmapFile, READ_SIZE, WRITE_SIZE, ERASE_SIZE>;
11
12impl<const READ_SIZE: usize, const WRITE_SIZE: usize, const ERASE_SIZE: usize>
13    NorMemoryInFile<READ_SIZE, WRITE_SIZE, ERASE_SIZE>
14{
15    pub fn new<P: std::convert::AsRef<std::path::Path>>(
16        path: P,
17        size: usize,
18    ) -> Result<Self, std::io::Error> {
19        let is_new = !path.as_ref().exists();
20        let file = std::fs::OpenOptions::new()
21            .read(true)
22            .write(true)
23            .create(true)
24            .truncate(false)
25            .open(path)?;
26        file.set_len(size as u64)?;
27        let mut mmap = unsafe { memmap2::MmapOptions::new().map_mut(&file)? };
28        if is_new {
29            mmap[..size].fill(0xFF);
30        }
31        Ok(Self {
32            buffer: MmapFile { file, mmap },
33        })
34    }
35
36    pub fn new_from_mmap(mmap: MmapFile) -> Self {
37        Self { buffer: mmap }
38    }
39}
40
41impl BufferBackend for MmapFile {
42    fn with_data<F>(&self, from: usize, to: usize, mut f: F) -> Result<(), Error>
43    where
44        F: FnMut(&[u8]) -> Result<(), Error>,
45    {
46        if to > self.size() {
47            return Err(Error::OutOfBounds);
48        }
49        if from > to {
50            return Err(Error::OutOfBounds);
51        }
52        let b = &self.mmap[from..to];
53        f(b)
54    }
55
56    fn with_data_mut<F>(&mut self, from: usize, to: usize, mut f: F) -> Result<(), Error>
57    where
58        F: FnMut(&mut [u8]) -> Result<(), Error>,
59    {
60        if to > self.size() {
61            return Err(Error::OutOfBounds);
62        }
63        if from > to {
64            return Err(Error::OutOfBounds);
65        }
66        let b = &mut self.mmap[from..to];
67        f(b)
68    }
69
70    fn size(&self) -> usize {
71        self.mmap.len()
72    }
73}