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,
}
}
pub fn append<T: Sized + Copy>(&mut self, data: &T) {
let size = size_of::<T>();
let end = self.offset + size;
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<T: Sized + Copy>(&mut self, data: &[T]) {
let size = size_of::<T>() * data.len();
let end = self.offset + size;
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<MmapReader> {
Self::at_offset(file, 0)
}
pub fn at_offset(file: &File, offset: usize) -> io::Result<MmapReader> {
let mmap = unsafe { Mmap::map(file)? };
Ok(MmapReader {
mmap,
offset,
})
}
pub fn get<'b : 'a, T: Sized + Copy>(&mut self) -> &'b T {
let size = size_of::<T>();
let end = self.offset + size;
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::<T>();
let end = self.offset + size * n_elements;
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()
}
}