Remove unneeded Fat prefix for most structures.
This commit is contained in:
parent
beb463ba3f
commit
a1a2ffc2af
@ -6,12 +6,12 @@ use std::io::BufReader;
|
|||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use fatfs::FatFileSystem;
|
use fatfs::FileSystem;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let file = File::open("resources/fat32.img").unwrap();
|
let file = File::open("resources/fat32.img").unwrap();
|
||||||
let mut buf_rdr = BufReader::new(file);
|
let mut buf_rdr = BufReader::new(file);
|
||||||
let fs = FatFileSystem::new(&mut buf_rdr).unwrap();
|
let fs = FileSystem::new(&mut buf_rdr).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![];
|
||||||
|
@ -7,7 +7,7 @@ use std::io::BufReader;
|
|||||||
use std::str;
|
use std::str;
|
||||||
use chrono::{DateTime, Local};
|
use chrono::{DateTime, Local};
|
||||||
|
|
||||||
use fatfs::FatFileSystem;
|
use fatfs::FileSystem;
|
||||||
|
|
||||||
fn format_file_size(size: u64) -> String {
|
fn format_file_size(size: u64) -> String {
|
||||||
const KB: u64 = 1024;
|
const KB: u64 = 1024;
|
||||||
@ -27,7 +27,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 = BufReader::new(file);
|
let mut buf_rdr = BufReader::new(file);
|
||||||
let fs = FatFileSystem::new(&mut buf_rdr).unwrap();
|
let fs = FileSystem::new(&mut buf_rdr).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,
|
||||||
|
187
src/dir.rs
187
src/dir.rs
@ -6,38 +6,40 @@ use std::io::{Cursor, ErrorKind, SeekFrom};
|
|||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "chrono")]
|
||||||
use chrono::{DateTime, Date, TimeZone, Local};
|
use chrono::{TimeZone, Local};
|
||||||
|
#[cfg(feature = "chrono")]
|
||||||
|
use chrono;
|
||||||
|
|
||||||
use fs::{FatFileSystemRef, FatSlice};
|
use fs::{FileSystemRef, DiskSlice};
|
||||||
use file::FatFile;
|
use file::File;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) enum FatDirReader<'a, 'b: 'a> {
|
pub(crate) enum DirReader<'a, 'b: 'a> {
|
||||||
File(FatFile<'a, 'b>),
|
File(File<'a, 'b>),
|
||||||
Root(FatSlice<'a, 'b>),
|
Root(DiskSlice<'a, 'b>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> Read for FatDirReader<'a, 'b> {
|
impl <'a, 'b> Read for DirReader<'a, 'b> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
match self {
|
match self {
|
||||||
&mut FatDirReader::File(ref mut file) => file.read(buf),
|
&mut DirReader::File(ref mut file) => file.read(buf),
|
||||||
&mut FatDirReader::Root(ref mut raw) => raw.read(buf),
|
&mut DirReader::Root(ref mut raw) => raw.read(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> Seek for FatDirReader<'a, 'b> {
|
impl <'a, 'b> Seek for DirReader<'a, 'b> {
|
||||||
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
||||||
match self {
|
match self {
|
||||||
&mut FatDirReader::File(ref mut file) => file.seek(pos),
|
&mut DirReader::File(ref mut file) => file.seek(pos),
|
||||||
&mut FatDirReader::Root(ref mut raw) => raw.seek(pos),
|
&mut DirReader::Root(ref mut raw) => raw.seek(pos),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct FatFileAttributes: u8 {
|
pub struct FileAttributes: u8 {
|
||||||
const READ_ONLY = 0x01;
|
const READ_ONLY = 0x01;
|
||||||
const HIDDEN = 0x02;
|
const HIDDEN = 0x02;
|
||||||
const SYSTEM = 0x04;
|
const SYSTEM = 0x04;
|
||||||
@ -51,9 +53,9 @@ bitflags! {
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
struct FatDirFileEntryData {
|
struct DirFileEntryData {
|
||||||
name: [u8; 11],
|
name: [u8; 11],
|
||||||
attrs: FatFileAttributes,
|
attrs: FileAttributes,
|
||||||
reserved_0: u8,
|
reserved_0: u8,
|
||||||
create_time_0: u8,
|
create_time_0: u8,
|
||||||
create_time_1: u16,
|
create_time_1: u16,
|
||||||
@ -68,10 +70,10 @@ struct FatDirFileEntryData {
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
struct FatDirLfnEntryData {
|
struct DirLfnEntryData {
|
||||||
order: u8,
|
order: u8,
|
||||||
name_0: [u16; 5],
|
name_0: [u16; 5],
|
||||||
attrs: FatFileAttributes,
|
attrs: FileAttributes,
|
||||||
entry_type: u8,
|
entry_type: u8,
|
||||||
checksum: u8,
|
checksum: u8,
|
||||||
name_1: [u16; 6],
|
name_1: [u16; 6],
|
||||||
@ -80,74 +82,77 @@ struct FatDirLfnEntryData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum FatDirEntryData {
|
enum DirEntryData {
|
||||||
File(FatDirFileEntryData),
|
File(DirFileEntryData),
|
||||||
Lfn(FatDirLfnEntryData),
|
Lfn(DirLfnEntryData),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FatDirEntry<'a, 'b: 'a> {
|
pub struct DirEntry<'a, 'b: 'a> {
|
||||||
data: FatDirFileEntryData,
|
data: DirFileEntryData,
|
||||||
lfn: Vec<u16>,
|
lfn: Vec<u16>,
|
||||||
fs: FatFileSystemRef<'a, 'b>,
|
fs: FileSystemRef<'a, 'b>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DosDate {
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct Date {
|
||||||
pub year: u16,
|
pub year: u16,
|
||||||
pub month: u16,
|
pub month: u16,
|
||||||
pub day: u16,
|
pub day: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DosTime {
|
impl Date {
|
||||||
|
pub(crate) fn from_word(dos_date: u16) -> Self {
|
||||||
|
let (year, month, day) = ((dos_date >> 9) + 1980, (dos_date >> 5) & 0xF, dos_date & 0x1F);
|
||||||
|
Date { year, month, day }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct Time {
|
||||||
pub hour: u16,
|
pub hour: u16,
|
||||||
pub min: u16,
|
pub min: u16,
|
||||||
pub sec: u16,
|
pub sec: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DosDateTime {
|
impl Time {
|
||||||
pub date: DosDate,
|
|
||||||
pub time: DosTime,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DosDate {
|
|
||||||
pub(crate) fn from_word(dos_date: u16) -> Self {
|
|
||||||
let (year, month, day) = ((dos_date >> 9) + 1980, (dos_date >> 5) & 0xF, dos_date & 0x1F);
|
|
||||||
DosDate { year, month, day }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DosTime {
|
|
||||||
pub(crate) fn from_word(dos_time: u16) -> Self {
|
pub(crate) fn from_word(dos_time: u16) -> Self {
|
||||||
let (hour, min, sec) = (dos_time >> 11, (dos_time >> 5) & 0x3F, (dos_time & 0x1F) * 2);
|
let (hour, min, sec) = (dos_time >> 11, (dos_time >> 5) & 0x3F, (dos_time & 0x1F) * 2);
|
||||||
DosTime { hour, min, sec }
|
Time { hour, min, sec }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DosDateTime {
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct DateTime {
|
||||||
|
pub date: Date,
|
||||||
|
pub time: Time,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DateTime {
|
||||||
pub(crate) fn from_words(dos_date: u16, dos_time: u16) -> Self {
|
pub(crate) fn from_words(dos_date: u16, dos_time: u16) -> Self {
|
||||||
DosDateTime {
|
DateTime {
|
||||||
date: DosDate::from_word(dos_date),
|
date: Date::from_word(dos_date),
|
||||||
time: DosTime::from_word(dos_time),
|
time: Time::from_word(dos_time),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "chrono")]
|
||||||
impl From<DosDate> for Date<Local> {
|
impl From<Date> for chrono::Date<Local> {
|
||||||
fn from(date: DosDate) -> Self {
|
fn from(date: Date) -> Self {
|
||||||
Local.ymd(date.year as i32, date.month as u32, date.day as u32)
|
Local.ymd(date.year as i32, date.month as u32, date.day as u32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "chrono")]
|
||||||
impl From<DosDateTime> for DateTime<Local> {
|
impl From<DateTime> for chrono::DateTime<Local> {
|
||||||
fn from(date_time: DosDateTime) -> Self {
|
fn from(date_time: DateTime) -> Self {
|
||||||
Date::<Local>::from(date_time.date)
|
chrono::Date::<Local>::from(date_time.date)
|
||||||
.and_hms(date_time.time.hour as u32, date_time.time.min as u32, date_time.time.sec as u32)
|
.and_hms(date_time.time.hour as u32, date_time.time.min as u32, date_time.time.sec as u32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> FatDirEntry<'a, 'b> {
|
impl <'a, 'b> DirEntry<'a, 'b> {
|
||||||
pub fn short_file_name(&self) -> String {
|
pub fn short_file_name(&self) -> String {
|
||||||
let name_str = String::from_utf8_lossy(&self.data.name[0..8]);
|
let name_str = String::from_utf8_lossy(&self.data.name[0..8]);
|
||||||
let ext_str = String::from_utf8_lossy(&self.data.name[8..11]);
|
let ext_str = String::from_utf8_lossy(&self.data.name[8..11]);
|
||||||
@ -168,12 +173,12 @@ impl <'a, 'b> FatDirEntry<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attributes(&self) -> FatFileAttributes {
|
pub fn attributes(&self) -> FileAttributes {
|
||||||
self.data.attrs
|
self.data.attrs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_dir(&self) -> bool {
|
pub fn is_dir(&self) -> bool {
|
||||||
self.data.attrs.contains(FatFileAttributes::DIRECTORY)
|
self.data.attrs.contains(FileAttributes::DIRECTORY)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_file(&self) -> bool {
|
pub fn is_file(&self) -> bool {
|
||||||
@ -185,58 +190,58 @@ impl <'a, 'b> FatDirEntry<'a, 'b> {
|
|||||||
if n == 0 { None } else { Some(n) }
|
if n == 0 { None } else { Some(n) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_file(&self) -> FatFile<'a, 'b> {
|
pub fn to_file(&self) -> File<'a, 'b> {
|
||||||
if self.is_dir() {
|
if self.is_dir() {
|
||||||
panic!("This is a directory");
|
panic!("This is a directory");
|
||||||
}
|
}
|
||||||
FatFile::new(self.first_cluster(), Some(self.data.size), self.fs)
|
File::new(self.first_cluster(), Some(self.data.size), self.fs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_dir(&self) -> FatDir<'a, 'b> {
|
pub fn to_dir(&self) -> Dir<'a, 'b> {
|
||||||
if !self.is_dir() {
|
if !self.is_dir() {
|
||||||
panic!("This is a file");
|
panic!("This is a file");
|
||||||
}
|
}
|
||||||
let file = FatFile::new(self.first_cluster(), None, self.fs);
|
let file = File::new(self.first_cluster(), None, self.fs);
|
||||||
FatDir::new(FatDirReader::File(file), self.fs)
|
Dir::new(DirReader::File(file), self.fs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> u64 {
|
pub fn len(&self) -> u64 {
|
||||||
self.data.size as u64
|
self.data.size as u64
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn created(&self) -> DosDateTime {
|
pub fn created(&self) -> DateTime {
|
||||||
DosDateTime::from_words(self.data.create_date, self.data.create_time_1)
|
DateTime::from_words(self.data.create_date, self.data.create_time_1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn accessed(&self) -> DosDate {
|
pub fn accessed(&self) -> Date {
|
||||||
DosDate::from_word(self.data.access_date)
|
Date::from_word(self.data.access_date)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn modified(&self) -> DosDateTime {
|
pub fn modified(&self) -> DateTime {
|
||||||
DosDateTime::from_words(self.data.modify_date, self.data.modify_time)
|
DateTime::from_words(self.data.modify_date, self.data.modify_time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> fmt::Debug for FatDirEntry<'a, 'b> {
|
impl <'a, 'b> fmt::Debug for DirEntry<'a, 'b> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
self.data.fmt(f)
|
self.data.fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FatDir<'a, 'b: 'a> {
|
pub struct Dir<'a, 'b: 'a> {
|
||||||
rdr: FatDirReader<'a, 'b>,
|
rdr: DirReader<'a, 'b>,
|
||||||
fs: FatFileSystemRef<'a, 'b>,
|
fs: FileSystemRef<'a, 'b>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> FatDir<'a, 'b> {
|
impl <'a, 'b> Dir<'a, 'b> {
|
||||||
|
|
||||||
pub(crate) fn new(rdr: FatDirReader<'a, 'b>, fs: FatFileSystemRef<'a, 'b>) -> FatDir<'a, 'b> {
|
pub(crate) fn new(rdr: DirReader<'a, 'b>, fs: FileSystemRef<'a, 'b>) -> Dir<'a, 'b> {
|
||||||
FatDir { rdr, fs }
|
Dir { rdr, fs }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> FatDirIter<'a, 'b> {
|
pub fn iter(&self) -> DirIter<'a, 'b> {
|
||||||
FatDirIter {
|
DirIter {
|
||||||
rdr: self.rdr.clone(),
|
rdr: self.rdr.clone(),
|
||||||
fs: self.fs.clone(),
|
fs: self.fs.clone(),
|
||||||
err: false,
|
err: false,
|
||||||
@ -250,7 +255,7 @@ impl <'a, 'b> FatDir<'a, 'b> {
|
|||||||
(comp, rest_opt)
|
(comp, rest_opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_entry(&mut self, name: &str) -> io::Result<FatDirEntry<'a, 'b>> {
|
fn find_entry(&mut self, name: &str) -> io::Result<DirEntry<'a, 'b>> {
|
||||||
for r in self.iter() {
|
for r in self.iter() {
|
||||||
let e = r?;
|
let e = r?;
|
||||||
if e.file_name().eq_ignore_ascii_case(name) {
|
if e.file_name().eq_ignore_ascii_case(name) {
|
||||||
@ -260,7 +265,7 @@ impl <'a, 'b> FatDir<'a, 'b> {
|
|||||||
Err(io::Error::new(ErrorKind::NotFound, "file not found"))
|
Err(io::Error::new(ErrorKind::NotFound, "file not found"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_dir(&mut self, path: &str) -> io::Result<FatDir<'a, 'b>> {
|
pub fn open_dir(&mut self, path: &str) -> io::Result<Dir<'a, 'b>> {
|
||||||
let (name, rest_opt) = Self::split_path(path);
|
let (name, rest_opt) = Self::split_path(path);
|
||||||
let e = self.find_entry(name)?;
|
let e = self.find_entry(name)?;
|
||||||
match rest_opt {
|
match rest_opt {
|
||||||
@ -269,7 +274,7 @@ impl <'a, 'b> FatDir<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_file(&mut self, path: &str) -> io::Result<FatFile<'a, 'b>> {
|
pub fn open_file(&mut self, path: &str) -> io::Result<File<'a, 'b>> {
|
||||||
let (name, rest_opt) = Self::split_path(path);
|
let (name, rest_opt) = Self::split_path(path);
|
||||||
let e = self.find_entry(name)?;
|
let e = self.find_entry(name)?;
|
||||||
match rest_opt {
|
match rest_opt {
|
||||||
@ -280,19 +285,19 @@ impl <'a, 'b> FatDir<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FatDirIter<'a, 'b: 'a> {
|
pub struct DirIter<'a, 'b: 'a> {
|
||||||
rdr: FatDirReader<'a, 'b>,
|
rdr: DirReader<'a, 'b>,
|
||||||
fs: FatFileSystemRef<'a, 'b>,
|
fs: FileSystemRef<'a, 'b>,
|
||||||
err: bool,
|
err: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> FatDirIter<'a, 'b> {
|
impl <'a, 'b> DirIter<'a, 'b> {
|
||||||
fn read_dir_entry_data(&mut self) -> io::Result<FatDirEntryData> {
|
fn read_dir_entry_data(&mut self) -> io::Result<DirEntryData> {
|
||||||
let mut name = [0; 11];
|
let mut name = [0; 11];
|
||||||
self.rdr.read(&mut name)?;
|
self.rdr.read(&mut name)?;
|
||||||
let attrs = FatFileAttributes::from_bits(self.rdr.read_u8()?).expect("invalid attributes");
|
let attrs = FileAttributes::from_bits(self.rdr.read_u8()?).expect("invalid attributes"); // FIXME
|
||||||
if attrs == FatFileAttributes::LFN {
|
if attrs == FileAttributes::LFN {
|
||||||
let mut data = FatDirLfnEntryData {
|
let mut data = DirLfnEntryData {
|
||||||
attrs, ..Default::default()
|
attrs, ..Default::default()
|
||||||
};
|
};
|
||||||
let mut cur = Cursor::new(&name);
|
let mut cur = Cursor::new(&name);
|
||||||
@ -303,9 +308,9 @@ impl <'a, 'b> FatDirIter<'a, 'b> {
|
|||||||
self.rdr.read_u16_into::<LittleEndian>(&mut data.name_1)?;
|
self.rdr.read_u16_into::<LittleEndian>(&mut data.name_1)?;
|
||||||
data.reserved_0 = self.rdr.read_u16::<LittleEndian>()?;
|
data.reserved_0 = self.rdr.read_u16::<LittleEndian>()?;
|
||||||
self.rdr.read_u16_into::<LittleEndian>(&mut data.name_2)?;
|
self.rdr.read_u16_into::<LittleEndian>(&mut data.name_2)?;
|
||||||
Ok(FatDirEntryData::Lfn(data))
|
Ok(DirEntryData::Lfn(data))
|
||||||
} else {
|
} else {
|
||||||
let data = FatDirFileEntryData {
|
let data = DirFileEntryData {
|
||||||
name,
|
name,
|
||||||
attrs,
|
attrs,
|
||||||
reserved_0: self.rdr.read_u8()?,
|
reserved_0: self.rdr.read_u8()?,
|
||||||
@ -319,13 +324,13 @@ impl <'a, 'b> FatDirIter<'a, 'b> {
|
|||||||
first_cluster_lo: self.rdr.read_u16::<LittleEndian>()?,
|
first_cluster_lo: self.rdr.read_u16::<LittleEndian>()?,
|
||||||
size: self.rdr.read_u32::<LittleEndian>()?,
|
size: self.rdr.read_u32::<LittleEndian>()?,
|
||||||
};
|
};
|
||||||
Ok(FatDirEntryData::File(data))
|
Ok(DirEntryData::File(data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> Iterator for FatDirIter<'a, 'b> {
|
impl <'a, 'b> Iterator for DirIter<'a, 'b> {
|
||||||
type Item = io::Result<FatDirEntry<'a, 'b>>;
|
type Item = io::Result<DirEntry<'a, 'b>>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if self.err {
|
if self.err {
|
||||||
@ -342,13 +347,13 @@ impl <'a, 'b> Iterator for FatDirIter<'a, 'b> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
match data {
|
match data {
|
||||||
FatDirEntryData::File(data) => {
|
DirEntryData::File(data) => {
|
||||||
// Check if this is end of dif
|
// Check if this is end of dif
|
||||||
if data.name[0] == 0 {
|
if data.name[0] == 0 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// Check if this is deleted or volume ID entry
|
// Check if this is deleted or volume ID entry
|
||||||
if data.name[0] == 0xE5 || data.attrs.contains(FatFileAttributes::VOLUME_ID) {
|
if data.name[0] == 0xE5 || data.attrs.contains(FileAttributes::VOLUME_ID) {
|
||||||
lfn_buf.clear();
|
lfn_buf.clear();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -364,13 +369,13 @@ impl <'a, 'b> Iterator for FatDirIter<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
lfn_buf.truncate(lfn_len);
|
lfn_buf.truncate(lfn_len);
|
||||||
return Some(Ok(FatDirEntry {
|
return Some(Ok(DirEntry {
|
||||||
data,
|
data,
|
||||||
lfn: lfn_buf,
|
lfn: lfn_buf,
|
||||||
fs: self.fs,
|
fs: self.fs,
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
FatDirEntryData::Lfn(data) => {
|
DirEntryData::Lfn(data) => {
|
||||||
// Check if this is deleted entry
|
// Check if this is deleted entry
|
||||||
if data.order == 0xE5 {
|
if data.order == 0xE5 {
|
||||||
lfn_buf.clear();
|
lfn_buf.clear();
|
||||||
|
16
src/file.rs
16
src/file.rs
@ -3,20 +3,20 @@ use std::io::prelude::*;
|
|||||||
use std::io::{SeekFrom, ErrorKind};
|
use std::io::{SeekFrom, ErrorKind};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use fs::FatFileSystemRef;
|
use fs::FileSystemRef;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FatFile<'a, 'b: 'a> {
|
pub struct File<'a, 'b: 'a> {
|
||||||
first_cluster: Option<u32>,
|
first_cluster: Option<u32>,
|
||||||
size: Option<u32>,
|
size: Option<u32>,
|
||||||
offset: u32,
|
offset: u32,
|
||||||
current_cluster: Option<u32>,
|
current_cluster: Option<u32>,
|
||||||
fs: FatFileSystemRef<'a, 'b>,
|
fs: FileSystemRef<'a, 'b>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> FatFile<'a, 'b> {
|
impl <'a, 'b> File<'a, 'b> {
|
||||||
pub(crate) fn new(first_cluster: Option<u32>, size: Option<u32>, fs: FatFileSystemRef<'a, 'b>) -> Self {
|
pub(crate) fn new(first_cluster: Option<u32>, size: Option<u32>, fs: FileSystemRef<'a, 'b>) -> Self {
|
||||||
FatFile {
|
File {
|
||||||
first_cluster, size, fs,
|
first_cluster, size, fs,
|
||||||
current_cluster: first_cluster,
|
current_cluster: first_cluster,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
@ -24,7 +24,7 @@ impl <'a, 'b> FatFile<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> Read for FatFile<'a, 'b> {
|
impl <'a, 'b> Read for File<'a, 'b> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
let mut buf_offset: usize = 0;
|
let mut buf_offset: usize = 0;
|
||||||
let cluster_size = self.fs.get_cluster_size();
|
let cluster_size = self.fs.get_cluster_size();
|
||||||
@ -62,7 +62,7 @@ impl <'a, 'b> Read for FatFile<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> Seek for FatFile<'a, 'b> {
|
impl <'a, 'b> Seek for File<'a, 'b> {
|
||||||
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
||||||
let new_offset = match pos {
|
let new_offset = match pos {
|
||||||
SeekFrom::Current(x) => self.offset as i64 + x,
|
SeekFrom::Current(x) => self.offset as i64 + x,
|
||||||
|
68
src/fs.rs
68
src/fs.rs
@ -6,9 +6,9 @@ use std::io::{Error, ErrorKind, SeekFrom};
|
|||||||
use std::io;
|
use std::io;
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
|
|
||||||
use file::FatFile;
|
use file::File;
|
||||||
use dir::{FatDirReader, FatDir};
|
use dir::{DirReader, Dir};
|
||||||
use table::FatClusterIterator;
|
use table::ClusterIterator;
|
||||||
|
|
||||||
// FAT implementation based on:
|
// FAT implementation based on:
|
||||||
// http://wiki.osdev.org/FAT
|
// http://wiki.osdev.org/FAT
|
||||||
@ -24,7 +24,7 @@ impl<T> ReadSeek for T where T: Read + Seek {}
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
pub(crate) struct FatBiosParameterBlock {
|
pub(crate) struct BiosParameterBlock {
|
||||||
bytes_per_sector: u16,
|
bytes_per_sector: u16,
|
||||||
sectors_per_cluster: u8,
|
sectors_per_cluster: u8,
|
||||||
reserved_sectors: u16,
|
reserved_sectors: u16,
|
||||||
@ -55,17 +55,17 @@ pub(crate) struct FatBiosParameterBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) struct FatBootRecord {
|
pub(crate) struct BootRecord {
|
||||||
bootjmp: [u8; 3],
|
bootjmp: [u8; 3],
|
||||||
oem_name: [u8; 8],
|
oem_name: [u8; 8],
|
||||||
bpb: FatBiosParameterBlock,
|
bpb: BiosParameterBlock,
|
||||||
boot_code: [u8; 448],
|
boot_code: [u8; 448],
|
||||||
boot_sig: [u8; 2],
|
boot_sig: [u8; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FatBootRecord {
|
impl Default for BootRecord {
|
||||||
fn default() -> FatBootRecord {
|
fn default() -> BootRecord {
|
||||||
FatBootRecord {
|
BootRecord {
|
||||||
bootjmp: Default::default(),
|
bootjmp: Default::default(),
|
||||||
oem_name: Default::default(),
|
oem_name: Default::default(),
|
||||||
bpb: Default::default(),
|
bpb: Default::default(),
|
||||||
@ -75,19 +75,19 @@ impl Default for FatBootRecord {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type FatFileSystemRef<'a, 'b: 'a> = &'a FatFileSystem<'b>;
|
pub(crate) type FileSystemRef<'a, 'b: 'a> = &'a FileSystem<'b>;
|
||||||
|
|
||||||
pub struct FatFileSystem<'a> {
|
pub struct FileSystem<'a> {
|
||||||
pub(crate) rdr: RefCell<&'a mut ReadSeek>,
|
pub(crate) rdr: RefCell<&'a mut ReadSeek>,
|
||||||
pub(crate) fat_type: FatType,
|
pub(crate) fat_type: FatType,
|
||||||
pub(crate) boot: FatBootRecord,
|
pub(crate) boot: BootRecord,
|
||||||
pub(crate) first_data_sector: u32,
|
pub(crate) first_data_sector: u32,
|
||||||
pub(crate) root_dir_sectors: u32,
|
pub(crate) root_dir_sectors: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a> FatFileSystem<'a> {
|
impl <'a> FileSystem<'a> {
|
||||||
|
|
||||||
pub fn new<T: ReadSeek>(mut rdr: &'a mut T) -> io::Result<FatFileSystem<'a>> {
|
pub fn new<T: ReadSeek>(mut rdr: &'a mut T) -> io::Result<FileSystem<'a>> {
|
||||||
let boot = Self::read_boot_record(&mut *rdr)?;
|
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"));
|
||||||
@ -101,7 +101,7 @@ impl <'a> FatFileSystem<'a> {
|
|||||||
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 = Self::fat_type_from_clusters(total_clusters);
|
let fat_type = Self::fat_type_from_clusters(total_clusters);
|
||||||
|
|
||||||
Ok(FatFileSystem {
|
Ok(FileSystem {
|
||||||
rdr: RefCell::new(rdr),
|
rdr: RefCell::new(rdr),
|
||||||
fat_type,
|
fat_type,
|
||||||
boot,
|
boot,
|
||||||
@ -122,19 +122,19 @@ impl <'a> FatFileSystem<'a> {
|
|||||||
String::from_utf8_lossy(&self.boot.bpb.volume_label).trim_right().to_string()
|
String::from_utf8_lossy(&self.boot.bpb.volume_label).trim_right().to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root_dir<'b>(&'b self) -> FatDir<'b, 'a> {
|
pub fn root_dir<'b>(&'b self) -> Dir<'b, 'a> {
|
||||||
let root_rdr = {
|
let root_rdr = {
|
||||||
match self.fat_type {
|
match self.fat_type {
|
||||||
FatType::Fat12 | FatType::Fat16 => FatDirReader::Root(FatSlice::from_sectors(
|
FatType::Fat12 | FatType::Fat16 => DirReader::Root(DiskSlice::from_sectors(
|
||||||
self.first_data_sector - self.root_dir_sectors, self.root_dir_sectors, self)),
|
self.first_data_sector - self.root_dir_sectors, self.root_dir_sectors, self)),
|
||||||
_ => FatDirReader::File(FatFile::new(Some(self.boot.bpb.root_dir_first_cluster), None, self)),
|
_ => DirReader::File(File::new(Some(self.boot.bpb.root_dir_first_cluster), None, self)),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
FatDir::new(root_rdr, self)
|
Dir::new(root_rdr, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_bpb(rdr: &mut Read) -> io::Result<FatBiosParameterBlock> {
|
fn read_bpb(rdr: &mut Read) -> io::Result<BiosParameterBlock> {
|
||||||
let mut bpb: FatBiosParameterBlock = Default::default();
|
let mut bpb: BiosParameterBlock = Default::default();
|
||||||
bpb.bytes_per_sector = rdr.read_u16::<LittleEndian>()?;
|
bpb.bytes_per_sector = rdr.read_u16::<LittleEndian>()?;
|
||||||
bpb.sectors_per_cluster = rdr.read_u8()?;
|
bpb.sectors_per_cluster = rdr.read_u8()?;
|
||||||
bpb.reserved_sectors = rdr.read_u16::<LittleEndian>()?;
|
bpb.reserved_sectors = rdr.read_u16::<LittleEndian>()?;
|
||||||
@ -183,8 +183,8 @@ impl <'a> FatFileSystem<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_boot_record(rdr: &mut Read) -> io::Result<FatBootRecord> {
|
fn read_boot_record(rdr: &mut Read) -> io::Result<BootRecord> {
|
||||||
let mut boot: FatBootRecord = Default::default();
|
let mut boot: BootRecord = 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 = Self::read_bpb(rdr)?;
|
boot.bpb = Self::read_bpb(rdr)?;
|
||||||
@ -214,38 +214,38 @@ impl <'a> FatFileSystem<'a> {
|
|||||||
self.offset_from_sector(self.sector_from_cluster(cluser))
|
self.offset_from_sector(self.sector_from_cluster(cluser))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn cluster_iter<'b>(&'b self, cluster: u32) -> iter::Chain<iter::Once<io::Result<u32>>, FatClusterIterator<'b, 'a>> {
|
pub(crate) fn cluster_iter<'b>(&'b self, cluster: u32) -> iter::Chain<iter::Once<io::Result<u32>>, ClusterIterator<'b, 'a>> {
|
||||||
let bytes_per_sector = self.boot.bpb.bytes_per_sector as u64;
|
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 fat_offset = self.boot.bpb.reserved_sectors as u64 * bytes_per_sector;
|
||||||
let sectors_per_fat =
|
let sectors_per_fat =
|
||||||
if self.boot.bpb.sectors_per_fat_16 == 0 { self.boot.bpb.sectors_per_fat_32 }
|
if self.boot.bpb.sectors_per_fat_16 == 0 { self.boot.bpb.sectors_per_fat_32 }
|
||||||
else { self.boot.bpb.sectors_per_fat_16 as u32 };
|
else { self.boot.bpb.sectors_per_fat_16 as u32 };
|
||||||
let fat_size = sectors_per_fat as u64 * bytes_per_sector;
|
let fat_size = sectors_per_fat as u64 * bytes_per_sector;
|
||||||
let fat_slice = FatSlice::new(fat_offset, fat_size, self);
|
let disk_slice = DiskSlice::new(fat_offset, fat_size, self);
|
||||||
FatClusterIterator::new(fat_slice, self.fat_type, cluster)
|
ClusterIterator::new(disk_slice, self.fat_type, cluster)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct FatSlice<'a, 'b: 'a> {
|
pub(crate) struct DiskSlice<'a, 'b: 'a> {
|
||||||
begin: u64,
|
begin: u64,
|
||||||
size: u64,
|
size: u64,
|
||||||
offset: u64,
|
offset: u64,
|
||||||
fs: &'a FatFileSystem<'b>,
|
fs: &'a FileSystem<'b>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> FatSlice<'a, 'b> {
|
impl <'a, 'b> DiskSlice<'a, 'b> {
|
||||||
pub(crate) fn new(begin: u64, size: u64, fs: FatFileSystemRef<'a, 'b>) -> Self {
|
pub(crate) fn new(begin: u64, size: u64, fs: FileSystemRef<'a, 'b>) -> Self {
|
||||||
FatSlice { begin, size, fs, offset: 0 }
|
DiskSlice { begin, size, fs, offset: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_sectors(first_sector: u32, sectors_count: u32, fs: FatFileSystemRef<'a, 'b>) -> Self {
|
pub(crate) fn from_sectors(first_sector: u32, sectors_count: u32, fs: FileSystemRef<'a, 'b>) -> Self {
|
||||||
let bytes_per_sector = fs.boot.bpb.bytes_per_sector as u64;
|
let bytes_per_sector = fs.boot.bpb.bytes_per_sector as u64;
|
||||||
Self::new(first_sector as u64 * bytes_per_sector, sectors_count as u64 * bytes_per_sector, fs)
|
Self::new(first_sector as u64 * bytes_per_sector, sectors_count as u64 * bytes_per_sector, fs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> Read for FatSlice<'a, 'b> {
|
impl <'a, 'b> Read for DiskSlice<'a, 'b> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
let offset = self.begin + self.offset;
|
let offset = self.begin + self.offset;
|
||||||
let read_size = cmp::min((self.size - self.offset) as usize, buf.len());
|
let read_size = cmp::min((self.size - self.offset) as usize, buf.len());
|
||||||
@ -257,7 +257,7 @@ impl <'a, 'b> Read for FatSlice<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> Seek for FatSlice<'a, 'b> {
|
impl <'a, 'b> Seek for DiskSlice<'a, 'b> {
|
||||||
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
||||||
let new_offset = match pos {
|
let new_offset = match pos {
|
||||||
SeekFrom::Current(x) => self.offset as i64 + x,
|
SeekFrom::Current(x) => self.offset as i64 + x,
|
||||||
|
16
src/table.rs
16
src/table.rs
@ -1,6 +1,6 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
use fs::{FatType, FatSlice, ReadSeek};
|
use fs::{FatType, DiskSlice, ReadSeek};
|
||||||
use core::iter;
|
use core::iter;
|
||||||
|
|
||||||
fn get_next_cluster(rdr: &mut ReadSeek, fat_type: FatType, cluster: u32) -> io::Result<Option<u32>> {
|
fn get_next_cluster(rdr: &mut ReadSeek, fat_type: FatType, cluster: u32) -> io::Result<Option<u32>> {
|
||||||
@ -50,17 +50,17 @@ fn get_next_cluster_32(rdr: &mut ReadSeek, cluster: u32) -> io::Result<Option<u3
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct FatClusterIterator<'a, 'b: 'a> {
|
pub(crate) struct ClusterIterator<'a, 'b: 'a> {
|
||||||
rdr: FatSlice<'a, 'b>,
|
rdr: DiskSlice<'a, 'b>,
|
||||||
fat_type: FatType,
|
fat_type: FatType,
|
||||||
cluster: Option<u32>,
|
cluster: Option<u32>,
|
||||||
err: bool,
|
err: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> FatClusterIterator<'a, 'b> {
|
impl <'a, 'b> ClusterIterator<'a, 'b> {
|
||||||
pub(crate) fn new(rdr: FatSlice<'a, 'b>, fat_type: FatType, cluster: u32)
|
pub(crate) fn new(rdr: DiskSlice<'a, 'b>, fat_type: FatType, cluster: u32)
|
||||||
-> iter::Chain<iter::Once<io::Result<u32>>, FatClusterIterator<'a, 'b>> {
|
-> iter::Chain<iter::Once<io::Result<u32>>, ClusterIterator<'a, 'b>> {
|
||||||
let iter = FatClusterIterator {
|
let iter = ClusterIterator {
|
||||||
rdr: rdr,
|
rdr: rdr,
|
||||||
fat_type: fat_type,
|
fat_type: fat_type,
|
||||||
cluster: Some(cluster),
|
cluster: Some(cluster),
|
||||||
@ -70,7 +70,7 @@ impl <'a, 'b> FatClusterIterator<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, 'b> Iterator for FatClusterIterator<'a, 'b> {
|
impl <'a, 'b> Iterator for ClusterIterator<'a, 'b> {
|
||||||
type Item = io::Result<u32>;
|
type Item = io::Result<u32>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
extern crate fatfs;
|
extern crate fatfs;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs;
|
||||||
use std::io::{BufReader, SeekFrom};
|
use std::io::{BufReader, SeekFrom};
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use fatfs::{FatFileSystem, FatType, FatDirEntry};
|
use fatfs::{FileSystem, FatType, DirEntry};
|
||||||
|
|
||||||
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";
|
||||||
const FAT16_IMG: &str = "resources/fat16.img";
|
const FAT16_IMG: &str = "resources/fat16.img";
|
||||||
const FAT32_IMG: &str = "resources/fat32.img";
|
const FAT32_IMG: &str = "resources/fat32.img";
|
||||||
|
|
||||||
fn call_with_fs(f: &Fn(FatFileSystem) -> (), filename: &str) {
|
fn call_with_fs(f: &Fn(FileSystem) -> (), filename: &str) {
|
||||||
let file = File::open(filename).unwrap();
|
let file = fs::File::open(filename).unwrap();
|
||||||
let mut buf_rdr = BufReader::new(file);
|
let mut buf_rdr = BufReader::new(file);
|
||||||
let fs = FatFileSystem::new(&mut buf_rdr).unwrap();
|
let fs = FileSystem::new(&mut buf_rdr).unwrap();
|
||||||
f(fs);
|
f(fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_root_dir(fs: FatFileSystem) {
|
fn test_root_dir(fs: FileSystem) {
|
||||||
let root_dir = fs.root_dir();
|
let root_dir = fs.root_dir();
|
||||||
let entries = root_dir.iter().map(|r| r.unwrap()).collect::<Vec<FatDirEntry>>();
|
let entries = root_dir.iter().map(|r| r.unwrap()).collect::<Vec<DirEntry>>();
|
||||||
let short_names = entries.iter().map(|e| e.short_file_name()).collect::<Vec<String>>();
|
let short_names = entries.iter().map(|e| e.short_file_name()).collect::<Vec<String>>();
|
||||||
assert_eq!(short_names, ["LONG.TXT", "SHORT.TXT", "VERY", "VERY-L~1"]);
|
assert_eq!(short_names, ["LONG.TXT", "SHORT.TXT", "VERY", "VERY-L~1"]);
|
||||||
let names = entries.iter().map(|e| e.file_name()).collect::<Vec<String>>();
|
let names = entries.iter().map(|e| e.file_name()).collect::<Vec<String>>();
|
||||||
@ -46,7 +46,7 @@ fn test_root_dir_fat32() {
|
|||||||
call_with_fs(&test_root_dir, FAT32_IMG)
|
call_with_fs(&test_root_dir, FAT32_IMG)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_read_seek_short_file(fs: FatFileSystem) {
|
fn test_read_seek_short_file(fs: FileSystem) {
|
||||||
let mut root_dir = fs.root_dir();
|
let mut root_dir = fs.root_dir();
|
||||||
let mut short_file = root_dir.open_file("short.txt").unwrap();
|
let mut short_file = root_dir.open_file("short.txt").unwrap();
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
@ -74,7 +74,7 @@ fn test_read_seek_short_file_fat32() {
|
|||||||
call_with_fs(&test_read_seek_short_file, FAT32_IMG)
|
call_with_fs(&test_read_seek_short_file, FAT32_IMG)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_read_long_file(fs: FatFileSystem) {
|
fn test_read_long_file(fs: FileSystem) {
|
||||||
let mut root_dir = fs.root_dir();
|
let mut root_dir = fs.root_dir();
|
||||||
let mut long_file = root_dir.open_file("long.txt").unwrap();
|
let mut long_file = root_dir.open_file("long.txt").unwrap();
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
@ -103,7 +103,7 @@ fn test_read_long_file_fat32() {
|
|||||||
call_with_fs(&test_read_long_file, FAT32_IMG)
|
call_with_fs(&test_read_long_file, FAT32_IMG)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_get_dir_by_path(fs: FatFileSystem) {
|
fn test_get_dir_by_path(fs: FileSystem) {
|
||||||
let mut root_dir = fs.root_dir();
|
let mut root_dir = fs.root_dir();
|
||||||
let dir = root_dir.open_dir("very/long/path/").unwrap();
|
let dir = root_dir.open_dir("very/long/path/").unwrap();
|
||||||
let names = dir.iter().map(|r| r.unwrap().file_name()).collect::<Vec<String>>();
|
let names = dir.iter().map(|r| r.unwrap().file_name()).collect::<Vec<String>>();
|
||||||
@ -125,7 +125,7 @@ fn test_get_dir_by_path_fat32() {
|
|||||||
call_with_fs(&test_get_dir_by_path, FAT32_IMG)
|
call_with_fs(&test_get_dir_by_path, FAT32_IMG)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_get_file_by_path(fs: FatFileSystem) {
|
fn test_get_file_by_path(fs: FileSystem) {
|
||||||
let mut root_dir = fs.root_dir();
|
let mut root_dir = fs.root_dir();
|
||||||
let mut file = root_dir.open_file("very/long/path/test.txt").unwrap();
|
let mut file = root_dir.open_file("very/long/path/test.txt").unwrap();
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
@ -153,7 +153,7 @@ fn test_get_file_by_path_fat32() {
|
|||||||
call_with_fs(&test_get_file_by_path, FAT32_IMG)
|
call_with_fs(&test_get_file_by_path, FAT32_IMG)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_volume_metadata(fs: FatFileSystem, fat_type: FatType) {
|
fn test_volume_metadata(fs: FileSystem, fat_type: FatType) {
|
||||||
assert_eq!(fs.volume_id(), 0x12345678);
|
assert_eq!(fs.volume_id(), 0x12345678);
|
||||||
assert_eq!(fs.volume_label(), "Test!");
|
assert_eq!(fs.volume_label(), "Test!");
|
||||||
assert_eq!(fs.fat_type(), fat_type);
|
assert_eq!(fs.fat_type(), fat_type);
|
||||||
|
Loading…
Reference in New Issue
Block a user