fat-rs/fat-bits/src/iter.rs

73 lines
1.8 KiB
Rust
Raw Normal View History

2025-07-26 15:51:21 +02:00
use std::io::Read;
use crate::FatFs;
2025-07-26 15:51:21 +02:00
use crate::subslice::SubSlice;
use crate::utils::replace;
pub struct ClusterChainReader<'a> {
sub_slice: SubSlice<'a>,
2025-07-26 15:51:21 +02:00
next_cluster: Option<u32>,
}
impl<'a> ClusterChainReader<'a> {
pub fn new(fat_fs: &'a FatFs, first_cluster: u32) -> ClusterChainReader<'a> {
2025-07-26 15:51:21 +02:00
let next_cluster = fat_fs.next_cluster(first_cluster).unwrap_or(None);
let sub_slice = fat_fs.cluster_as_subslice(first_cluster);
ClusterChainReader {
sub_slice,
next_cluster,
}
}
2025-08-01 01:08:48 +02:00
fn move_to_next_cluster(&mut self) -> bool {
2025-07-26 15:51:21 +02:00
let Some(next_cluster) = self.next_cluster else {
return false;
};
replace(&mut self.sub_slice, |sub_slice| {
let fat_fs = sub_slice.release();
self.next_cluster = fat_fs.next_cluster(next_cluster).unwrap_or(None);
fat_fs.cluster_as_subslice(next_cluster)
});
true
}
2025-08-01 01:08:48 +02:00
pub fn skip(&mut self, n: u64) -> u64 {
let mut bytes_to_skip = n;
while bytes_to_skip > self.sub_slice.len() as u64 {
bytes_to_skip -= self.sub_slice.len() as u64;
if !self.move_to_next_cluster() {
// ran out of bytes to seek
return n - bytes_to_skip;
}
}
if bytes_to_skip != 0 {
bytes_to_skip -= self.sub_slice.skip(bytes_to_skip as usize) as u64;
}
// n should absolutely be zero here
assert_eq!(bytes_to_skip, 0);
n
}
2025-07-26 15:51:21 +02:00
}
2025-08-01 01:08:48 +02:00
impl Read for ClusterChainReader<'_> {
2025-07-26 15:51:21 +02:00
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
if self.sub_slice.is_empty() {
2025-08-01 01:08:48 +02:00
if !self.move_to_next_cluster() {
2025-07-26 15:51:21 +02:00
return Ok(0);
}
}
self.sub_slice.read(buf)
}
}