forked from M-Labs/rust-fatfs
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:
|
You can start using library now:
|
||||||
|
|
||||||
let img_file = File::open("fat.img").unwrap();
|
let img_file = File::open("fat.img").unwrap();
|
||||||
let mut buf_stream = BufStream::new(img_file);
|
let mut buf_stream = fatfs::BufStream::new(img_file);
|
||||||
let fs = fatfs::FileSystem::new(&mut buf_stream, true).unwrap();
|
let fs = fatfs::FileSystem::new(&mut buf_stream, fatfs::FsOptions::new()).unwrap();
|
||||||
let mut root_dir = fs.root_dir();
|
let mut root_dir = fs.root_dir();
|
||||||
let mut file = root_dir.create_file("hello.txt").unwrap();
|
let mut file = root_dir.create_file("hello.txt").unwrap();
|
||||||
file.write_all(b"Hello World!").unwrap();
|
file.write_all(b"Hello World!").unwrap();
|
||||||
|
@ -5,12 +5,12 @@ use std::fs::File;
|
|||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use fatfs::{FileSystem, BufStream};
|
use fatfs::{FileSystem, FsOptions, BufStream};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let file = File::open("resources/fat32.img").unwrap();
|
let file = File::open("resources/fat32.img").unwrap();
|
||||||
let mut buf_rdr = BufStream::new(file);
|
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 root_dir = fs.root_dir();
|
||||||
let mut file = root_dir.open_file(&env::args().nth(1).unwrap()).unwrap();
|
let mut file = root_dir.open_file(&env::args().nth(1).unwrap()).unwrap();
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
|
@ -5,7 +5,7 @@ use std::env;
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use chrono::{DateTime, Local};
|
use chrono::{DateTime, Local};
|
||||||
|
|
||||||
use fatfs::{FileSystem, BufStream};
|
use fatfs::{FileSystem, FsOptions, BufStream};
|
||||||
|
|
||||||
fn format_file_size(size: u64) -> String {
|
fn format_file_size(size: u64) -> String {
|
||||||
const KB: u64 = 1024;
|
const KB: u64 = 1024;
|
||||||
@ -25,7 +25,7 @@ fn format_file_size(size: u64) -> String {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let file = File::open("resources/fat32.img").unwrap();
|
let file = File::open("resources/fat32.img").unwrap();
|
||||||
let mut buf_rdr = BufStream::new(file);
|
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 root_dir = fs.root_dir();
|
||||||
let dir = match env::args().nth(1) {
|
let dir = match env::args().nth(1) {
|
||||||
None => root_dir,
|
None => root_dir,
|
||||||
|
@ -194,7 +194,7 @@ impl<'a, 'b> Read for File<'a, 'b> {
|
|||||||
self.current_cluster = Some(current_cluster);
|
self.current_cluster = Some(current_cluster);
|
||||||
|
|
||||||
match self.entry {
|
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)
|
Ok(read_bytes)
|
||||||
|
41
src/fs.rs
41
src/fs.rs
@ -129,6 +129,14 @@ impl BiosParameterBlock {
|
|||||||
}
|
}
|
||||||
Ok(bpb)
|
Ok(bpb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mirroring_enabled(&self) -> bool {
|
||||||
|
self.extended_flags & 0x80 == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn active_fat(&self) -> u16 {
|
||||||
|
self.extended_flags & 0x0F
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[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>;
|
pub(crate) type FileSystemRef<'a, 'b: 'a> = &'a FileSystem<'b>;
|
||||||
|
|
||||||
/// FAT filesystem main struct.
|
/// FAT filesystem main struct.
|
||||||
pub struct FileSystem<'a> {
|
pub struct FileSystem<'a> {
|
||||||
pub(crate) disk: RefCell<&'a mut ReadWriteSeek>,
|
pub(crate) disk: RefCell<&'a mut ReadWriteSeek>,
|
||||||
pub(crate) read_only: bool,
|
pub(crate) options: FsOptions,
|
||||||
fat_type: FatType,
|
fat_type: FatType,
|
||||||
bpb: BiosParameterBlock,
|
bpb: BiosParameterBlock,
|
||||||
first_data_sector: u32,
|
first_data_sector: u32,
|
||||||
@ -184,12 +212,9 @@ pub struct FileSystem<'a> {
|
|||||||
impl <'a> FileSystem<'a> {
|
impl <'a> FileSystem<'a> {
|
||||||
/// Creates new filesystem object instance.
|
/// 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
|
/// Note: creating multiple filesystem objects with one underlying device/disk image can
|
||||||
/// cause filesystem corruption.
|
/// 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 bpb = {
|
||||||
let boot = BootRecord::deserialize(disk)?;
|
let boot = BootRecord::deserialize(disk)?;
|
||||||
if boot.boot_sig != [0x55, 0xAA] {
|
if boot.boot_sig != [0x55, 0xAA] {
|
||||||
@ -214,7 +239,7 @@ impl <'a> FileSystem<'a> {
|
|||||||
|
|
||||||
Ok(FileSystem {
|
Ok(FileSystem {
|
||||||
disk: RefCell::new(disk),
|
disk: RefCell::new(disk),
|
||||||
read_only,
|
options,
|
||||||
fat_type,
|
fat_type,
|
||||||
bpb: bpb,
|
bpb: bpb,
|
||||||
first_data_sector,
|
first_data_sector,
|
||||||
@ -272,11 +297,11 @@ impl <'a> FileSystem<'a> {
|
|||||||
let sectors_per_fat =
|
let sectors_per_fat =
|
||||||
if self.bpb.sectors_per_fat_16 == 0 { self.bpb.sectors_per_fat_32 }
|
if self.bpb.sectors_per_fat_16 == 0 { self.bpb.sectors_per_fat_32 }
|
||||||
else { self.bpb.sectors_per_fat_16 as u32 };
|
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 {
|
let (fat_first_sector, mirrors) = if mirroring_enabled {
|
||||||
(self.bpb.reserved_sectors as u32, self.bpb.fats)
|
(self.bpb.reserved_sectors as u32, self.bpb.fats)
|
||||||
} else {
|
} 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;
|
let fat_first_sector = (self.bpb.reserved_sectors as u32) + active_fat * sectors_per_fat;
|
||||||
(fat_first_sector, 1)
|
(fat_first_sector, 1)
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@ use std::io::SeekFrom;
|
|||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::str;
|
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 TEST_TEXT: &str = "Rust is cool!\n";
|
||||||
const FAT12_IMG: &str = "resources/fat12.img";
|
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 _ = env_logger::init();
|
||||||
let file = fs::File::open(filename).unwrap();
|
let file = fs::File::open(filename).unwrap();
|
||||||
let mut buf_file = BufStream::new(file);
|
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);
|
f(fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,7 @@ use std::io::prelude::*;
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use fatfs::FileSystem;
|
use fatfs::{FileSystem, FsOptions, BufStream};
|
||||||
use fatfs::BufStream;
|
|
||||||
|
|
||||||
const FAT12_IMG: &str = "fat12.img";
|
const FAT12_IMG: &str = "fat12.img";
|
||||||
const FAT16_IMG: &str = "fat16.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 file = fs::OpenOptions::new().read(true).write(true).open(&tmp_path).unwrap();
|
||||||
let mut buf_file = BufStream::new(file);
|
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);
|
f(fs);
|
||||||
}
|
}
|
||||||
fs::remove_file(tmp_path).unwrap();
|
fs::remove_file(tmp_path).unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user