diff --git a/src/iter.rs b/src/iter.rs index 0e0922e..2e34765 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -1,6 +1,5 @@ use std::io::Read; -use crate::fat::Fatty; use crate::subslice::SubSlice; use crate::utils::replace; use crate::{FatFs, SliceLike}; @@ -12,7 +11,7 @@ pub struct ClusterChainReader<'a, S: SliceLike> { } impl<'a, S: SliceLike> ClusterChainReader<'a, S> { - pub fn new(fat_fs: &'a mut FatFs, first_cluster: u32) -> ClusterChainReader<'a, S> { + pub fn new(fat_fs: &'a FatFs, first_cluster: u32) -> ClusterChainReader<'a, S> { let next_cluster = fat_fs.next_cluster(first_cluster).unwrap_or(None); let sub_slice = fat_fs.cluster_as_subslice(first_cluster); diff --git a/src/lib.rs b/src/lib.rs index e948f4b..a0f086c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,6 @@ -use std::io::{Read as _, Seek as _, SeekFrom, Write as _}; +use std::cell::RefCell; +use std::io::{Read, Seek, SeekFrom, Write}; +use std::rc::Rc; use crate::dir::{DirIter, RegularDirEntry}; use crate::fat::{FatError, Fatty}; @@ -94,7 +96,7 @@ impl SliceLike for std::fs::File { #[allow(dead_code)] pub struct FatFs { - data: S, + inner: Rc>, fat_offset: u64, fat_size: usize, @@ -150,8 +152,10 @@ impl FatFs { let bytes_per_cluster = bpb.bytes_per_cluster(); + let data = Rc::new(RefCell::new(data)); + Ok(FatFs { - data, + inner: data, fat_offset, fat_size, root_dir_offset, @@ -194,7 +198,7 @@ impl FatFs { SubSliceMut::new(self, offset, self.bytes_per_cluster) } - pub fn cluster_as_subslice(&mut self, cluster: u32) -> SubSlice<'_, S> { + pub fn cluster_as_subslice(&self, cluster: u32) -> SubSlice<'_, S> { let offset = self.data_cluster_to_offset(cluster); SubSlice::new(self, offset, self.bytes_per_cluster) @@ -215,20 +219,20 @@ impl FatFs { let mut data = vec![0; self.bytes_per_cluster]; - self.data - .read_at_offset(self.data_cluster_to_offset(cluster), &mut data)?; + let mut inner = self.inner.borrow_mut(); + + inner.read_at_offset(self.data_cluster_to_offset(cluster), &mut data)?; while let Ok(Some(next_cluster)) = self.next_cluster(cluster) { cluster = next_cluster; - self.data - .read_at_offset(self.data_cluster_to_offset(cluster), &mut data)?; + inner.read_at_offset(self.data_cluster_to_offset(cluster), &mut data)?; } Ok(data) } - pub fn root_dir_iter(&mut self) -> Box + '_> { + pub fn root_dir_iter(&self) -> Box + '_> { // TODO: maybe wrap this in another RootDirIter enum, so we don't have to Box if let Some(root_dir_offset) = self.root_dir_offset { @@ -248,4 +252,8 @@ impl FatFs { Box::new(DirIter::new(cluster_iter)) } + + pub fn chain_reader(&self, first_cluster: u32) -> impl Read { + iter::ClusterChainReader::new(self, first_cluster) + } } diff --git a/src/subslice.rs b/src/subslice.rs index 4dbb43c..821081c 100644 --- a/src/subslice.rs +++ b/src/subslice.rs @@ -44,7 +44,8 @@ impl Read for SubSliceMut<'_, S> { let bytes_to_read = self.len.min(buf.len()); self.fat_fs - .data + .inner + .borrow_mut() .read_at_offset(self.offset, &mut buf[..bytes_to_read])?; self.offset += bytes_to_read as u64; @@ -59,7 +60,8 @@ impl Write for SubSliceMut<'_, S> { let bytes_to_write = self.len.min(buf.len()); self.fat_fs - .data + .inner + .borrow_mut() .write_at_offset(self.offset, &buf[..bytes_to_write])?; self.offset += bytes_to_write as u64; @@ -74,7 +76,7 @@ impl Write for SubSliceMut<'_, S> { } pub struct SubSlice<'a, S: SliceLike> { - fat_fs: &'a mut FatFs, + fat_fs: &'a FatFs, offset: u64, len: usize, @@ -90,7 +92,7 @@ impl Debug for SubSlice<'_, S> { } impl SubSlice<'_, S> { - pub fn new(fat_fs: &mut FatFs, offset: u64, len: usize) -> SubSlice<'_, S> { + pub fn new(fat_fs: &FatFs, offset: u64, len: usize) -> SubSlice<'_, S> { SubSlice { fat_fs, offset, @@ -115,7 +117,7 @@ impl SubSlice<'_, S> { } impl<'a, S: SliceLike> SubSlice<'a, S> { - pub fn release(self) -> &'a mut FatFs { + pub fn release(self) -> &'a FatFs { self.fat_fs } } @@ -125,7 +127,8 @@ impl Read for SubSlice<'_, S> { let bytes_to_read = self.len.min(buf.len()); self.fat_fs - .data + .inner + .borrow_mut() .read_at_offset(self.offset, &mut buf[..bytes_to_read])?; self.offset += bytes_to_read as u64;