Skip to content

Commit 0557c3e

Browse files
committed
A new IO-Layer
1 parent 85f06e0 commit 0557c3e

File tree

4 files changed

+97
-45
lines changed

4 files changed

+97
-45
lines changed

Diff for: src/dir.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::dir_entry::{SFN_PADDING, SFN_SIZE};
1515
use crate::error::{Error, IoError};
1616
use crate::file::File;
1717
use crate::fs::{DiskSlice, FileSystem, FsIoAdapter, OemCpConverter, ReadWriteSeek};
18-
use crate::io::{self, IoBase, Read, Seek, SeekFrom, Write};
18+
use crate::io::{self, IoBase, ReadFile, Seek, SeekFrom, WriteFile};
1919
use crate::time::TimeProvider;
2020

2121
const LFN_PADDING: u16 = 0xFFFF;
@@ -55,7 +55,7 @@ impl<IO: ReadWriteSeek, TP, OCC> IoBase for DirRawStream<'_, IO, TP, OCC> {
5555
type Error = Error<IO::Error>;
5656
}
5757

58-
impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> Read for DirRawStream<'_, IO, TP, OCC> {
58+
impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> ReadFile for DirRawStream<'_, IO, TP, OCC> {
5959
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
6060
match self {
6161
DirRawStream::File(file) => file.read(buf),
@@ -64,7 +64,7 @@ impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> Read for DirRawStream<'_, IO, TP,
6464
}
6565
}
6666

67-
impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> Write for DirRawStream<'_, IO, TP, OCC> {
67+
impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> WriteFile for DirRawStream<'_, IO, TP, OCC> {
6868
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
6969
match self {
7070
DirRawStream::File(file) => file.write(buf),

Diff for: src/file.rs

+16-25
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::convert::TryFrom;
33
use crate::dir_entry::DirEntryEditor;
44
use crate::error::Error;
55
use crate::fs::{FileSystem, ReadWriteSeek};
6-
use crate::io::{IoBase, Read, Seek, SeekFrom, Write};
6+
use crate::io::{IoBase, ReadFile, Seek, SeekFrom, Write, WriteFile};
77
use crate::time::{Date, DateTime, TimeProvider};
88

99
const MAX_FILE_SIZE: u32 = core::u32::MAX;
@@ -254,7 +254,7 @@ impl<IO: ReadWriteSeek, TP, OCC> IoBase for File<'_, IO, TP, OCC> {
254254
type Error = Error<IO::Error>;
255255
}
256256

257-
impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> Read for File<'_, IO, TP, OCC> {
257+
impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> ReadFile for File<'_, IO, TP, OCC> {
258258
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
259259
trace!("File::read");
260260
let cluster_size = self.fs.cluster_size();
@@ -286,15 +286,10 @@ impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> Read for File<'_, IO, TP, OCC> {
286286
}
287287
trace!("read {} bytes in cluster {}", read_size, current_cluster);
288288
let offset_in_fs = self.fs.offset_from_cluster(current_cluster) + u64::from(offset_in_cluster);
289-
let read_bytes = {
290-
let mut disk = self.fs.disk.borrow_mut();
291-
disk.seek(SeekFrom::Start(offset_in_fs))?;
292-
disk.read(&mut buf[..read_size])?
293-
};
294-
if read_bytes == 0 {
295-
return Ok(0);
296-
}
297-
self.offset += read_bytes as u32;
289+
let mut disk = self.fs.disk.borrow_mut();
290+
disk.seek(SeekFrom::Start(offset_in_fs))?;
291+
disk.read_exact(&mut buf[..read_size])?;
292+
self.offset += read_size as u32;
298293
self.current_cluster = Some(current_cluster);
299294

300295
if let Some(ref mut e) = self.entry {
@@ -303,7 +298,7 @@ impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> Read for File<'_, IO, TP, OCC> {
303298
e.set_accessed(now);
304299
}
305300
}
306-
Ok(read_bytes)
301+
Ok(read_size)
307302
}
308303
}
309304

@@ -313,11 +308,11 @@ where
313308
std::io::Error: From<Error<IO::Error>>,
314309
{
315310
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
316-
Ok(Read::read(self, buf)?)
311+
Ok(ReadFile::read(self, buf)?)
317312
}
318313
}
319314

