Introduce FsOptions struct for providing options for library.
Old read_only flag in FileSystem::new was misleading.
This commit is contained in:
parent
8a8ee3c51a
commit
d5c37f2af5
@ -31,8 +31,8 @@ Put this in your crate root:
|
||||
You can start using library now:
|
||||
|
||||
let img_file = File::open("fat.img").unwrap();
|
||||
let mut buf_stream = BufStream::new(img_file);
|
||||
let fs = fatfs::FileSystem::new(&mut buf_stream, true).unwrap();
|
||||
let mut buf_stream = fatfs::BufStream::new(img_file);
|
||||
let fs = fatfs::FileSystem::new(&mut buf_stream, fatfs::FsOptions::new()).unwrap();
|
||||
let mut root_dir = fs.root_dir();
|
||||
let mut file = root_dir.create_file("hello.txt").unwrap();
|
||||
file.write_all(b"Hello World!").unwrap();
|
||||
|
@ -5,12 +5,12 @@ use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::str;
|
||||
|
||||
use fatfs::{FileSystem, BufStream};
|
||||
use fatfs::{FileSystem, FsOptions, BufStream};
|
||||
|
||||
fn main() {
|
||||
let file = File::open("resources/fat32.img").unwrap();
|
||||
let mut buf_rdr = BufStream::new(file);
|
||||
let fs = FileSystem::new(&mut buf_rdr, true).unwrap();
|
||||
let fs = FileSystem::new(&mut buf_rdr, FsOptions::new()).unwrap();
|
||||
let mut root_dir = fs.root_dir();
|
||||
let mut file = root_dir.open_file(&env::args().nth(1).unwrap()).unwrap();
|
||||
let mut buf = vec![];
|
||||
|
@ -5,7 +5,7 @@ use std::env;
|
||||
use std::fs::File;
|
||||
use chrono::{DateTime, Local};
|
||||
|
||||
use fatfs::{FileSystem, BufStream};
|
||||
use fatfs::{FileSystem, FsOptions, BufStream};
|
||||
|
||||
fn format_file_size(size: u64) -> String {
|
||||
const KB: u64 = 1024;
|
||||
@ -25,7 +25,7 @@ fn format_file_size(size: u64) -> String {
|
||||
fn main() {
|
||||
let file = File::open("resources/fat32.img").unwrap();
|
||||
let mut buf_rdr = BufStream::new(file);
|
||||
let fs = FileSystem::new(&mut buf_rdr, true).unwrap();
|
||||
let fs = FileSystem::new(&mut buf_rdr, FsOptions::new()).unwrap();
|
||||
let mut root_dir = fs.root_dir();
|
||||
let dir = match env::args().nth(1) {
|
||||
None => root_dir,
|
||||
|
@ -194,7 +194,7 @@ impl<'a, 'b> Read for File<'a, 'b> {
|
||||
self.current_cluster = Some(current_cluster);
|
||||
|
||||
match self.entry {
|
||||
Some(ref mut e) if !self.fs.read_only => e.reset_accessed(),
|
||||
Some(ref mut e) if self.fs.options.update_accessed_date => e.reset_accessed(),
|
||||
_ => {},
|
||||
}
|
||||
Ok(read_bytes)
|
||||
|
41
src/fs.rs
41
src/fs.rs
@ -129,6 +129,14 @@ impl BiosParameterBlock {
|
||||
}
|
||||
Ok(bpb)
|
||||
}
|
||||
|
||||
fn mirroring_enabled(&self) -> bool {
|
||||
self.extended_flags & 0x80 == 0
|
||||
}
|
||||
|
||||
fn active_fat(&self) -> u16 {
|
||||
self.extended_flags & 0x0F
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -169,12 +177,32 @@ impl Default for BootRecord {
|
||||
}
|
||||
}
|
||||
|
||||
/// FAT filesystem options.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct FsOptions {
|
||||
pub(crate) update_accessed_date: bool,
|
||||
}
|
||||
|
||||
impl FsOptions {
|
||||
pub fn new() -> Self {
|
||||
FsOptions {
|
||||
update_accessed_date: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// If enabled library updates accessed date field in directory entry when reading
|
||||
pub fn update_accessed_date(mut self, enabled: bool) -> Self {
|
||||
self.update_accessed_date = enabled;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) type FileSystemRef<'a, 'b: 'a> = &'a FileSystem<'b>;
|
||||
|
||||
/// FAT filesystem main struct.
|
||||
pub struct FileSystem<'a> {
|
||||
pub(crate) disk: RefCell<&'a mut ReadWriteSeek>,
|
||||
pub(crate) read_only: bool,
|
||||
pub(crate) options: FsOptions,
|
||||
fat_type: FatType,
|
||||
bpb: BiosParameterBlock,
|
||||
first_data_sector: u32,
|
||||
@ -184,12 +212,9 @@ pub struct FileSystem<'a> {
|
||||
impl <'a> FileSystem<'a> {
|
||||
/// Creates new filesystem object instance.
|
||||
///
|
||||
/// read_only argument is a hint for library. It doesnt prevent user from writing to file.
|
||||
/// For now it prevents accessed date field automatic update in dir entry.
|
||||
///
|
||||
/// Note: creating multiple filesystem objects with one underlying device/disk image can
|
||||
/// cause filesystem corruption.
|
||||
pub fn new<T: ReadWriteSeek>(disk: &'a mut T, read_only: bool) -> io::Result<FileSystem<'a>> {
|
||||
pub fn new<T: ReadWriteSeek>(disk: &'a mut T, options: FsOptions) -> io::Result<FileSystem<'a>> {
|
||||
let bpb = {
|
||||
let boot = BootRecord::deserialize(disk)?;
|
||||
if boot.boot_sig != [0x55, 0xAA] {
|
||||
@ -214,7 +239,7 @@ impl <'a> FileSystem<'a> {
|
||||
|
||||
Ok(FileSystem {
|
||||
disk: RefCell::new(disk),
|
||||
read_only,
|
||||
options,
|
||||
fat_type,
|
||||
bpb: bpb,
|
||||
first_data_sector,
|
||||
@ -272,11 +297,11 @@ impl <'a> FileSystem<'a> {
|
||||
let sectors_per_fat =
|
||||
if self.bpb.sectors_per_fat_16 == 0 { self.bpb.sectors_per_fat_32 }
|
||||
else { self.bpb.sectors_per_fat_16 as u32 };
|
||||
let mirroring_enabled = self.bpb.extended_flags & 0x80 == 0;
|
||||
let mirroring_enabled = self.bpb.mirroring_enabled();
|
||||
let (fat_first_sector, mirrors) = if mirroring_enabled {
|
||||
(self.bpb.reserved_sectors as u32, self.bpb.fats)
|
||||
} else {
|
||||
let active_fat = (self.bpb.extended_flags & 0x0F) as u32;
|
||||
let active_fat = self.bpb.active_fat() as u32;
|
||||
let fat_first_sector = (self.bpb.reserved_sectors as u32) + active_fat * sectors_per_fat;
|
||||
(fat_first_sector, 1)
|
||||
};
|
||||
|
@ -6,7 +6,7 @@ use std::io::SeekFrom;
|
||||
use std::io::prelude::*;
|
||||
use std::str;
|
||||
|
||||
use fatfs::{FileSystem, FatType, DirEntry, BufStream};
|
||||
use fatfs::{FileSystem, FsOptions, FatType, DirEntry, BufStream};
|
||||
|
||||
const TEST_TEXT: &str = "Rust is cool!\n";
|
||||
const FAT12_IMG: &str = "resources/fat12.img";
|
||||
@ -17,7 +17,7 @@ fn call_with_fs(f: &Fn(FileSystem) -> (), filename: &str) {
|
||||
let _ = env_logger::init();
|
||||
let file = fs::File::open(filename).unwrap();
|
||||
let mut buf_file = BufStream::new(file);
|
||||
let fs = FileSystem::new(&mut buf_file, true).unwrap();
|
||||
let fs = FileSystem::new(&mut buf_file, FsOptions::new()).unwrap();
|
||||
f(fs);
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@ use std::io::prelude::*;
|
||||
use std::io;
|
||||
use std::str;
|
||||
|
||||
use fatfs::FileSystem;
|
||||
use fatfs::BufStream;
|
||||
use fatfs::{FileSystem, FsOptions, BufStream};
|
||||
|
||||
const FAT12_IMG: &str = "fat12.img";
|
||||
const FAT16_IMG: &str = "fat16.img";
|
||||
@ -25,7 +24,8 @@ fn call_with_fs(f: &Fn(FileSystem) -> (), filename: &str, test_seq: u32) {
|
||||
{
|
||||
let file = fs::OpenOptions::new().read(true).write(true).open(&tmp_path).unwrap();
|
||||
let mut buf_file = BufStream::new(file);
|
||||
let fs = FileSystem::new(&mut buf_file, false).unwrap();
|
||||
let options = FsOptions::new().update_accessed_date(true);
|
||||
let fs = FileSystem::new(&mut buf_file, options).unwrap();
|
||||
f(fs);
|
||||
}
|
||||
fs::remove_file(tmp_path).unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user