Refactor code to use shared state.
This way for example FatFile can implement Read trait.
This commit is contained in:
parent
3933a29078
commit
88fd442dac
@ -8,10 +8,10 @@ use rustfat::FatFileSystem;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let file = File::open("resources/floppy.img").unwrap();
|
let file = File::open("resources/floppy.img").unwrap();
|
||||||
let mut buf_rdr = BufReader::new(file);
|
let buf_rdr = BufReader::new(file);
|
||||||
let mut fs = FatFileSystem::new(&mut buf_rdr).unwrap();
|
let mut fs = FatFileSystem::new(Box::new(buf_rdr)).unwrap();
|
||||||
let mut root_dir = fs.root_dir();
|
let mut root_dir = fs.root_dir();
|
||||||
let entries = fs.read_dir(&mut root_dir).unwrap();
|
let entries = root_dir.list().unwrap();
|
||||||
for e in entries {
|
for e in entries {
|
||||||
println!("{} - size {} - modified {}", e.get_name(), e.get_size(), e.get_modify_time());
|
println!("{} - size {} - modified {}", e.get_name(), e.get_size(), e.get_modify_time());
|
||||||
}
|
}
|
||||||
|
65
src/dir.rs
65
src/dir.rs
@ -5,7 +5,7 @@ use std::str;
|
|||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
use chrono::{DateTime, Date, TimeZone, Local};
|
use chrono::{DateTime, Date, TimeZone, Local};
|
||||||
|
|
||||||
use fs::FatFileSystem;
|
use fs::FatSharedStateRef;
|
||||||
use file::FatFile;
|
use file::FatFile;
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
@ -35,6 +35,7 @@ pub struct FatDirEntry {
|
|||||||
modify_date: u16,
|
modify_date: u16,
|
||||||
first_cluster_lo: u16,
|
first_cluster_lo: u16,
|
||||||
size: u32,
|
size: u32,
|
||||||
|
state: FatSharedStateRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_date(dos_date: u16) -> Date<Local> {
|
fn convert_date(dos_date: u16) -> Date<Local> {
|
||||||
@ -61,8 +62,8 @@ impl FatDirEntry {
|
|||||||
((self.first_cluster_hi as u32) << 16) | self.first_cluster_lo as u32
|
((self.first_cluster_hi as u32) << 16) | self.first_cluster_lo as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_file<T: Read+Seek>(&self, fs: &FatFileSystem<T>) -> FatFile {
|
pub fn get_file(&self) -> FatFile {
|
||||||
FatFile::new(fs.sector_from_cluster(self.get_cluster()), self.size)
|
FatFile::new(self.get_cluster(), self.size, self.state.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_size(&self) -> u32 {
|
pub fn get_size(&self) -> u32 {
|
||||||
@ -82,19 +83,30 @@ impl FatDirEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Read+Seek> FatFileSystem<T> {
|
pub struct FatDir {
|
||||||
pub fn read_dir(&mut self, dir: &mut FatFile) -> io::Result<Vec<FatDirEntry>> {
|
rdr: Box<Read>,
|
||||||
|
state: FatSharedStateRef,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FatDir {
|
||||||
|
|
||||||
|
pub(crate) fn new(rdr: Box<Read>, state: FatSharedStateRef) -> FatDir {
|
||||||
|
FatDir { rdr, state }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list(&mut self) -> io::Result<Vec<FatDirEntry>> {
|
||||||
let mut entries = Vec::new();
|
let mut entries = Vec::new();
|
||||||
let mut buf = vec![0; self.get_cluster_size() as usize];
|
let cluster_size = self.state.borrow().get_cluster_size() as usize;
|
||||||
|
let mut buf = vec![0; cluster_size];
|
||||||
loop {
|
loop {
|
||||||
let size = self.read(dir, &mut buf)?;
|
let size = self.rdr.read(&mut buf)?;
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cur = Cursor::new(&buf[..size]);
|
let mut cur = Cursor::new(&buf[..size]);
|
||||||
loop {
|
loop {
|
||||||
let entry = read_dir_entry(&mut cur)?;
|
let entry = self.read_dir_entry(&mut cur)?;
|
||||||
if entry.name[0] == 0 {
|
if entry.name[0] == 0 {
|
||||||
break; // end of dir
|
break; // end of dir
|
||||||
}
|
}
|
||||||
@ -107,23 +119,24 @@ impl<T: Read+Seek> FatFileSystem<T> {
|
|||||||
|
|
||||||
Ok(entries)
|
Ok(entries)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn read_dir_entry(rdr: &mut Read) -> io::Result<FatDirEntry> {
|
fn read_dir_entry(&self, rdr: &mut Read) -> io::Result<FatDirEntry> {
|
||||||
let mut name = [0; 11];
|
let mut name = [0; 11];
|
||||||
rdr.read(&mut name)?;
|
rdr.read(&mut name)?;
|
||||||
Ok(FatDirEntry {
|
Ok(FatDirEntry {
|
||||||
name: name,
|
name: name,
|
||||||
attrs: FatFileAttributes::from_bits(rdr.read_u8()?).unwrap(),
|
attrs: FatFileAttributes::from_bits(rdr.read_u8()?).unwrap(),
|
||||||
reserved_0: rdr.read_u8()?,
|
reserved_0: rdr.read_u8()?,
|
||||||
create_time_0: rdr.read_u8()?,
|
create_time_0: rdr.read_u8()?,
|
||||||
create_time_1: rdr.read_u16::<LittleEndian>()?,
|
create_time_1: rdr.read_u16::<LittleEndian>()?,
|
||||||
create_date: rdr.read_u16::<LittleEndian>()?,
|
create_date: rdr.read_u16::<LittleEndian>()?,
|
||||||
access_date: rdr.read_u16::<LittleEndian>()?,
|
access_date: rdr.read_u16::<LittleEndian>()?,
|
||||||
first_cluster_hi: rdr.read_u16::<LittleEndian>()?,
|
first_cluster_hi: rdr.read_u16::<LittleEndian>()?,
|
||||||
modify_time: rdr.read_u16::<LittleEndian>()?,
|
modify_time: rdr.read_u16::<LittleEndian>()?,
|
||||||
modify_date: rdr.read_u16::<LittleEndian>()?,
|
modify_date: rdr.read_u16::<LittleEndian>()?,
|
||||||
first_cluster_lo: rdr.read_u16::<LittleEndian>()?,
|
first_cluster_lo: rdr.read_u16::<LittleEndian>()?,
|
||||||
size: rdr.read_u32::<LittleEndian>()?,
|
size: rdr.read_u32::<LittleEndian>()?,
|
||||||
})
|
state: self.state.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
42
src/file.rs
42
src/file.rs
@ -3,39 +3,39 @@ use std::io::prelude::*;
|
|||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use fs::FatFileSystem;
|
use fs::FatSharedStateRef;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct FatFile {
|
pub struct FatFile {
|
||||||
first_sector: u32,
|
first_sector: u32,
|
||||||
size: u32,
|
size: u32,
|
||||||
offset: u32,
|
offset: u32,
|
||||||
|
state: FatSharedStateRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FatFile {
|
impl FatFile {
|
||||||
pub fn new(first_sector: u32, size: u32) -> FatFile {
|
pub(crate) fn new(first_cluster: u32, size: u32, state: FatSharedStateRef) -> FatFile {
|
||||||
FatFile { first_sector, size, offset: 0 }
|
let first_sector = state.borrow().sector_from_cluster(first_cluster);
|
||||||
|
FatFile {
|
||||||
|
first_sector, size, state, offset: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Read+Seek> FatFileSystem<T> {
|
impl Read for FatFile {
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
pub fn file_from_cluster(&mut self, cluster: u32, size: u32) -> FatFile {
|
let (offset, read_size) = {
|
||||||
FatFile {
|
let state = self.state.borrow();
|
||||||
first_sector: self.sector_from_cluster(cluster),
|
let offset = state.offset_from_sector(self.first_sector) + self.offset as u64;
|
||||||
size: size,
|
let mut read_size = cmp::min((self.size - self.offset) as usize, buf.len());
|
||||||
offset: 0,
|
// FIXME: allow only one cluster for now
|
||||||
}
|
read_size = cmp::min(read_size, (state.get_cluster_size() - self.offset) as usize);
|
||||||
}
|
(offset, read_size)
|
||||||
|
};
|
||||||
pub fn read(&mut self, file: &mut FatFile, buf: &mut [u8]) -> io::Result<usize> {
|
let mut state = self.state.borrow_mut();
|
||||||
let offset = self.offset_from_sector(file.first_sector) + file.offset as u64;
|
state.rdr.seek(SeekFrom::Start(offset))?;
|
||||||
let mut read_size = cmp::min((file.size - file.offset) as usize, buf.len());
|
let size = state.rdr.read(&mut buf[..read_size])?;
|
||||||
// FIXME: allow only one cluster for now
|
self.offset += size as u32;
|
||||||
read_size = cmp::min(read_size, (self.get_cluster_size() - file.offset) as usize);
|
|
||||||
self.rdr.seek(SeekFrom::Start(offset))?;
|
|
||||||
let size = self.rdr.read(&mut buf[..read_size])?;
|
|
||||||
file.offset += size as u32;
|
|
||||||
Ok(size)
|
Ok(size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
167
src/fs.rs
167
src/fs.rs
@ -1,10 +1,15 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
|
use std::cmp;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::io::{Error, ErrorKind};
|
use std::io::{Error, ErrorKind};
|
||||||
|
use std::io::SeekFrom;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
use std::rc::Rc;
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
|
|
||||||
use file::FatFile;
|
use file::FatFile;
|
||||||
|
use dir::FatDir;
|
||||||
use table::{FatTable, FatTable12, FatTable16, FatTable32};
|
use table::{FatTable, FatTable12, FatTable16, FatTable32};
|
||||||
|
|
||||||
// FAT implementation based on:
|
// FAT implementation based on:
|
||||||
@ -16,15 +21,46 @@ pub enum FatType {
|
|||||||
Fat12, Fat16, Fat32, ExFat
|
Fat12, Fat16, Fat32, ExFat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ReadSeek: Read + Seek {}
|
||||||
|
impl<T> ReadSeek for T where T: Read + Seek {}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct FatFileSystem<T: Read+Seek> {
|
pub(crate) struct FatSharedState {
|
||||||
pub(crate) rdr: T,
|
pub rdr: Box<ReadSeek>,
|
||||||
pub(crate) fat_type: FatType,
|
pub fat_type: FatType,
|
||||||
pub(crate) boot: FatBootRecord,
|
pub boot: FatBootRecord,
|
||||||
first_fat_sector: u32,
|
pub first_fat_sector: u32,
|
||||||
pub(crate) first_data_sector: u32,
|
pub first_data_sector: u32,
|
||||||
pub(crate) root_dir_sectors: u32,
|
pub root_dir_sectors: u32,
|
||||||
pub(crate) table: Box<FatTable>,
|
pub table: Box<FatTable>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FatSharedState {
|
||||||
|
pub(crate) fn offset_from_sector(&self, sector: u32) -> u64 {
|
||||||
|
(sector as u64) * self.boot.bpb.bytes_per_sector as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn sector_from_cluster(&self, cluster: u32) -> u32 {
|
||||||
|
((cluster - 2) * self.boot.bpb.sectors_per_cluster as u32) + self.first_data_sector
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_cluster_size(&self) -> u32 {
|
||||||
|
self.boot.bpb.sectors_per_cluster as u32 * self.boot.bpb.bytes_per_sector as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_root_dir_sector(&self) -> u32 {
|
||||||
|
match self.fat_type {
|
||||||
|
FatType::Fat12 | FatType::Fat16 => self.first_data_sector - self.root_dir_sectors,
|
||||||
|
_ => self.sector_from_cluster(self.boot.bpb.root_cluster)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) type FatSharedStateRef = Rc<RefCell<FatSharedState>>;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct FatFileSystem {
|
||||||
|
pub(crate) state: FatSharedStateRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -80,21 +116,11 @@ impl Default for FatBootRecord {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Read+Seek> FatFileSystem<T> {
|
impl FatFileSystem {
|
||||||
fn fat_type_from_clusters(total_clusters: u32) -> FatType {
|
|
||||||
if total_clusters < 4085 {
|
|
||||||
FatType::Fat12
|
|
||||||
} else if total_clusters < 65525 {
|
|
||||||
FatType::Fat16
|
|
||||||
} else if total_clusters < 268435445 {
|
|
||||||
FatType::Fat32
|
|
||||||
} else {
|
|
||||||
FatType::ExFat
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(rdr: &mut T) -> io::Result<FatFileSystem<&mut T>> {
|
//pub fn new<T: ReadSeek + 'static>(rdr: T) -> io::Result<FatFileSystem> {
|
||||||
let boot = FatFileSystem::<T>::read_boot_record(rdr)?;
|
pub fn new<T: ReadSeek + 'static>(mut rdr: Box<T>) -> io::Result<FatFileSystem> {
|
||||||
|
let boot = Self::read_boot_record(&mut *rdr)?;
|
||||||
if boot.boot_sig != [0x55, 0xAA] {
|
if boot.boot_sig != [0x55, 0xAA] {
|
||||||
return Err(Error::new(ErrorKind::Other, "invalid signature"));
|
return Err(Error::new(ErrorKind::Other, "invalid signature"));
|
||||||
}
|
}
|
||||||
@ -106,7 +132,7 @@ impl<T: Read+Seek> FatFileSystem<T> {
|
|||||||
let first_fat_sector = boot.bpb.reserved_sector_count as u32;
|
let first_fat_sector = boot.bpb.reserved_sector_count as u32;
|
||||||
let data_sectors = total_sectors - (boot.bpb.reserved_sector_count as u32 + (boot.bpb.table_count as u32 * table_size) + root_dir_sectors as u32);
|
let data_sectors = total_sectors - (boot.bpb.reserved_sector_count as u32 + (boot.bpb.table_count as u32 * table_size) + root_dir_sectors as u32);
|
||||||
let total_clusters = data_sectors / boot.bpb.sectors_per_cluster as u32;
|
let total_clusters = data_sectors / boot.bpb.sectors_per_cluster as u32;
|
||||||
let fat_type = FatFileSystem::<T>::fat_type_from_clusters(total_clusters);
|
let fat_type = Self::fat_type_from_clusters(total_clusters);
|
||||||
|
|
||||||
{
|
{
|
||||||
let oem_name_str = str::from_utf8(&boot.oem_name).unwrap().trim_right();
|
let oem_name_str = str::from_utf8(&boot.oem_name).unwrap().trim_right();
|
||||||
@ -121,17 +147,17 @@ impl<T: Read+Seek> FatFileSystem<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: other versions
|
// FIXME: other versions
|
||||||
|
|
||||||
let table_size_bytes = table_size * boot.bpb.bytes_per_sector as u32;
|
let table_size_bytes = table_size * boot.bpb.bytes_per_sector as u32;
|
||||||
let table: Box<FatTable> = match fat_type {
|
let table: Box<FatTable> = match fat_type {
|
||||||
FatType::Fat12 => Box::new(FatTable12::read(rdr, table_size_bytes as usize)?),
|
FatType::Fat12 => Box::new(FatTable12::read(&mut rdr, table_size_bytes as usize)?),
|
||||||
FatType::Fat16 => Box::new(FatTable16::read(rdr, table_size_bytes as usize)?),
|
FatType::Fat16 => Box::new(FatTable16::read(&mut rdr, table_size_bytes as usize)?),
|
||||||
FatType::Fat32 => Box::new(FatTable32::read(rdr, table_size_bytes as usize)?),
|
FatType::Fat32 => Box::new(FatTable32::read(&mut rdr, table_size_bytes as usize)?),
|
||||||
_ => panic!("TODO: exfat")
|
_ => panic!("TODO: exfat")
|
||||||
};
|
};
|
||||||
|
|
||||||
let fs = FatFileSystem {
|
let rdr_box = Box::new(rdr);
|
||||||
rdr: rdr,
|
let state = FatSharedState {
|
||||||
|
rdr: rdr_box,
|
||||||
fat_type: fat_type,
|
fat_type: fat_type,
|
||||||
boot: boot,
|
boot: boot,
|
||||||
first_data_sector: first_data_sector,
|
first_data_sector: first_data_sector,
|
||||||
@ -140,7 +166,9 @@ impl<T: Read+Seek> FatFileSystem<T> {
|
|||||||
table: table,
|
table: table,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(fs)
|
Ok(FatFileSystem {
|
||||||
|
state: Rc::new(RefCell::new(state)),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_bpb(rdr: &mut Read) -> io::Result<FatBiosParameterBlock> {
|
fn read_bpb(rdr: &mut Read) -> io::Result<FatBiosParameterBlock> {
|
||||||
@ -187,11 +215,23 @@ impl<T: Read+Seek> FatFileSystem<T> {
|
|||||||
Ok(bpb)
|
Ok(bpb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fat_type_from_clusters(total_clusters: u32) -> FatType {
|
||||||
|
if total_clusters < 4085 {
|
||||||
|
FatType::Fat12
|
||||||
|
} else if total_clusters < 65525 {
|
||||||
|
FatType::Fat16
|
||||||
|
} else if total_clusters < 268435445 {
|
||||||
|
FatType::Fat32
|
||||||
|
} else {
|
||||||
|
FatType::ExFat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn read_boot_record(rdr: &mut Read) -> io::Result<FatBootRecord> {
|
fn read_boot_record(rdr: &mut Read) -> io::Result<FatBootRecord> {
|
||||||
let mut boot: FatBootRecord = Default::default();
|
let mut boot: FatBootRecord = Default::default();
|
||||||
rdr.read(&mut boot.bootjmp)?;
|
rdr.read(&mut boot.bootjmp)?;
|
||||||
rdr.read(&mut boot.oem_name)?;
|
rdr.read(&mut boot.oem_name)?;
|
||||||
boot.bpb = FatFileSystem::<T>::read_bpb(rdr)?;
|
boot.bpb = Self::read_bpb(rdr)?;
|
||||||
|
|
||||||
if boot.bpb.table_size_16 == 0 {
|
if boot.bpb.table_size_16 == 0 {
|
||||||
rdr.read_exact(&mut boot.boot_code[0..420])?;
|
rdr.read_exact(&mut boot.boot_code[0..420])?;
|
||||||
@ -206,28 +246,47 @@ impl<T: Read+Seek> FatFileSystem<T> {
|
|||||||
// self.offset_from_sector(self.sector_from_cluster(cluser))
|
// self.offset_from_sector(self.sector_from_cluster(cluser))
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub(crate) fn offset_from_sector(&self, sector: u32) -> u64 {
|
pub fn root_dir(&mut self) -> FatDir {
|
||||||
(sector as u64) * self.boot.bpb.bytes_per_sector as u64
|
let state = self.state.borrow();
|
||||||
}
|
let root_rdr: Box<Read> = match state.fat_type {
|
||||||
|
FatType::Fat12 | FatType::Fat16 => Box::new(FatSlice::from_sectors(
|
||||||
pub(crate) fn sector_from_cluster(&self, cluster: u32) -> u32 {
|
state.first_data_sector - state.root_dir_sectors, state.root_dir_sectors, self.state.clone())),
|
||||||
((cluster - 2) * self.boot.bpb.sectors_per_cluster as u32) + self.first_data_sector
|
_ => Box::new(FatFile::new(state.boot.bpb.root_cluster, state.root_dir_sectors, self.state.clone()))
|
||||||
}
|
};
|
||||||
|
FatDir::new(root_rdr, self.state.clone())
|
||||||
pub(crate) fn get_cluster_size(&self) -> u32 {
|
}
|
||||||
self.boot.bpb.sectors_per_cluster as u32 * self.boot.bpb.bytes_per_sector as u32
|
}
|
||||||
}
|
|
||||||
|
struct FatSlice {
|
||||||
pub(crate) fn get_root_dir_sector(&self) -> u32 {
|
begin: u64,
|
||||||
match self.fat_type {
|
size: u64,
|
||||||
FatType::Fat12 | FatType::Fat16 => self.first_data_sector - self.root_dir_sectors,
|
offset: u64,
|
||||||
_ => self.sector_from_cluster(self.boot.bpb.root_cluster)
|
state: FatSharedStateRef,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
impl FatSlice {
|
||||||
pub fn root_dir(&mut self) -> FatFile {
|
pub(crate) fn new(begin: u64, size: u64, state: FatSharedStateRef) -> FatSlice {
|
||||||
let first_root_dir_sector = self.get_root_dir_sector();
|
FatSlice { begin, size, state, offset: 0 }
|
||||||
let root_dir_size = self.root_dir_sectors * self.boot.bpb.bytes_per_sector as u32;
|
}
|
||||||
FatFile::new(first_root_dir_sector, root_dir_size)
|
|
||||||
|
pub(crate) fn from_sectors(first_sector: u32, sectors_count: u32, state: FatSharedStateRef) -> FatSlice {
|
||||||
|
let bytes_per_sector = state.borrow().boot.bpb.bytes_per_sector as u64;
|
||||||
|
Self::new(first_sector as u64 * bytes_per_sector, sectors_count as u64 * bytes_per_sector, state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Read for FatSlice {
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
|
let (offset, read_size) = {
|
||||||
|
let state = self.state.borrow();
|
||||||
|
let offset = self.begin + self.offset;
|
||||||
|
let mut read_size = cmp::min((self.size - self.offset) as usize, buf.len());
|
||||||
|
(offset, read_size)
|
||||||
|
};
|
||||||
|
let mut state = self.state.borrow_mut();
|
||||||
|
state.rdr.seek(SeekFrom::Start(offset))?;
|
||||||
|
let size = state.rdr.read(&mut buf[..read_size])?;
|
||||||
|
self.offset += size as u64;
|
||||||
|
Ok(size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,10 @@ use rustfat::FatFileSystem;
|
|||||||
#[test]
|
#[test]
|
||||||
fn fat12_test() {
|
fn fat12_test() {
|
||||||
let file = File::open("resources/floppy.img").unwrap();
|
let file = File::open("resources/floppy.img").unwrap();
|
||||||
let mut buf_rdr = BufReader::new(file);
|
let buf_rdr = BufReader::new(file);
|
||||||
let mut fs = FatFileSystem::new(&mut buf_rdr).unwrap();
|
let mut fs = FatFileSystem::new(Box::new(buf_rdr)).unwrap();
|
||||||
let mut root_dir = fs.root_dir();
|
let mut root_dir = fs.root_dir();
|
||||||
let entries = fs.read_dir(&mut root_dir).unwrap();
|
let entries = root_dir.list().unwrap();
|
||||||
assert_eq!(entries.len(), 2);
|
assert_eq!(entries.len(), 2);
|
||||||
assert_eq!(entries[0].get_name(), "RAFOS");
|
assert_eq!(entries[0].get_name(), "RAFOS");
|
||||||
assert_eq!(entries[1].get_name(), "GRUB");
|
assert_eq!(entries[1].get_name(), "GRUB");
|
||||||
|
Loading…
Reference in New Issue
Block a user