320-
impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> Write for File<'_, IO, TP, OCC> {
315+
impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> WriteFile for File<'_, IO, TP, OCC> {
321316
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
322317
trace!("File::write");
323318
let cluster_size = self.fs.cluster_size();
@@ -365,19 +360,14 @@ impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> Write for File<'_, IO, TP, OCC> {
365360
};
366361
trace!("write {} bytes in cluster {}", write_size, current_cluster);
367362
let offset_in_fs = self.fs.offset_from_cluster(current_cluster) + u64::from(offset_in_cluster);
368-
let written_bytes = {
369-
let mut disk = self.fs.disk.borrow_mut();
370-
disk.seek(SeekFrom::Start(offset_in_fs))?;
371-
disk.write(&buf[..write_size])?
372-
};
373-
if written_bytes == 0 {
374-
return Ok(0);
375-
}
363+
let mut disk = self.fs.disk.borrow_mut();
364+
disk.seek(SeekFrom::Start(offset_in_fs))?;
365+
disk.write_all(&buf[..write_size])?;
376366
// some bytes were writter - update position and optionally size
377-
self.offset += written_bytes as u32;
367+
self.offset += write_size as u32;
378368
self.current_cluster = Some(current_cluster);
379369
self.update_dir_entry_after_write();
380-
Ok(written_bytes)
370+
Ok(write_size)
381371
}
382372

383373
fn flush(&mut self) -> Result<(), Self::Error> {
@@ -391,7 +381,8 @@ where
391381
std::io::Error: From<Error<IO::Error>>,
392382
{
393383
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
394-
Ok(Write::write(self, buf)?)
384+
Write::write_all(self, buf)?;
385+
Ok(buf.len())
395386
}
396387

397388
fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {

Diff for: src/fs.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::dir::{Dir, DirRawStream};
1313
use crate::dir_entry::{DirFileEntryData, FileAttributes, SFN_PADDING, SFN_SIZE};
1414
use crate::error::Error;
1515
use crate::file::File;
16-
use crate::io::{self, IoBase, Read, ReadLeExt, Seek, SeekFrom, Write, WriteLeExt};
16+
use crate::io::{self, IoBase, Read, ReadFile, ReadLeExt, Seek, SeekFrom, Write, WriteFile, WriteLeExt};
1717
use crate::table::{
1818
alloc_cluster, count_free_clusters, format_fat, read_fat_flags, ClusterIterator, RESERVED_FAT_ENTRIES,
1919
};
@@ -699,18 +699,19 @@ impl<IO: ReadWriteSeek, TP, OCC> IoBase for FsIoAdapter<'_, IO, TP, OCC> {
699699
}
700700

701701
impl<IO: ReadWriteSeek, TP, OCC> Read for FsIoAdapter<'_, IO, TP, OCC> {
702-
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
703-
self.fs.disk.borrow_mut().read(buf)
702+
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
703+
self.fs.disk.borrow_mut().read_exact(buf)
704704
}
705705
}
706706

707707
impl<IO: ReadWriteSeek, TP, OCC> Write for FsIoAdapter<'_, IO, TP, OCC> {
708-
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
709-
let size = self.fs.disk.borrow_mut().write(buf)?;
710-
if size > 0 {
708+
fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
709+
if buf.is_empty() {
710+
Ok(())
711+
} else {
711712
self.fs.set_dirty_flag(true)?;
713+
self.fs.disk.borrow_mut().write_all(buf)
712714
}
713-
Ok(size)
714715
}
715716

