pub mod decrypting;
pub mod file;
pub mod prefetched;
use crate::error::Result;
pub trait SectorSource: Send {
fn capacity_sectors(&self) -> u32 {
0
}
fn read_sectors(
&mut self,
lba: u32,
count: u16,
buf: &mut [u8],
recovery: bool,
) -> Result<usize>;
fn set_speed(&mut self, _kbs: u16) {}
}
impl SectorSource for Box<dyn SectorSource> {
fn capacity_sectors(&self) -> u32 {
(**self).capacity_sectors()
}
fn read_sectors(
&mut self,
lba: u32,
count: u16,
buf: &mut [u8],
recovery: bool,
) -> Result<usize> {
(**self).read_sectors(lba, count, buf, recovery)
}
fn set_speed(&mut self, kbs: u16) {
(**self).set_speed(kbs)
}
}
impl SectorSource for &mut (dyn SectorSource + '_) {
fn capacity_sectors(&self) -> u32 {
(**self).capacity_sectors()
}
fn read_sectors(
&mut self,
lba: u32,
count: u16,
buf: &mut [u8],
recovery: bool,
) -> Result<usize> {
(**self).read_sectors(lba, count, buf, recovery)
}
fn set_speed(&mut self, kbs: u16) {
(**self).set_speed(kbs)
}
}
pub trait SectorSink: Send {
fn write_sectors(&mut self, lba: u32, buf: &[u8]) -> Result<()>;
fn finish(self: Box<Self>) -> Result<()>;
}
pub use crate::io::file_sector_source::FileSectorSource;
pub use decrypting::DecryptingSectorSource;
pub use file::FileSectorSink;
pub use prefetched::PrefetchedSectorSource;
#[cfg(test)]
mod tests {
use super::*;
use std::sync::{Arc, Mutex};
struct Spy {
capacity: u32,
reads: Arc<Mutex<Vec<(u32, u16, bool)>>>,
speeds: Arc<Mutex<Vec<u16>>>,
}
impl Spy {
fn new(
capacity: u32,
) -> (
Self,
Arc<Mutex<Vec<(u32, u16, bool)>>>,
Arc<Mutex<Vec<u16>>>,
) {
let reads = Arc::new(Mutex::new(Vec::new()));
let speeds = Arc::new(Mutex::new(Vec::new()));
(
Self {
capacity,
reads: reads.clone(),
speeds: speeds.clone(),
},
reads,
speeds,
)
}
}
impl SectorSource for Spy {
fn capacity_sectors(&self) -> u32 {
self.capacity
}
fn read_sectors(
&mut self,
lba: u32,
count: u16,
buf: &mut [u8],
recovery: bool,
) -> Result<usize> {
self.reads.lock().unwrap().push((lba, count, recovery));
let bytes = count as usize * 2048;
buf[..bytes].fill(0xa5);
Ok(bytes)
}
fn set_speed(&mut self, kbs: u16) {
self.speeds.lock().unwrap().push(kbs);
}
}
#[test]
fn default_capacity_is_zero() {
struct Minimal;
impl SectorSource for Minimal {
fn read_sectors(
&mut self,
_lba: u32,
_count: u16,
_buf: &mut [u8],
_recovery: bool,
) -> Result<usize> {
Ok(0)
}
}
assert_eq!(Minimal.capacity_sectors(), 0);
}
#[test]
fn default_set_speed_is_noop() {
struct Minimal;
impl SectorSource for Minimal {
fn read_sectors(
&mut self,
_lba: u32,
_count: u16,
_buf: &mut [u8],
_recovery: bool,
) -> Result<usize> {
Ok(0)
}
}
let mut m = Minimal;
m.set_speed(12345); }
#[test]
fn boxed_dyn_forwards_all_methods() {
let (spy, reads, speeds) = Spy::new(777);
let mut boxed: Box<dyn SectorSource> = Box::new(spy);
assert_eq!(boxed.capacity_sectors(), 777, "capacity must forward");
let mut buf = vec![0u8; 3 * 2048];
let n = boxed.read_sectors(99, 3, &mut buf, true).unwrap();
assert_eq!(n, 3 * 2048, "read return must forward");
assert!(buf.iter().all(|b| *b == 0xa5), "inner must have filled buf");
boxed.set_speed(5400);
assert_eq!(
*reads.lock().unwrap(),
vec![(99, 3, true)],
"read args (lba/count/recovery) must forward unchanged"
);
assert_eq!(
*speeds.lock().unwrap(),
vec![5400],
"set_speed must forward"
);
}
#[test]
fn mut_ref_dyn_forwards_all_methods() {
let (mut spy, reads, speeds) = Spy::new(123);
let r: &mut dyn SectorSource = &mut spy;
assert_eq!(r.capacity_sectors(), 123);
let mut buf = vec![0u8; 2 * 2048];
let n = r.read_sectors(7, 2, &mut buf, false).unwrap();
assert_eq!(n, 2 * 2048);
r.set_speed(8800);
assert_eq!(*reads.lock().unwrap(), vec![(7, 2, false)]);
assert_eq!(*speeds.lock().unwrap(), vec![8800]);
}
}