2017-09-23 06:22:31 +08:00
|
|
|
use std::cmp;
|
2017-09-23 04:27:39 +08:00
|
|
|
use std::io::prelude::*;
|
2017-09-23 06:22:31 +08:00
|
|
|
use std::io::SeekFrom;
|
2017-09-23 04:27:39 +08:00
|
|
|
use std::io;
|
2017-09-23 05:20:06 +08:00
|
|
|
|
2017-09-24 01:42:09 +08:00
|
|
|
use fs::FatSharedStateRef;
|
2017-09-23 04:27:39 +08:00
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
pub struct FatFile {
|
2017-09-24 02:16:32 +08:00
|
|
|
first_cluster: u32,
|
2017-09-23 04:27:39 +08:00
|
|
|
size: u32,
|
|
|
|
offset: u32,
|
2017-09-24 02:16:32 +08:00
|
|
|
current_cluster: Option<u32>,
|
2017-09-24 01:42:09 +08:00
|
|
|
state: FatSharedStateRef,
|
2017-09-23 04:27:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl FatFile {
|
2017-09-24 01:42:09 +08:00
|
|
|
pub(crate) fn new(first_cluster: u32, size: u32, state: FatSharedStateRef) -> FatFile {
|
2017-09-23 04:27:39 +08:00
|
|
|
FatFile {
|
2017-09-24 02:16:32 +08:00
|
|
|
first_cluster, size, state,
|
|
|
|
current_cluster: Some(first_cluster),
|
|
|
|
offset: 0,
|
2017-09-23 04:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
2017-09-24 01:42:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Read for FatFile {
|
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
2017-09-24 02:16:32 +08:00
|
|
|
let mut buf_offset: usize = 0;
|
|
|
|
let cluster_size = self.state.borrow().get_cluster_size();
|
2017-09-24 01:42:09 +08:00
|
|
|
let mut state = self.state.borrow_mut();
|
2017-09-24 02:16:32 +08:00
|
|
|
loop {
|
|
|
|
let offset_in_cluster = self.offset % cluster_size;
|
|
|
|
let bytes_left_in_cluster = (cluster_size - offset_in_cluster) as usize;
|
|
|
|
let bytes_left_in_file = (self.size - self.offset) as usize;
|
|
|
|
let bytes_left_in_buf = buf.len() - buf_offset;
|
|
|
|
let read_size = cmp::min(cmp::min(bytes_left_in_file, bytes_left_in_cluster), bytes_left_in_buf);
|
|
|
|
if read_size == 0 {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
let current_cluster = self.current_cluster.unwrap();
|
|
|
|
let offset_in_fs = state.offset_from_cluster(current_cluster) + (offset_in_cluster as u64);
|
|
|
|
state.rdr.seek(SeekFrom::Start(offset_in_fs))?;
|
|
|
|
let read_bytes = state.rdr.read(&mut buf[buf_offset..buf_offset+read_size])?;
|
|
|
|
if read_bytes == 0 {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
self.offset += read_bytes as u32;
|
|
|
|
buf_offset += read_bytes;
|
|
|
|
if self.offset % cluster_size == 0 {
|
|
|
|
self.current_cluster = state.table.get_next_cluster(current_cluster);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(buf_offset)
|
2017-09-23 04:27:39 +08:00
|
|
|
}
|
|
|
|
}
|