From 892c3974d389df125daa337a75fc7def7d5f4aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Harabie=C5=84?= Date: Sat, 16 Jun 2018 17:57:29 +0200 Subject: [PATCH] Move BufStream to fscommon crate (BREAKING CHANGE) BufStream is universal and can be used with any filesystem so its place is in different crate. Also moved Partition struct from examples to fscommon::StreamSlice struct (please note constructor arguments has changed). --- Cargo.toml | 1 + examples/cat.rs | 4 +- examples/ls.rs | 4 +- examples/partition.rs | 70 ++-------------------- examples/write.rs | 4 +- src/lib.rs | 6 -- src/utils.rs | 131 ------------------------------------------ tests/read.rs | 4 +- tests/write.rs | 4 +- 9 files changed, 21 insertions(+), 207 deletions(-) delete mode 100644 src/utils.rs diff --git a/Cargo.toml b/Cargo.toml index d1d7562..46ba8da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,3 +34,4 @@ core_io = { version = "0.1", optional = true } [dev-dependencies] env_logger = "0.5" +fscommon = "0.1" diff --git a/examples/cat.rs b/examples/cat.rs index e9ea2bf..dba0411 100644 --- a/examples/cat.rs +++ b/examples/cat.rs @@ -1,10 +1,12 @@ extern crate fatfs; +extern crate fscommon; use std::env; use std::fs::File; use std::io::{self, prelude::*}; -use fatfs::{FileSystem, FsOptions, BufStream}; +use fatfs::{FileSystem, FsOptions}; +use fscommon::BufStream; fn main() -> io::Result<()> { let file = File::open("resources/fat32.img")?; diff --git a/examples/ls.rs b/examples/ls.rs index 2fdaf00..151cd4a 100644 --- a/examples/ls.rs +++ b/examples/ls.rs @@ -1,4 +1,5 @@ extern crate fatfs; +extern crate fscommon; extern crate chrono; use std::env; @@ -6,7 +7,8 @@ use std::fs::File; use std::io; use chrono::{DateTime, Local}; -use fatfs::{FileSystem, FsOptions, BufStream}; +use fatfs::{FileSystem, FsOptions}; +use fscommon::BufStream; fn format_file_size(size: u64) -> String { const KB: u64 = 1024; diff --git a/examples/partition.rs b/examples/partition.rs index b8e2ff0..19cd9be 100644 --- a/examples/partition.rs +++ b/examples/partition.rs @@ -1,69 +1,9 @@ extern crate fatfs; +extern crate fscommon; -use std::{cmp, fs, io}; -use std::io::{prelude::*, SeekFrom, ErrorKind}; -use fatfs::{FileSystem, FsOptions, BufStream}; - -trait ReadWriteSeek: Read + Write + Seek {} -impl ReadWriteSeek for T where T: Read + Write + Seek {} - -// File wrapper for accessing part of file -#[derive(Clone)] -pub(crate) struct Partition { - inner: T, - start_offset: u64, - current_offset: u64, - size: u64, -} - -impl Partition { - pub(crate) fn new(mut inner: T, start_offset: u64, size: u64) -> io::Result { - inner.seek(SeekFrom::Start(start_offset))?; - Ok(Self { - start_offset, size, inner, - current_offset: 0, - }) - } -} - -impl Read for Partition { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - let max_read_size = cmp::min((self.size - self.current_offset) as usize, buf.len()); - let bytes_read = self.inner.read(&mut buf[..max_read_size])?; - self.current_offset += bytes_read as u64; - Ok(bytes_read) - } -} - -impl Write for Partition { - fn write(&mut self, buf: &[u8]) -> io::Result { - let max_write_size = cmp::min((self.size - self.current_offset) as usize, buf.len()); - let bytes_written = self.inner.write(&buf[..max_write_size])?; - self.current_offset += bytes_written as u64; - Ok(bytes_written) - } - - fn flush(&mut self) -> io::Result<()> { - self.inner.flush() - } -} - -impl Seek for Partition { - fn seek(&mut self, pos: SeekFrom) -> io::Result { - let new_offset = match pos { - SeekFrom::Current(x) => self.current_offset as i64 + x, - SeekFrom::Start(x) => x as i64, - SeekFrom::End(x) => self.size as i64 + x, - }; - if new_offset < 0 || new_offset as u64 > self.size { - Err(io::Error::new(ErrorKind::InvalidInput, "invalid seek")) - } else { - self.inner.seek(SeekFrom::Start(self.start_offset + new_offset as u64))?; - self.current_offset = new_offset as u64; - Ok(self.current_offset) - } - } -} +use std::{fs, io}; +use fatfs::{FileSystem, FsOptions}; +use fscommon::{BufStream, StreamSlice}; fn main() -> io::Result<()> { // Open disk image @@ -72,7 +12,7 @@ fn main() -> io::Result<()> { let first_lba = 0; let last_lba = 10000; // Create partition using provided start address and size in bytes - let partition = Partition::::new(file, first_lba, last_lba - first_lba + 1)?; + let partition = StreamSlice::new(file, first_lba, last_lba + 1)?; // Create buffered stream to optimize file access let buf_rdr = BufStream::new(partition); // Finally initialize filesystem struct using provided partition diff --git a/examples/write.rs b/examples/write.rs index ee23cff..a9c9920 100644 --- a/examples/write.rs +++ b/examples/write.rs @@ -1,9 +1,11 @@ extern crate fatfs; +extern crate fscommon; use std::fs::OpenOptions; use std::io::{self, prelude::*}; -use fatfs::{FileSystem, FsOptions, BufStream}; +use fatfs::{FileSystem, FsOptions}; +use fscommon::BufStream; fn main() -> io::Result<()> { let img_file = match OpenOptions::new().read(true).write(true).open("fat.img") { diff --git a/src/lib.rs b/src/lib.rs index 0cb032f..c0c6137 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,9 +30,6 @@ mod dir_entry; mod file; mod table; -#[cfg(all(feature = "alloc"))] -mod utils; - #[cfg(not(feature = "std"))] mod byteorder_core_io; @@ -52,6 +49,3 @@ pub use fs::*; pub use dir::*; pub use dir_entry::*; pub use file::*; - -#[cfg(all(feature = "alloc"))] -pub use utils::*; diff --git a/src/utils.rs b/src/utils.rs deleted file mode 100644 index 0df2ca1..0000000 --- a/src/utils.rs +++ /dev/null @@ -1,131 +0,0 @@ -use io::prelude::*; -use io; -use core::cmp; - -const BUF_SIZE: usize = 512; - -pub struct BufStream { - inner: T, - buf: [u8; BUF_SIZE], - len: usize, - pos: usize, - write: bool, -} - -/// The BufStream struct adds buffering to underlying file or device. -/// -/// It's basically composition of BufReader and BufWritter. -impl BufStream { - /// Creates new BufStream object for given stream. - pub fn new(inner: T) -> Self { - BufStream:: { - inner, - buf: [0; BUF_SIZE], - pos: 0, - len: 0, - write: false, - } - } - - fn flush_buf(&mut self) -> io::Result<()> { - if self.write { - self.inner.write_all(&self.buf[..self.pos])?; - self.pos = 0; - } - Ok(()) - } - - fn make_reader(&mut self) -> io::Result<()> { - if self.write { - self.flush_buf()?; - self.write = false; - self.len = 0; - self.pos = 0; - } - Ok(()) - } - - fn make_writter(&mut self) -> io::Result<()> { - if !self.write { - self.inner.seek(io::SeekFrom::Current(-(self.len as i64 - self.pos as i64)))?; - self.write = true; - self.len = 0; - self.pos = 0; - } - Ok(()) - } -} - -impl BufRead for BufStream { - fn fill_buf(&mut self) -> io::Result<&[u8]> { - self.make_reader()?; - if self.pos >= self.len { - self.len = self.inner.read(&mut self.buf)?; - self.pos = 0; - } - Ok(&self.buf[self.pos..self.len]) - } - - fn consume(&mut self, amt: usize) { - self.pos = cmp::min(self.pos + amt, self.len); - } -} - -impl Read for BufStream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - // Make sure we are in read mode - self.make_reader()?; - // Check if this read is bigger than buffer size - if self.pos == self.len && buf.len() >= BUF_SIZE { - return self.inner.read(buf); - } - let nread = { - let mut rem = self.fill_buf()?; - rem.read(buf)? - }; - self.consume(nread); - Ok(nread) - } -} - -impl Write for BufStream { - fn write(&mut self, buf: &[u8]) -> io::Result { - // Make sure we are in write mode - self.make_writter()?; - if self.pos + buf.len() > BUF_SIZE { - self.flush_buf()?; - if buf.len() >= BUF_SIZE { - return self.inner.write(buf); - } - } - let written = (&mut self.buf[self.pos..]).write(buf)?; - self.pos += written; - Ok(written) - } - - fn flush(&mut self) -> io::Result<()> { - self.flush_buf()?; - self.inner.flush() - } -} - -impl Seek for BufStream { - fn seek(&mut self, pos: io::SeekFrom) -> io::Result { - self.flush_buf()?; - let new_pos = match pos { - io::SeekFrom::Current(x) => io::SeekFrom::Current(x - (self.len as i64 - self.pos as i64)), - _ => pos, - }; - self.pos = 0; - self.len = 0; - self.inner.seek(new_pos) - } -} - -impl Drop for BufStream { - fn drop(&mut self) { - if let Err(err) = self.flush() { - error!("flush failed {}", err); - } - } -} diff --git a/tests/read.rs b/tests/read.rs index 2c37257..d29b7c8 100644 --- a/tests/read.rs +++ b/tests/read.rs @@ -1,4 +1,5 @@ extern crate fatfs; +extern crate fscommon; extern crate env_logger; use std::fs; @@ -6,7 +7,8 @@ use std::io::SeekFrom; use std::io::prelude::*; use std::str; -use fatfs::{FsOptions, FatType, BufStream}; +use fatfs::{FsOptions, FatType}; +use fscommon::BufStream; const TEST_TEXT: &str = "Rust is cool!\n"; const FAT12_IMG: &str = "resources/fat12.img"; diff --git a/tests/write.rs b/tests/write.rs index 0ec0651..f9a6ad4 100644 --- a/tests/write.rs +++ b/tests/write.rs @@ -1,4 +1,5 @@ extern crate fatfs; +extern crate fscommon; extern crate env_logger; use std::fs; @@ -6,7 +7,8 @@ use std::io::prelude::*; use std::io; use std::str; -use fatfs::{FsOptions, BufStream}; +use fatfs::FsOptions; +use fscommon::BufStream; const FAT12_IMG: &str = "fat12.img"; const FAT16_IMG: &str = "fat16.img";