Compare commits
No commits in common. "3c20c2c97c331ee8ec247a7a8c9bd0058f3614fc" and "b96805c1c40e486626887199e0c24f481c207981" have entirely different histories.
3c20c2c97c
...
b96805c1c4
5 changed files with 19 additions and 94 deletions
26
src/dir.rs
26
src/dir.rs
|
|
@ -76,7 +76,7 @@ impl Display for RegularDirEntry {
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{} {: <16} created: {} modified: {}",
|
"DirEntry {{ {} {: <16} created: {} modified: {} }}",
|
||||||
self.attr,
|
self.attr,
|
||||||
name,
|
name,
|
||||||
self.create_time().format("%a %b %d %H:%M:%S%.3f %Y"),
|
self.create_time().format("%a %b %d %H:%M:%S%.3f %Y"),
|
||||||
|
|
@ -167,30 +167,6 @@ impl RegularDirEntry {
|
||||||
self.attr.contains(Attr::Directory) && !self.attr.intersects(Attr::System | Attr::VolumeId)
|
self.attr.contains(Attr::Directory) && !self.attr.intersects(Attr::System | Attr::VolumeId)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_dot(&self) -> bool {
|
|
||||||
if !self.is_dir() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// &self.name[..2] == &[b'.', b' ']
|
|
||||||
|
|
||||||
self.name[0] == b'.' && &self.name[1..] == &[b' '; 10]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_dotdot(&self) -> bool {
|
|
||||||
if !self.is_dir() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// &self.name[..3] == &[b'.', b'.', b' ']
|
|
||||||
|
|
||||||
&self.name[..2] == &[b'.', b'.'] && &self.name[2..] == &[b' '; 9]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_hidden(&self) -> bool {
|
|
||||||
self.is_dot() || self.is_dotdot() || self.attr.contains(Attr::Hidden)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn name(&self) -> &[u8] {
|
pub fn name(&self) -> &[u8] {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
|
||||||
43
src/dump.rs
43
src/dump.rs
|
|
@ -1,8 +1,7 @@
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
use fat_rs::dir::{DirIter, RegularDirEntry};
|
use fat_rs::FatFs;
|
||||||
use fat_rs::fat::Fatty as _;
|
use fat_rs::fat::Fatty as _;
|
||||||
use fat_rs::{FatFs, SliceLike};
|
|
||||||
|
|
||||||
pub fn main() -> anyhow::Result<()> {
|
pub fn main() -> anyhow::Result<()> {
|
||||||
let args = std::env::args();
|
let args = std::env::args();
|
||||||
|
|
@ -39,45 +38,5 @@ pub fn main() -> anyhow::Result<()> {
|
||||||
println!("{}", dir_entry);
|
println!("{}", dir_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!();
|
|
||||||
println!();
|
|
||||||
|
|
||||||
tree(&fat_fs);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tree<S: SliceLike>(fat_fs: &FatFs<S>) {
|
|
||||||
fn do_indent(indent: u32) {
|
|
||||||
for _ in 0..indent {
|
|
||||||
print!(" ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn tree_impl<S: SliceLike>(
|
|
||||||
fat_fs: &FatFs<S>,
|
|
||||||
iter: impl Iterator<Item = RegularDirEntry>,
|
|
||||||
indent: u32,
|
|
||||||
) {
|
|
||||||
for dir_entry in iter.filter(|x| !x.is_hidden()) {
|
|
||||||
do_indent(indent);
|
|
||||||
|
|
||||||
println!("{}", dir_entry);
|
|
||||||
|
|
||||||
if dir_entry.is_dot() || dir_entry.is_dotdot() {
|
|
||||||
// do not descent into . and ..
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if dir_entry.is_dir() {
|
|
||||||
let reader = fat_fs.chain_reader(dir_entry.first_cluster());
|
|
||||||
|
|
||||||
let iter = DirIter::new(reader);
|
|
||||||
|
|
||||||
tree_impl(fat_fs, iter, indent + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tree_impl(fat_fs, fat_fs.root_dir_iter(), 0);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
|
use crate::fat::Fatty;
|
||||||
use crate::subslice::SubSlice;
|
use crate::subslice::SubSlice;
|
||||||
use crate::utils::replace;
|
use crate::utils::replace;
|
||||||
use crate::{FatFs, SliceLike};
|
use crate::{FatFs, SliceLike};
|
||||||
|
|
@ -11,7 +12,7 @@ pub struct ClusterChainReader<'a, S: SliceLike> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S: SliceLike> ClusterChainReader<'a, S> {
|
impl<'a, S: SliceLike> ClusterChainReader<'a, S> {
|
||||||
pub fn new(fat_fs: &'a FatFs<S>, first_cluster: u32) -> ClusterChainReader<'a, S> {
|
pub fn new(fat_fs: &'a mut FatFs<S>, first_cluster: u32) -> ClusterChainReader<'a, S> {
|
||||||
let next_cluster = fat_fs.next_cluster(first_cluster).unwrap_or(None);
|
let next_cluster = fat_fs.next_cluster(first_cluster).unwrap_or(None);
|
||||||
|
|
||||||
let sub_slice = fat_fs.cluster_as_subslice(first_cluster);
|
let sub_slice = fat_fs.cluster_as_subslice(first_cluster);
|
||||||
|
|
|
||||||
26
src/lib.rs
26
src/lib.rs
|
|
@ -1,6 +1,4 @@
|
||||||
use std::cell::RefCell;
|
use std::io::{Read as _, Seek as _, SeekFrom, Write as _};
|
||||||
use std::io::{Read, Seek, SeekFrom, Write};
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use crate::dir::{DirIter, RegularDirEntry};
|
use crate::dir::{DirIter, RegularDirEntry};
|
||||||
use crate::fat::{FatError, Fatty};
|
use crate::fat::{FatError, Fatty};
|
||||||
|
|
@ -96,7 +94,7 @@ impl SliceLike for std::fs::File {
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct FatFs<S: SliceLike> {
|
pub struct FatFs<S: SliceLike> {
|
||||||
inner: Rc<RefCell<S>>,
|
data: S,
|
||||||
|
|
||||||
fat_offset: u64,
|
fat_offset: u64,
|
||||||
fat_size: usize,
|
fat_size: usize,
|
||||||
|
|
@ -152,10 +150,8 @@ impl<S: SliceLike> FatFs<S> {
|
||||||
|
|
||||||
let bytes_per_cluster = bpb.bytes_per_cluster();
|
let bytes_per_cluster = bpb.bytes_per_cluster();
|
||||||
|
|
||||||
let data = Rc::new(RefCell::new(data));
|
|
||||||
|
|
||||||
Ok(FatFs {
|
Ok(FatFs {
|
||||||
inner: data,
|
data,
|
||||||
fat_offset,
|
fat_offset,
|
||||||
fat_size,
|
fat_size,
|
||||||
root_dir_offset,
|
root_dir_offset,
|
||||||
|
|
@ -198,7 +194,7 @@ impl<S: SliceLike> FatFs<S> {
|
||||||
SubSliceMut::new(self, offset, self.bytes_per_cluster)
|
SubSliceMut::new(self, offset, self.bytes_per_cluster)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cluster_as_subslice(&self, cluster: u32) -> SubSlice<'_, S> {
|
pub fn cluster_as_subslice(&mut self, cluster: u32) -> SubSlice<'_, S> {
|
||||||
let offset = self.data_cluster_to_offset(cluster);
|
let offset = self.data_cluster_to_offset(cluster);
|
||||||
|
|
||||||
SubSlice::new(self, offset, self.bytes_per_cluster)
|
SubSlice::new(self, offset, self.bytes_per_cluster)
|
||||||
|
|
@ -219,20 +215,20 @@ impl<S: SliceLike> FatFs<S> {
|
||||||
|
|
||||||
let mut data = vec![0; self.bytes_per_cluster];
|
let mut data = vec![0; self.bytes_per_cluster];
|
||||||
|
|
||||||
let mut inner = self.inner.borrow_mut();
|
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)?;
|
|
||||||
|
|
||||||
while let Ok(Some(next_cluster)) = self.next_cluster(cluster) {
|
while let Ok(Some(next_cluster)) = self.next_cluster(cluster) {
|
||||||
cluster = next_cluster;
|
cluster = next_cluster;
|
||||||
|
|
||||||
inner.read_at_offset(self.data_cluster_to_offset(cluster), &mut data)?;
|
self.data
|
||||||
|
.read_at_offset(self.data_cluster_to_offset(cluster), &mut data)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root_dir_iter(&self) -> Box<dyn Iterator<Item = RegularDirEntry> + '_> {
|
pub fn root_dir_iter(&mut self) -> Box<dyn Iterator<Item = RegularDirEntry> + '_> {
|
||||||
// TODO: maybe wrap this in another RootDirIter enum, so we don't have to Box<dyn>
|
// TODO: maybe wrap this in another RootDirIter enum, so we don't have to Box<dyn>
|
||||||
|
|
||||||
if let Some(root_dir_offset) = self.root_dir_offset {
|
if let Some(root_dir_offset) = self.root_dir_offset {
|
||||||
|
|
@ -252,8 +248,4 @@ impl<S: SliceLike> FatFs<S> {
|
||||||
|
|
||||||
Box::new(DirIter::new(cluster_iter))
|
Box::new(DirIter::new(cluster_iter))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chain_reader(&self, first_cluster: u32) -> impl Read {
|
|
||||||
iter::ClusterChainReader::new(self, first_cluster)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,7 @@ impl<S: SliceLike> Read for SubSliceMut<'_, S> {
|
||||||
let bytes_to_read = self.len.min(buf.len());
|
let bytes_to_read = self.len.min(buf.len());
|
||||||
|
|
||||||
self.fat_fs
|
self.fat_fs
|
||||||
.inner
|
.data
|
||||||
.borrow_mut()
|
|
||||||
.read_at_offset(self.offset, &mut buf[..bytes_to_read])?;
|
.read_at_offset(self.offset, &mut buf[..bytes_to_read])?;
|
||||||
|
|
||||||
self.offset += bytes_to_read as u64;
|
self.offset += bytes_to_read as u64;
|
||||||
|
|
@ -60,8 +59,7 @@ impl<S: SliceLike> Write for SubSliceMut<'_, S> {
|
||||||
let bytes_to_write = self.len.min(buf.len());
|
let bytes_to_write = self.len.min(buf.len());
|
||||||
|
|
||||||
self.fat_fs
|
self.fat_fs
|
||||||
.inner
|
.data
|
||||||
.borrow_mut()
|
|
||||||
.write_at_offset(self.offset, &buf[..bytes_to_write])?;
|
.write_at_offset(self.offset, &buf[..bytes_to_write])?;
|
||||||
|
|
||||||
self.offset += bytes_to_write as u64;
|
self.offset += bytes_to_write as u64;
|
||||||
|
|
@ -76,7 +74,7 @@ impl<S: SliceLike> Write for SubSliceMut<'_, S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SubSlice<'a, S: SliceLike> {
|
pub struct SubSlice<'a, S: SliceLike> {
|
||||||
fat_fs: &'a FatFs<S>,
|
fat_fs: &'a mut FatFs<S>,
|
||||||
|
|
||||||
offset: u64,
|
offset: u64,
|
||||||
len: usize,
|
len: usize,
|
||||||
|
|
@ -92,7 +90,7 @@ impl<S: SliceLike> Debug for SubSlice<'_, S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: SliceLike> SubSlice<'_, S> {
|
impl<S: SliceLike> SubSlice<'_, S> {
|
||||||
pub fn new(fat_fs: &FatFs<S>, offset: u64, len: usize) -> SubSlice<'_, S> {
|
pub fn new(fat_fs: &mut FatFs<S>, offset: u64, len: usize) -> SubSlice<'_, S> {
|
||||||
SubSlice {
|
SubSlice {
|
||||||
fat_fs,
|
fat_fs,
|
||||||
offset,
|
offset,
|
||||||
|
|
@ -117,7 +115,7 @@ impl<S: SliceLike> SubSlice<'_, S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S: SliceLike> SubSlice<'a, S> {
|
impl<'a, S: SliceLike> SubSlice<'a, S> {
|
||||||
pub fn release(self) -> &'a FatFs<S> {
|
pub fn release(self) -> &'a mut FatFs<S> {
|
||||||
self.fat_fs
|
self.fat_fs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -127,8 +125,7 @@ impl<S: SliceLike> Read for SubSlice<'_, S> {
|
||||||
let bytes_to_read = self.len.min(buf.len());
|
let bytes_to_read = self.len.min(buf.len());
|
||||||
|
|
||||||
self.fat_fs
|
self.fat_fs
|
||||||
.inner
|
.data
|
||||||
.borrow_mut()
|
|
||||||
.read_at_offset(self.offset, &mut buf[..bytes_to_read])?;
|
.read_at_offset(self.offset, &mut buf[..bytes_to_read])?;
|
||||||
|
|
||||||
self.offset += bytes_to_read as u64;
|
self.offset += bytes_to_read as u64;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue