Dont assume cluster iterator always succeeds.

This commit is contained in:
Rafał Harabień 2017-10-07 02:19:19 +02:00
parent 057eef07bb
commit 3e08c80fb0
3 changed files with 38 additions and 10 deletions

View File

@ -50,7 +50,11 @@ impl <'a, 'b> Read for FatFile<'a, 'b> {
self.offset += read_bytes as u32;
buf_offset += read_bytes;
if self.offset % cluster_size == 0 {
self.current_cluster = self.fs.cluster_iter(current_cluster).skip(1).next();
match self.fs.cluster_iter(current_cluster).skip(1).next() {
Some(Err(err)) => return Err(err),
Some(Ok(n)) => self.current_cluster = Some(n),
None => self.current_cluster = None,
}
}
}
Ok(buf_offset)
@ -71,7 +75,11 @@ impl <'a, 'b> Seek for FatFile<'a, 'b> {
let cluster_count = (new_offset / cluster_size as i64) as usize;
let mut new_cluster = Some(self.first_cluster);
if cluster_count > 0 {
new_cluster = self.fs.cluster_iter(new_cluster.unwrap()).skip(cluster_count).next();
match self.fs.cluster_iter(new_cluster.unwrap()).skip(cluster_count).next() {
Some(Err(err)) => return Err(err),
Some(Ok(n)) => new_cluster = Some(n),
None => new_cluster = None,
}
}
self.offset = new_offset as u32;
self.current_cluster = new_cluster;

View File

@ -214,7 +214,7 @@ impl <'a> FatFileSystem<'a> {
self.offset_from_sector(self.sector_from_cluster(cluser))
}
pub(crate) fn cluster_iter<'b>(&'b self, cluster: u32) -> iter::Chain<iter::Once<u32>, FatClusterIterator<'b, 'a>> {
pub(crate) fn cluster_iter<'b>(&'b self, cluster: u32) -> iter::Chain<iter::Once<io::Result<u32>>, FatClusterIterator<'b, 'a>> {
let bytes_per_sector = self.boot.bpb.bytes_per_sector as u64;
let fat_offset = self.boot.bpb.reserved_sectors as u64 * bytes_per_sector;
let sectors_per_fat =

View File

@ -51,27 +51,47 @@ fn get_next_cluster_32(rdr: &mut ReadSeek, cluster: u32) -> io::Result<Option<u3
}
pub(crate) struct FatClusterIterator<'a, 'b: 'a> {
part: FatSlice<'a, 'b>,
rdr: FatSlice<'a, 'b>,
fat_type: FatType,
cluster: Option<u32>,
err: bool,
}
impl <'a, 'b> FatClusterIterator<'a, 'b> {
pub(crate) fn new(part: FatSlice<'a, 'b>, fat_type: FatType, cluster: u32) -> iter::Chain<iter::Once<u32>, FatClusterIterator<'a, 'b>> {
pub(crate) fn new(rdr: FatSlice<'a, 'b>, fat_type: FatType, cluster: u32)
-> iter::Chain<iter::Once<io::Result<u32>>, FatClusterIterator<'a, 'b>> {
let iter = FatClusterIterator {
part: part,
rdr: rdr,
fat_type: fat_type,
cluster: Some(cluster),
err: false,
};
iter::once(cluster).chain(iter)
iter::once(Ok(cluster)).chain(iter)
}
}
impl <'a, 'b> Iterator for FatClusterIterator<'a, 'b> {
type Item = u32;
type Item = io::Result<u32>;
fn next(&mut self) -> Option<Self::Item> {
self.cluster = get_next_cluster(&mut self.part, self.fat_type, self.cluster.unwrap()).unwrap(); // FIXME: unwrap!
self.cluster
if self.err {
return None;
}
match self.cluster {
Some(current_cluster) => {
self.cluster = match get_next_cluster(&mut self.rdr, self.fat_type, current_cluster) {
Ok(next_cluster) => next_cluster,
Err(err) => {
self.err = true;
return Some(Err(err));
},
}
},
None => {},
};
match self.cluster {
Some(n) => Some(Ok(n)),
None => None,
}
}
}