use std::fs;
use std::io;
use std::path::Path;
use std::sync::Arc;
use memmap::{Mmap, Protection};
pub struct MmapReadOnly {
map: Arc<Mmap>,
offset: usize,
len: usize,
}
impl MmapReadOnly {
pub fn open(file: &fs::File) -> io::Result<MmapReadOnly> {
Ok(try!(Mmap::open(file, Protection::Read)).into())
}
pub fn open_path<P: AsRef<Path>>(path: P) -> io::Result<MmapReadOnly> {
MmapReadOnly::open(&try!(fs::File::open(path)))
}
pub fn len(&self,) -> usize {
self.len
}
pub fn range(&self, offset: usize, len: usize) -> MmapReadOnly {
assert!(offset + len <= self.len);
MmapReadOnly {
map: self.map.clone(),
offset: self.offset + offset,
len: len,
}
}
pub unsafe fn as_slice(&self) -> &[u8] {
&self.map.as_slice()[self.offset..self.offset + self.len]
}
}
impl Clone for MmapReadOnly {
fn clone(&self) -> MmapReadOnly {
MmapReadOnly{
map: self.map.clone(),
offset: self.offset,
len: self.len,
}
}
}
impl From<Mmap> for MmapReadOnly {
fn from(mmap: Mmap) -> MmapReadOnly {
From::from(Arc::new(mmap))
}
}
impl From<Arc<Mmap>> for MmapReadOnly {
fn from(mmap_arc: Arc<Mmap>) -> MmapReadOnly {
let len = mmap_arc.len();
MmapReadOnly {
map: mmap_arc,
offset: 0,
len: len,
}
}
}