#![no_std]
extern crate alloc;
use alloc::vec;
pub trait BlockDevice {
fn block_size(&self) -> usize;
fn block_count(&self) -> usize;
fn read_block(&self, block_index: usize, buf: &mut [u8]);
fn write_block(&mut self, block_index: usize, buf: &[u8]);
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<(), ()> {
let block_size = self.block_size();
if offset % buf.len() == 0 && buf.len() == block_size {
self.read_block(offset / block_size, buf);
}
let start_block = offset / block_size;
let end_block = (offset + buf.len()) / block_size;
let relative_offset = offset % block_size;
let block_count = if relative_offset == 0 && start_block != end_block {
end_block - start_block
} else {
end_block - start_block + 1
};
let mut data = vec![0_u8; block_count * block_size];
for i in 0..block_count {
let start_index = i * block_size;
let end_index = start_index + block_size;
let read_block_index = start_block + i;
self.read_block(read_block_index, &mut data[start_index..end_index]);
}
buf.copy_from_slice(&data[relative_offset..relative_offset + buf.len()]);
Ok(())
}
}