use super::*;
use std::fs::File;
use std::io::Read;
use std::path::Path;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Storage {
inner: Box<[u8]>,
capacity: usize,
}
impl Storage {
pub fn new() -> Self {
Storage::with_capacity(1 << 30)
}
pub fn with_capacity(capacity: usize) -> Self {
Storage {
inner: vec![0; capacity].into_boxed_slice(),
capacity,
}
}
pub fn from<P: AsRef<Path>>(path: P) -> Result<Self, StorageError> {
let mut file = match File::open(path.as_ref()) {
Ok(ok) => ok,
Err(err) => {
return Err(StorageError::new(format!(
"failed to open file `{}`: {}",
path.as_ref().display(),
err
)))
}
};
let mut buf: Vec<u8> = Vec::new();
match file.read_to_end(&mut buf) {
Ok(ok) => {
if ok == 0 {
return Err(StorageError::new(format!(
"file `{}` is empty",
path.as_ref().display()
)));
} else {
Ok(Storage {
inner: buf.into_boxed_slice(),
capacity: ok,
})
}
}
Err(err) => {
return Err(StorageError::new(format!(
"failed to read file `{}`: {}",
path.as_ref().display(),
err
)))
}
}
}
}
impl IO for Storage {
fn read(&self, addr: usize, byte: &mut u8) {
if addr < self.capacity {
*byte = self.inner[addr];
}
}
fn write(&mut self, addr: usize, byte: u8) {
if addr < self.capacity {
self.inner[addr] = byte;
}
}
fn capacity(&self) -> usize {
self.capacity
}
}
pub trait StorageSupport {
fn connect(&mut self, storage: &mut Storage, port: usize);
fn disconnect(&mut self, port: usize);
fn is_connected(&self, port: usize) -> bool;
}
pub type StorageError = mtk::Error;