1io_transform! {
2
3pub use super::super::{Read, Write, Seek, ReadExt, Error, ErrorKind, SeekFrom, Parsable, Writable};
6pub use super::super::IoResult;
7
8#[cfg(feature = "std")]
12pub fn error_from_kind(kind: ErrorKind) -> Error {
13 Error::new(kind, "")
14}
15
16#[cfg(not(feature = "std"))]
18pub fn error_from_kind(kind: ErrorKind) -> Error {
19 Error::from_kind(kind)
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
24pub(crate) struct Sector<T = usize>(pub T);
25
26pub trait SectorLike {
28 fn to_bytes(self, bytes_per_sector: usize) -> usize;
30}
31
32macro_rules! sector_impl {
33 ($ty:ty) => {
34 impl SectorLike for Sector<$ty> {
35 fn to_bytes(self, bytes_per_sector: usize) -> usize {
36 (self.0 as usize) * bytes_per_sector
37 }
38 }
39 };
40}
41sector_impl!(u8);
42sector_impl!(u16);
43sector_impl!(u32);
44sector_impl!(u64);
45sector_impl!(usize);
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
50pub struct Cluster<T = usize>(pub T);
51
52impl Cluster<usize> {
53 pub fn from_parts(high: u16, low: u16) -> Self {
55 Self((high as usize) << 16 | (low as usize))
56 }
57}
58
59pub(crate) trait ClusterLike {
60 fn to_bytes(self, data_start: usize, bytes_per_cluster: usize) -> usize;
61}
62
63macro_rules! cluster_impl {
64 ($ty:ty) => {
65 impl ClusterLike for Cluster<$ty> {
66 fn to_bytes(self, data_start: usize, bytes_per_cluster: usize) -> usize {
67 data_start + (self.0 as usize - 2) * bytes_per_cluster
68 }
69 }
70 };
71}
72cluster_impl!(u8);
73cluster_impl!(u16);
74cluster_impl!(u32);
75cluster_impl!(u64);
76cluster_impl!(usize);
77
78pub struct SectorCursor<DATA: Seek> {
80 pub(crate) data: DATA,
81 pub(crate) sector_size: usize,
82 pub(crate) cluster_size: usize,
83}
84
85impl<DATA: Seek> SectorCursor<DATA> {
86 pub const fn new(data: DATA, sector_size: usize, cluster_size: usize) -> Self {
88 Self {
89 data,
90 sector_size,
91 cluster_size,
92 }
93 }
94
95 pub async fn seek_sector(&mut self, sector: impl SectorLike) -> hadris_io::Result<u64> {
97 self.seek(SeekFrom::Start(sector.to_bytes(self.sector_size) as u64))
98 .await
99 .map_err(hadris_io::Error::erase)
100 }
101}
102
103impl<T> Seek for SectorCursor<T>
104where
105 T: Seek,
106{
107 type Error = <T as Seek>::Error;
108
109 async fn seek(&mut self, pos: hadris_io::SeekFrom) -> hadris_io::Result<u64, Self::Error> {
110 self.data.seek(pos).await
111 }
112
113 async fn stream_position(&mut self) -> hadris_io::Result<u64, Self::Error> {
114 self.data.stream_position().await
115 }
116
117 async fn seek_relative(&mut self, offset: i64) -> hadris_io::Result<(), Self::Error> {
118 self.data.seek_relative(offset).await
119 }
120}
121
122impl<T> Read for SectorCursor<T>
123where
124 T: Read + Seek,
125{
126 type Error = <T as Read>::Error;
127
128 async fn read(&mut self, buf: &mut [u8]) -> hadris_io::Result<usize, Self::Error> {
129 self.data.read(buf).await
130 }
131
132 async fn read_exact(&mut self, buf: &mut [u8]) -> hadris_io::Result<()> {
133 self.data.read_exact(buf).await
134 }
135}
136
137#[cfg(feature = "write")]
138impl<T> Write for SectorCursor<T>
139where
140 T: Write + Seek,
141{
142 type Error = <T as Write>::Error;
143
144 async fn write(&mut self, buf: &[u8]) -> hadris_io::Result<usize, Self::Error> {
145 self.data.write(buf).await
146 }
147
148 async fn flush(&mut self) -> hadris_io::Result<(), Self::Error> {
149 self.data.flush().await
150 }
151
152 async fn write_all(&mut self, buf: &[u8]) -> hadris_io::Result<()> {
153 self.data.write_all(buf).await
154 }
155}
156
157}