forked from M-Labs/rust-fatfs
Fix multiple corner cases and simplify code.
This commit is contained in:
parent
13dd50bf61
commit
0c6e9aec5b
28
src/dir.rs
28
src/dir.rs
@ -74,7 +74,7 @@ pub(crate) struct DirFileEntryData {
|
|||||||
modify_time: u16,
|
modify_time: u16,
|
||||||
modify_date: u16,
|
modify_date: u16,
|
||||||
first_cluster_lo: u16,
|
first_cluster_lo: u16,
|
||||||
pub(crate) size: u32,
|
size: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DirFileEntryData {
|
impl DirFileEntryData {
|
||||||
@ -93,6 +93,10 @@ impl DirFileEntryData {
|
|||||||
self.size
|
self.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_size(&mut self, size: u32) {
|
||||||
|
self.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_dir(&self) -> bool {
|
pub fn is_dir(&self) -> bool {
|
||||||
self.attrs.contains(FileAttributes::DIRECTORY)
|
self.attrs.contains(FileAttributes::DIRECTORY)
|
||||||
}
|
}
|
||||||
@ -107,7 +111,7 @@ impl DirFileEntryData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn serialize(&self, wrt: &mut Write) -> io::Result<()> {
|
pub(crate) fn serialize(&self, wrt: &mut Write) -> io::Result<()> {
|
||||||
wrt.write(&self.name)?;
|
wrt.write_all(&self.name)?;
|
||||||
wrt.write_u8(self.attrs.bits())?;
|
wrt.write_u8(self.attrs.bits())?;
|
||||||
wrt.write_u8(self.reserved_0)?;
|
wrt.write_u8(self.reserved_0)?;
|
||||||
wrt.write_u8(self.create_time_0)?;
|
wrt.write_u8(self.create_time_0)?;
|
||||||
@ -150,7 +154,7 @@ pub struct Date {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Date {
|
impl Date {
|
||||||
pub(crate) fn from_word(dos_date: u16) -> Self {
|
pub(crate) fn from_u16(dos_date: u16) -> Self {
|
||||||
let (year, month, day) = ((dos_date >> 9) + 1980, (dos_date >> 5) & 0xF, dos_date & 0x1F);
|
let (year, month, day) = ((dos_date >> 9) + 1980, (dos_date >> 5) & 0xF, dos_date & 0x1F);
|
||||||
Date { year, month, day }
|
Date { year, month, day }
|
||||||
}
|
}
|
||||||
@ -168,7 +172,7 @@ pub struct Time {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Time {
|
impl Time {
|
||||||
pub(crate) fn from_word(dos_time: u16) -> Self {
|
pub(crate) fn from_u16(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);
|
||||||
Time { hour, min, sec }
|
Time { hour, min, sec }
|
||||||
}
|
}
|
||||||
@ -185,10 +189,10 @@ pub struct DateTime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DateTime {
|
impl DateTime {
|
||||||
pub(crate) fn from_words(dos_date: u16, dos_time: u16) -> Self {
|
pub(crate) fn from_u16(dos_date: u16, dos_time: u16) -> Self {
|
||||||
DateTime {
|
DateTime {
|
||||||
date: Date::from_word(dos_date),
|
date: Date::from_u16(dos_date),
|
||||||
time: Time::from_word(dos_time),
|
time: Time::from_u16(dos_time),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,11 +260,11 @@ impl <'a, 'b> DirEntry<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_dir(&self) -> bool {
|
pub fn is_dir(&self) -> bool {
|
||||||
self.data.attrs.contains(FileAttributes::DIRECTORY)
|
self.data.is_dir()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_file(&self) -> bool {
|
pub fn is_file(&self) -> bool {
|
||||||
!self.is_dir()
|
self.data.is_file()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn first_cluster(&self) -> Option<u32> {
|
pub(crate) fn first_cluster(&self) -> Option<u32> {
|
||||||
@ -295,15 +299,15 @@ impl <'a, 'b> DirEntry<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn created(&self) -> DateTime {
|
pub fn created(&self) -> DateTime {
|
||||||
DateTime::from_words(self.data.create_date, self.data.create_time_1)
|
DateTime::from_u16(self.data.create_date, self.data.create_time_1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn accessed(&self) -> Date {
|
pub fn accessed(&self) -> Date {
|
||||||
Date::from_word(self.data.access_date)
|
Date::from_u16(self.data.access_date)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn modified(&self) -> DateTime {
|
pub fn modified(&self) -> DateTime {
|
||||||
DateTime::from_words(self.data.modify_date, self.data.modify_time)
|
DateTime::from_u16(self.data.modify_date, self.data.modify_time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
120
src/file.rs
120
src/file.rs
@ -8,11 +8,15 @@ use dir::{FileEntryInfo, DateTime};
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct File<'a, 'b: 'a> {
|
pub struct File<'a, 'b: 'a> {
|
||||||
|
// Note first_cluster is None if file is empty
|
||||||
first_cluster: Option<u32>,
|
first_cluster: Option<u32>,
|
||||||
// Note: if offset points between clusters current_cluster is the previous cluster
|
// Note: if offset points between clusters current_cluster is the previous cluster
|
||||||
current_cluster: Option<u32>,
|
current_cluster: Option<u32>,
|
||||||
|
// current position in this file
|
||||||
offset: u32,
|
offset: u32,
|
||||||
|
// file dir entry - None for root dir
|
||||||
entry: Option<FileEntryInfo>,
|
entry: Option<FileEntryInfo>,
|
||||||
|
// should file dir entry be flushed?
|
||||||
entry_dirty: bool,
|
entry_dirty: bool,
|
||||||
fs: FileSystemRef<'a, 'b>,
|
fs: FileSystemRef<'a, 'b>,
|
||||||
}
|
}
|
||||||
@ -31,7 +35,7 @@ impl <'a, 'b> File<'a, 'b> {
|
|||||||
match self.entry {
|
match self.entry {
|
||||||
Some(ref mut e) => {
|
Some(ref mut e) => {
|
||||||
if self.offset > e.data.size() {
|
if self.offset > e.data.size() {
|
||||||
e.data.size = self.offset;
|
e.data.set_size(self.offset);
|
||||||
self.entry_dirty = true;
|
self.entry_dirty = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -42,11 +46,11 @@ impl <'a, 'b> File<'a, 'b> {
|
|||||||
pub fn truncate(&mut self) -> io::Result<()> {
|
pub fn truncate(&mut self) -> io::Result<()> {
|
||||||
match self.entry {
|
match self.entry {
|
||||||
Some(ref mut e) => {
|
Some(ref mut e) => {
|
||||||
if e.data.size == self.offset {
|
if e.data.size() == self.offset {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
e.data.size = self.offset;
|
e.data.set_size(self.offset);
|
||||||
if self.offset == 0 {
|
if self.offset == 0 {
|
||||||
e.data.set_first_cluster(None);
|
e.data.set_first_cluster(None);
|
||||||
}
|
}
|
||||||
@ -55,15 +59,21 @@ impl <'a, 'b> File<'a, 'b> {
|
|||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
if self.offset > 0 {
|
if self.offset > 0 {
|
||||||
self.fs.cluster_iter(self.current_cluster.unwrap()).truncate()
|
debug_assert!(self.current_cluster.is_some());
|
||||||
|
self.fs.cluster_iter(self.current_cluster.unwrap()).truncate() // safe
|
||||||
} else {
|
} else {
|
||||||
self.fs.cluster_iter(self.first_cluster.unwrap()).free()?;
|
debug_assert!(self.current_cluster.is_none());
|
||||||
|
match self.first_cluster {
|
||||||
|
Some(n) => self.fs.cluster_iter(n).free()?,
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
self.first_cluster = None;
|
self.first_cluster = None;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn global_pos(&self) -> Option<u64> {
|
pub(crate) fn global_pos(&self) -> Option<u64> {
|
||||||
|
// Returns current position relative to filesystem start
|
||||||
// Note: when between clusters it returns position after previous cluster
|
// Note: when between clusters it returns position after previous cluster
|
||||||
match self.current_cluster {
|
match self.current_cluster {
|
||||||
Some(n) => {
|
Some(n) => {
|
||||||
@ -78,11 +88,13 @@ impl <'a, 'b> File<'a, 'b> {
|
|||||||
|
|
||||||
pub(crate) fn flush_dir_entry(&self) -> io::Result<()> {
|
pub(crate) fn flush_dir_entry(&self) -> io::Result<()> {
|
||||||
if self.entry_dirty {
|
if self.entry_dirty {
|
||||||
self.entry.iter().next().unwrap().write(self.fs)
|
match self.entry {
|
||||||
} else {
|
Some(ref e) => e.write(self.fs)?,
|
||||||
Ok(())
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_modified(&mut self, date_time: DateTime) {
|
pub fn set_modified(&mut self, date_time: DateTime) {
|
||||||
match self.entry {
|
match self.entry {
|
||||||
@ -98,7 +110,7 @@ impl <'a, 'b> File<'a, 'b> {
|
|||||||
match self.entry {
|
match self.entry {
|
||||||
Some(ref e) => {
|
Some(ref e) => {
|
||||||
if e.data.is_file() {
|
if e.data.is_file() {
|
||||||
Some((e.data.size - self.offset) as usize)
|
Some((e.data.size() - self.offset) as usize)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -127,9 +139,7 @@ impl<'a, 'b> Drop for File<'a, 'b> {
|
|||||||
|
|
||||||
impl<'a, 'b> Read for File<'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 cluster_size = self.fs.get_cluster_size();
|
let cluster_size = self.fs.get_cluster_size();
|
||||||
loop {
|
|
||||||
let current_cluster_opt = if self.offset % cluster_size == 0 {
|
let current_cluster_opt = if self.offset % cluster_size == 0 {
|
||||||
// next cluster
|
// next cluster
|
||||||
match self.current_cluster {
|
match self.current_cluster {
|
||||||
@ -148,49 +158,44 @@ impl<'a, 'b> Read for File<'a, 'b> {
|
|||||||
};
|
};
|
||||||
let current_cluster = match current_cluster_opt {
|
let current_cluster = match current_cluster_opt {
|
||||||
Some(n) => n,
|
Some(n) => n,
|
||||||
None => break,
|
None => return Ok(0),
|
||||||
};
|
};
|
||||||
let offset_in_cluster = self.offset % cluster_size;
|
let offset_in_cluster = self.offset % cluster_size;
|
||||||
let bytes_left_in_cluster = (cluster_size - offset_in_cluster) as usize;
|
let bytes_left_in_cluster = (cluster_size - offset_in_cluster) as usize;
|
||||||
let bytes_left_in_file = self.bytes_left_in_file().unwrap_or(bytes_left_in_cluster);
|
let bytes_left_in_file = self.bytes_left_in_file().unwrap_or(bytes_left_in_cluster);
|
||||||
let bytes_left_in_buf = buf.len() - buf_offset;
|
let read_size = cmp::min(cmp::min(buf.len(), bytes_left_in_cluster), bytes_left_in_file);
|
||||||
let read_size = cmp::min(cmp::min(bytes_left_in_buf, bytes_left_in_cluster), bytes_left_in_file);
|
|
||||||
if read_size == 0 {
|
if read_size == 0 {
|
||||||
break;
|
return Ok(0);
|
||||||
}
|
}
|
||||||
//println!("read c {} n {}", current_cluster, read_size);
|
//println!("read c {} n {}", current_cluster, read_size);
|
||||||
let offset_in_fs = self.fs.offset_from_cluster(current_cluster) + (offset_in_cluster as u64);
|
let offset_in_fs = self.fs.offset_from_cluster(current_cluster) + (offset_in_cluster as u64);
|
||||||
let read_bytes = {
|
let read_bytes = {
|
||||||
let mut disk = self.fs.disk.borrow_mut();
|
let mut disk = self.fs.disk.borrow_mut();
|
||||||
disk.seek(SeekFrom::Start(offset_in_fs))?;
|
disk.seek(SeekFrom::Start(offset_in_fs))?;
|
||||||
disk.read(&mut buf[buf_offset..buf_offset+read_size])?
|
disk.read(&mut buf[..read_size])?
|
||||||
};
|
};
|
||||||
if read_bytes == 0 {
|
if read_bytes == 0 {
|
||||||
break;
|
return Ok(0);
|
||||||
}
|
}
|
||||||
self.offset += read_bytes as u32;
|
self.offset += read_bytes as u32;
|
||||||
self.current_cluster = Some(current_cluster);
|
self.current_cluster = Some(current_cluster);
|
||||||
buf_offset += read_bytes;
|
Ok(read_bytes)
|
||||||
}
|
|
||||||
Ok(buf_offset)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> Write for File<'a, 'b> {
|
impl<'a, 'b> Write for File<'a, 'b> {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
let mut buf_offset: usize = 0;
|
|
||||||
let cluster_size = self.fs.get_cluster_size();
|
let cluster_size = self.fs.get_cluster_size();
|
||||||
loop {
|
|
||||||
let offset_in_cluster = self.offset % cluster_size;
|
let offset_in_cluster = self.offset % cluster_size;
|
||||||
let bytes_left_in_cluster = (cluster_size - offset_in_cluster) as usize;
|
let bytes_left_in_cluster = (cluster_size - offset_in_cluster) as usize;
|
||||||
let bytes_left_in_buf = buf.len() - buf_offset;
|
let write_size = cmp::min(buf.len(), bytes_left_in_cluster);
|
||||||
let write_size = cmp::min(bytes_left_in_buf, bytes_left_in_cluster);
|
|
||||||
//println!("write {:?}", write_size);
|
//println!("write {:?}", write_size);
|
||||||
|
// Exit early if we are going to write no data
|
||||||
if write_size == 0 {
|
if write_size == 0 {
|
||||||
break;
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
// Get cluster for write possibly allocating new one
|
||||||
let current_cluster_opt = if self.offset % cluster_size == 0 {
|
let current_cluster = if self.offset % cluster_size == 0 {
|
||||||
// next cluster
|
// next cluster
|
||||||
let next_cluster = match self.current_cluster {
|
let next_cluster = match self.current_cluster {
|
||||||
None => self.first_cluster,
|
None => self.first_cluster,
|
||||||
@ -204,37 +209,36 @@ impl<'a, 'b> Write for File<'a, 'b> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
match next_cluster {
|
match next_cluster {
|
||||||
Some(_) => next_cluster,
|
Some(n) => n,
|
||||||
None => {
|
None => {
|
||||||
|
// end of chain reached - allocate new cluster
|
||||||
let new_cluster = self.fs.alloc_cluster(self.current_cluster)?;
|
let new_cluster = self.fs.alloc_cluster(self.current_cluster)?;
|
||||||
if self.first_cluster.is_none() {
|
if self.first_cluster.is_none() {
|
||||||
self.set_first_cluster(new_cluster);
|
self.set_first_cluster(new_cluster);
|
||||||
}
|
}
|
||||||
Some(new_cluster)
|
new_cluster
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.current_cluster
|
// self.current_cluster should be a valid cluster
|
||||||
};
|
match self.current_cluster {
|
||||||
let current_cluster = match current_cluster_opt {
|
|
||||||
Some(n) => n,
|
Some(n) => n,
|
||||||
None => panic!("Offset inside cluster but no cluster allocated"), // FIXME
|
None => panic!("Offset inside cluster but no cluster allocated"),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let offset_in_fs = self.fs.offset_from_cluster(current_cluster) + (offset_in_cluster as u64);
|
let offset_in_fs = self.fs.offset_from_cluster(current_cluster) + (offset_in_cluster as u64);
|
||||||
let written_bytes = {
|
let written_bytes = {
|
||||||
let mut disk = self.fs.disk.borrow_mut();
|
let mut disk = self.fs.disk.borrow_mut();
|
||||||
disk.seek(SeekFrom::Start(offset_in_fs))?;
|
disk.seek(SeekFrom::Start(offset_in_fs))?;
|
||||||
disk.write(&buf[buf_offset..buf_offset+write_size])?
|
disk.write(&buf[..write_size])?
|
||||||
};
|
};
|
||||||
if written_bytes == 0 {
|
if written_bytes == 0 {
|
||||||
break;
|
return Ok(0);
|
||||||
}
|
}
|
||||||
self.offset += written_bytes as u32;
|
self.offset += written_bytes as u32;
|
||||||
self.current_cluster = Some(current_cluster);
|
self.current_cluster = Some(current_cluster);
|
||||||
buf_offset += written_bytes;
|
|
||||||
}
|
|
||||||
self.update_size();
|
self.update_size();
|
||||||
Ok(buf_offset)
|
Ok(written_bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
@ -246,33 +250,49 @@ impl<'a, 'b> Write for File<'a, 'b> {
|
|||||||
|
|
||||||
impl<'a, 'b> Seek for File<'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 mut new_pos = match pos {
|
||||||
SeekFrom::Current(x) => self.offset as i64 + x,
|
SeekFrom::Current(x) => self.offset as i64 + x,
|
||||||
SeekFrom::Start(x) => x as i64,
|
SeekFrom::Start(x) => x as i64,
|
||||||
SeekFrom::End(x) => self.entry.iter().next().expect("cannot seek from end if size is unknown").data.size() as i64 + x,
|
SeekFrom::End(x) => self.entry.iter().next().expect("cannot seek from end if size is unknown").data.size() as i64 + x,
|
||||||
};
|
};
|
||||||
if new_offset < 0 {
|
if new_pos < 0 {
|
||||||
return Err(io::Error::new(ErrorKind::InvalidInput, "invalid seek"));
|
return Err(io::Error::new(ErrorKind::InvalidInput, "invalid seek"));
|
||||||
}
|
}
|
||||||
|
new_pos = match self.entry {
|
||||||
|
Some(ref e) => cmp::min(new_pos, e.data.size() as i64),
|
||||||
|
_ => new_pos,
|
||||||
|
};
|
||||||
let cluster_size = self.fs.get_cluster_size();
|
let cluster_size = self.fs.get_cluster_size();
|
||||||
let cluster_count = ((new_offset + cluster_size as i64 - 1) / cluster_size as i64 - 1) as isize;
|
let new_cluster = if new_pos == 0 {
|
||||||
let new_cluster = if cluster_count == -1 {
|
|
||||||
None
|
None
|
||||||
} else if cluster_count == 0 {
|
|
||||||
self.first_cluster
|
|
||||||
} else {
|
} else {
|
||||||
|
// get number of clusters to seek (favoring previous cluster in corner case)
|
||||||
|
let cluster_count = ((new_pos - 1) / cluster_size as i64) as isize;
|
||||||
match self.first_cluster {
|
match self.first_cluster {
|
||||||
Some(n) => {
|
Some(n) => {
|
||||||
match self.fs.cluster_iter(n).skip(cluster_count as usize - 1).next() {
|
let mut cluster = n;
|
||||||
|
let mut iter = self.fs.cluster_iter(n);
|
||||||
|
for i in 0..cluster_count {
|
||||||
|
cluster = match iter.next() {
|
||||||
Some(Err(err)) => return Err(err),
|
Some(Err(err)) => return Err(err),
|
||||||
Some(Ok(n)) => Some(n),
|
Some(Ok(n)) => n,
|
||||||
None => None,
|
None => {
|
||||||
}
|
// chain ends before new position - seek to end of last cluster
|
||||||
|
new_pos = (i + 1) as i64 * cluster_size as i64;
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Some(cluster)
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
// empty file - always seek to 0
|
||||||
|
new_pos = 0;
|
||||||
|
None
|
||||||
},
|
},
|
||||||
None => None,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.offset = new_offset as u32;
|
self.offset = new_pos as u32;
|
||||||
self.current_cluster = new_cluster;
|
self.current_cluster = new_cluster;
|
||||||
Ok(self.offset as u64)
|
Ok(self.offset as u64)
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ fn test_read_seek_short_file(fs: FileSystem) {
|
|||||||
short_file.read_exact(&mut buf2).unwrap();
|
short_file.read_exact(&mut buf2).unwrap();
|
||||||
assert_eq!(str::from_utf8(&buf2).unwrap(), &TEST_TEXT[5..10]);
|
assert_eq!(str::from_utf8(&buf2).unwrap(), &TEST_TEXT[5..10]);
|
||||||
|
|
||||||
assert_eq!(short_file.seek(SeekFrom::Start(1000)).unwrap(), 1000);
|
assert_eq!(short_file.seek(SeekFrom::Start(1000)).unwrap(), TEST_TEXT.len() as u64);
|
||||||
let mut buf2 = [0; 5];
|
let mut buf2 = [0; 5];
|
||||||
assert_eq!(short_file.read(&mut buf2).unwrap(), 0);
|
assert_eq!(short_file.read(&mut buf2).unwrap(), 0);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ fn test_write_short_file(fs: FileSystem) {
|
|||||||
let mut root_dir = fs.root_dir();
|
let mut root_dir = fs.root_dir();
|
||||||
let mut file = root_dir.open_file("short.txt").expect("open file");
|
let mut file = root_dir.open_file("short.txt").expect("open file");
|
||||||
file.truncate().unwrap();
|
file.truncate().unwrap();
|
||||||
assert_eq!(TEST_STR.len(), file.write(&TEST_STR.as_bytes()).unwrap());
|
file.write_all(&TEST_STR.as_bytes()).unwrap();
|
||||||
file.seek(io::SeekFrom::Start(0)).unwrap();
|
file.seek(io::SeekFrom::Start(0)).unwrap();
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
file.read_to_end(&mut buf).unwrap();
|
file.read_to_end(&mut buf).unwrap();
|
||||||
@ -60,7 +60,7 @@ fn test_write_long_file(fs: FileSystem) {
|
|||||||
let mut file = root_dir.open_file("long.txt").expect("open file");
|
let mut file = root_dir.open_file("long.txt").expect("open file");
|
||||||
file.truncate().unwrap();
|
file.truncate().unwrap();
|
||||||
let test_str = TEST_STR.repeat(100);
|
let test_str = TEST_STR.repeat(100);
|
||||||
assert_eq!(test_str.len(), file.write(&test_str.as_bytes()).unwrap());
|
file.write_all(&test_str.as_bytes()).unwrap();
|
||||||
file.seek(io::SeekFrom::Start(0)).unwrap();
|
file.seek(io::SeekFrom::Start(0)).unwrap();
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
file.read_to_end(&mut buf).unwrap();
|
file.read_to_end(&mut buf).unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user