io_transform! {
pub use super::super::{Read, Write, Seek, ReadExt, Error, ErrorKind, SeekFrom, Parsable, Writable};
pub use super::super::IoResult;
#[cfg(feature = "std")]
pub fn error_from_kind(kind: ErrorKind) -> Error {
Error::new(kind, "")
}
#[cfg(not(feature = "std"))]
pub fn error_from_kind(kind: ErrorKind) -> Error {
Error::from_kind(kind)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct Sector<T = usize>(pub T);
pub trait SectorLike {
fn to_bytes(self, bytes_per_sector: usize) -> usize;
}
macro_rules! sector_impl {
($ty:ty) => {
impl SectorLike for Sector<$ty> {
fn to_bytes(self, bytes_per_sector: usize) -> usize {
(self.0 as usize) * bytes_per_sector
}
}
};
}
sector_impl!(u8);
sector_impl!(u16);
sector_impl!(u32);
sector_impl!(u64);
sector_impl!(usize);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Cluster<T = usize>(pub T);
impl Cluster<usize> {
pub fn from_parts(high: u16, low: u16) -> Self {
Self((high as usize) << 16 | (low as usize))
}
}
pub(crate) trait ClusterLike {
fn to_bytes(self, data_start: usize, bytes_per_cluster: usize) -> usize;
}
macro_rules! cluster_impl {
($ty:ty) => {
impl ClusterLike for Cluster<$ty> {
fn to_bytes(self, data_start: usize, bytes_per_cluster: usize) -> usize {
data_start + (self.0 as usize - 2) * bytes_per_cluster
}
}
};
}
cluster_impl!(u8);
cluster_impl!(u16);
cluster_impl!(u32);
cluster_impl!(u64);
cluster_impl!(usize);
pub struct SectorCursor<DATA: Seek> {
pub(crate) data: DATA,
pub(crate) sector_size: usize,
pub(crate) cluster_size: usize,
}
impl<DATA: Seek> SectorCursor<DATA> {
pub const fn new(data: DATA, sector_size: usize, cluster_size: usize) -> Self {
Self {
data,
sector_size,
cluster_size,
}
}
pub async fn seek_sector(&mut self, sector: impl SectorLike) -> hadris_io::Result<u64> {
self.seek(SeekFrom::Start(sector.to_bytes(self.sector_size) as u64)).await
}
}
impl<T> Seek for SectorCursor<T>
where
T: Seek,
{
async fn seek(&mut self, pos: hadris_io::SeekFrom) -> hadris_io::Result<u64> {
self.data.seek(pos).await
}
async fn stream_position(&mut self) -> hadris_io::Result<u64> {
self.data.stream_position().await
}
async fn seek_relative(&mut self, offset: i64) -> hadris_io::Result<()> {
self.data.seek_relative(offset).await
}
}
impl<T> Read for SectorCursor<T>
where
T: Read + Seek,
{
async fn read(&mut self, buf: &mut [u8]) -> hadris_io::Result<usize> {
self.data.read(buf).await
}
async fn read_exact(&mut self, buf: &mut [u8]) -> hadris_io::Result<()> {
self.data.read_exact(buf).await
}
}
#[cfg(feature = "write")]
impl<T> Write for SectorCursor<T>
where
T: Write + Seek,
{
async fn write(&mut self, buf: &[u8]) -> hadris_io::Result<usize> {
self.data.write(buf).await
}
async fn flush(&mut self) -> hadris_io::Result<()> {
self.data.flush().await
}
async fn write_all(&mut self, buf: &[u8]) -> hadris_io::Result<()> {
self.data.write_all(buf).await
}
}
}