716717
fn flush(&mut self) -> Result<(), Self::Error> {
@@ -801,18 +802,18 @@ impl<B, S: IoBase> IoBase for DiskSlice<B, S> {
801802
type Error = Error<S::Error>;
802803
}
803804

804-
impl<B: BorrowMut<S>, S: Read + Seek> Read for DiskSlice<B, S> {
805+
impl<B: BorrowMut<S>, S: Read + Seek> ReadFile for DiskSlice<B, S> {
805806
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
806807
let offset = self.begin + self.offset;
807808
let read_size = (buf.len() as u64).min(self.size - self.offset) as usize;
808809
self.inner.borrow_mut().seek(SeekFrom::Start(offset))?;
809-
let size = self.inner.borrow_mut().read(&mut buf[..read_size])?;
810-
self.offset += size as u64;
811-
Ok(size)
810+
self.inner.borrow_mut().read_exact(&mut buf[..read_size])?;
811+
self.offset += read_size as u64;
812+
Ok(read_size)
812813
}
813814
}
814815

815-
impl<B: BorrowMut<S>, S: Write + Seek> Write for DiskSlice<B, S> {
816+
impl<B: BorrowMut<S>, S: Write + Seek> WriteFile for DiskSlice<B, S> {
816817
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
817818
let offset = self.begin + self.offset;
818819
let write_size = (buf.len() as u64).min(self.size - self.offset) as usize;

Diff for: src/io.rs

+65-5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,28 @@ pub trait IoBase {
1313
///
1414
/// It is based on the `std::io::Read` trait.
1515
pub trait Read: IoBase {
16+
/// Read the exact number of bytes required to fill `buf`.
17+
///
18+
/// This function reads as many bytes as necessary to completely fill the specified buffer `buf`.
19+
///
20+
/// # Errors
21+
///
22+
/// If this function encounters an error for which `IoError::is_interrupted` returns true then the error is ignored
23+
/// and the operation will continue.
24+
///
25+
/// If this function encounters an end of file before completely filling the buffer, it returns an error
26+
/// instantiated by a call to `IoError::new_unexpected_eof_error`. The contents of `buf` are unspecified in this
27+
/// case.
28+
///
29+
/// If this function returns an error, it is unspecified how many bytes it has read, but it will never read more
30+
/// than would be necessary to completely fill the buffer.
31+
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::Error>;
32+
}
33+
34+
/// The `ReadFile` trait allows for reading bytes from a source.
35+
///
36+
/// It is based on the `std::io::Read` trait.
37+
pub trait ReadFile: Read {
1638
/// Pull some bytes from this source into the specified buffer, returning how many bytes were read.
1739
///
1840
/// This function does not provide any guarantees about whether it blocks waiting for data, but if an object needs
@@ -74,10 +96,42 @@ pub trait Read: IoBase {
7496
}
7597
}
7698

99+
impl<T: ReadFile> Read for T {
100+
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
101+
ReadFile::read_exact(self, buf)
102+
}
103+
}
104+
77105
/// The `Write` trait allows for writing bytes into the sink.
78106
///
79107
/// It is based on the `std::io::Write` trait.
80108
pub trait Write: IoBase {
109+
/// Attempts to write an entire buffer into this writer.
110+
///
111+
/// This method will continuously call `write` until there is no more data to be written or an error is returned.
112+
/// Errors for which `IoError::is_interrupted` method returns true are being skipped. This method will not return
113+
/// until the entire buffer has been successfully written or such an error occurs.
114+
/// If `write` returns 0 before the entire buffer has been written this method will return an error instantiated by
115+
/// a call to `IoError::new_write_zero_error`.
116+
///
117+
/// # Errors
118+
///
119+
/// This function will return the first error for which `IoError::is_interrupted` method returns false that `write`
120+
/// returns.
121+
fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error>;
122+
123+
/// Flush this output stream, ensuring that all intermediately buffered contents reach their destination.
124+
///
125+
/// # Errors
126+
///
127+
/// It is considered an error if not all bytes could be written due to I/O errors or EOF being reached.
128+
fn flush(&mut self) -> Result<(), Self::Error>;
129+
}
130+
131+
/// The `WriteFile` trait allows for writing bytes into the sink.
132+
///
133+
/// It is based on the `std::io::Write` trait.
134+
pub trait WriteFile: Write {
81135
/// Write a buffer into this writer, returning how many bytes were written.
82136
///
83137
/// # Errors
@@ -122,6 +176,16 @@ pub trait Write: IoBase {
122176
fn flush(&mut self) -> Result<(), Self::Error>;
123177
}
124178

179+
impl<T: WriteFile> Write for T {
180+
fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
181+
WriteFile::write_all(self, buf)
182+
}
183+
184+
fn flush(&mut self) -> Result<(), Self::Error> {
185+
WriteFile::flush(self)
186+
}
187+
}
188+
125189
/// Enumeration of possible methods to seek within an I/O object.
126190
///
127191
/// It is based on the `std::io::SeekFrom` enum.
@@ -201,7 +265,7 @@ impl<T> IoBase for StdIoWrapper<T> {
201265
}
202266

203267
#[cfg(feature = "std")]
204-
impl<T: std::io::Read> Read for StdIoWrapper<T> {
268+
impl<T: std::io::Read> ReadFile for StdIoWrapper<T> {
205269
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
206270
self.inner.read(buf)
207271
}
@@ -212,10 +276,6 @@ impl<T: std::io::Read> Read for StdIoWrapper<T> {
212276

213277
#[cfg(feature = "std")]
214278
impl<T: std::io::Write> Write for StdIoWrapper<T> {
215-
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
216-
self.inner.write(buf)
217-
}
218-
219279
fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
220280
self.inner.write_all(buf)
221281
}

0 commit comments

Comments
 (0)