use super::*; use std::slice::from_raw_parts; pub struct MmapWriter<'a> { mmap: &'a mut MmapMut, offset: usize, } impl<'a> MmapWriter<'a> { pub fn new(mmap: &mut MmapMut) -> MmapWriter { Self::at_offset(mmap, 0) } pub fn at_offset(mmap: &mut MmapMut, offset: usize) -> MmapWriter { MmapWriter { mmap, offset, } } /// Only use with Integers pub fn append(&mut self, data: &T) { let size = size_of::(); let end = self.offset + size; //println!("copy {}..{} ({}) to mmap ({})", self.offset, end, size, self.mmap.len()); if let Some(range) = self.mmap.get_mut(self.offset..end) { let ptr = data as *const T as *const u8; let src = unsafe { from_raw_parts(ptr, size) }; range.copy_from_slice(&src); self.offset = end; } else { panic!("MmapWriter::append() not enough file space") } } pub fn append_slice(&mut self, data: &[T]) { let size = size_of::() * data.len(); let end = self.offset + size; //println!("copy {}..{} ({}) to mmap ({})", self.offset, end, size, self.mmap.len()); if let Some(range) = self.mmap.get_mut(self.offset..end) { let ptr = data as *const [T] as *const u8; let src = unsafe { from_raw_parts(ptr, size) }; range.copy_from_slice(&src); self.offset = end; } else { panic!("MmapWriter::append() not enough file space") } } } pub struct MmapReader { mmap: Mmap, offset: usize, } impl<'a> MmapReader { pub fn new(file: &File) -> io::Result { Self::at_offset(file, 0) } pub fn at_offset(file: &File, offset: usize) -> io::Result { let mmap = unsafe { Mmap::map(file)? }; Ok(MmapReader { mmap, offset, }) } /// Only use with Integers pub fn get<'b : 'a, T: Sized + Copy>(&mut self) -> &'b T { let size = size_of::(); let end = self.offset + size; //println!("read {}..{} ({}) from mmap ({})", self.offset, end, size, self.mmap.len()); if let Some(range) = self.mmap.get(self.offset..end) { let data = range.as_ptr() as *const T; self.offset = end; unsafe { return data.as_ref().expect("reading from mapped file, can not be null"); } } else { panic!("MmapReader::get() not enough file space") } } pub fn get_slice<'b : 'a, T: Sized + Copy>(&mut self, n_elements: usize) -> &[T] { let size = size_of::(); let end = self.offset + size * n_elements; //println!("read {}..{} ({}) from mmap ({})", self.offset, end, size, self.mmap.len()); if let Some(range) = self.mmap.get(self.offset..end) { let ptr = range.as_ptr() as *const T; self.offset = end; unsafe { return from_raw_parts(ptr, n_elements); } } else { panic!("MmapReader::get_slice() not enough file space") } } pub fn get_str_slice<'b : 'a>(&mut self, n_elements: usize) -> &str { let slice = self.get_slice(n_elements); std::str::from_utf8(slice).unwrap() } }