-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rid into storage trait #74
base: master
Are you sure you want to change the base?
Changes from all commits
6c77e49
eff9406
6ed236a
8a3313c
08da64c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
use std::fs::OpenOptions; | ||
use std::io::{self, prelude::*}; | ||
|
||
use fatfs::{FileSystem, FsOptions}; | ||
use fatfs::{FileSystem, FsOptions, StdIoWrapper}; | ||
use fscommon::BufStream; | ||
|
||
fn main() -> io::Result<()> { | ||
let img_file = match OpenOptions::new().read(true).write(true).open("fat.img") { | ||
let img_file = match OpenOptions::new().create(true).read(true).write(true).open("fat.img") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
Ok(file) => file, | ||
Err(err) => { | ||
println!("Failed to open image!"); | ||
|
@@ -14,7 +14,8 @@ fn main() -> io::Result<()> { | |
}; | ||
let buf_stream = BufStream::new(img_file); | ||
let options = FsOptions::new().update_accessed_date(true); | ||
let fs = FileSystem::new(buf_stream, options)?; | ||
let mut disk = StdIoWrapper::new(buf_stream); | ||
let fs = FileSystem::new(&mut disk, options).unwrap(); | ||
let mut file = fs.root_dir().create_file("hello.txt")?; | ||
file.write_all(b"Hello World!")?; | ||
Ok(()) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -789,6 +789,7 @@ impl LfnBuffer { | |
}; | ||
for (i, usc2_unit) in usc2_units.enumerate() { | ||
lfn.ucs2_units[i] = usc2_unit; | ||
lfn.len += 1; | ||
} | ||
lfn | ||
} | ||
|
@@ -807,7 +808,7 @@ impl LfnBuffer { | |
} | ||
|
||
pub(crate) fn as_ucs2_units(&self) -> &[u16] { | ||
&self.ucs2_units | ||
&self.ucs2_units[..self.len] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you please rebase so those changes are not visible? |
||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -323,24 +323,14 @@ pub struct FileSystem<IO: ReadWriteSeek, TP, OCC> { | |
current_status_flags: Cell<FsStatusFlags>, | ||
} | ||
|
||
pub trait IntoStorage<T: Read + Write + Seek> { | ||
fn into_storage(self) -> T; | ||
} | ||
|
||
impl<T: Read + Write + Seek> IntoStorage<T> for T { | ||
fn into_storage(self) -> Self { | ||
self | ||
} | ||
} | ||
|
||
#[cfg(feature = "std")] | ||
impl<T: std::io::Read + std::io::Write + std::io::Seek> IntoStorage<io::StdIoWrapper<T>> for T { | ||
fn into_storage(self) -> io::StdIoWrapper<Self> { | ||
io::StdIoWrapper::new(self) | ||
} | ||
} | ||
|
||
impl<IO: Read + Write + Seek, TP, OCC> FileSystem<IO, TP, OCC> { | ||
// #[cfg(feature = "std")] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to be removed? |
||
// impl<T: std::io::Read + std::io::Write + std::io::Seek> Into<io::StdIoWrapper<T>> for T { | ||
// fn into(self) -> io::StdIoWrapper<Self> { | ||
// io::StdIoWrapper::new(self) | ||
// } | ||
// } | ||
|
||
impl<IO: ReadWriteSeek, TP, OCC> FileSystem<IO, TP, OCC> { | ||
/// Creates a new filesystem object instance. | ||
/// | ||
/// Supplied `storage` parameter cannot be seeked. If there is a need to read a fragment of disk | ||
|
@@ -361,11 +351,10 @@ impl<IO: Read + Write + Seek, TP, OCC> FileSystem<IO, TP, OCC> { | |
/// # Panics | ||
/// | ||
/// Panics in non-optimized build if `storage` position returned by `seek` is not zero. | ||
pub fn new<T: IntoStorage<IO>>(storage: T, options: FsOptions<TP, OCC>) -> Result<Self, Error<IO::Error>> { | ||
pub fn new(mut disk: IO, options: FsOptions<TP, OCC>) -> Result<Self, Error<IO::Error>> { | ||
// Make sure given image is not seeked | ||
let mut disk = storage.into_storage(); | ||
trace!("FileSystem::new"); | ||
debug_assert!(disk.seek(SeekFrom::Current(0))? == 0); | ||
disk.seek(SeekFrom::Start(0))?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a change of behavior that requires changing the function comment. |
||
|
||
// read boot sector | ||
let bpb = { | ||
|
@@ -1113,9 +1102,9 @@ impl FormatVolumeOptions { | |
/// | ||
/// Panics in non-optimized build if `storage` position returned by `seek` is not zero. | ||
#[allow(clippy::needless_pass_by_value)] | ||
pub fn format_volume<S: ReadWriteSeek>(storage: &mut S, options: FormatVolumeOptions) -> Result<(), Error<S::Error>> { | ||
pub fn format_volume<S: ReadWriteSeek>(mut storage: S, options: FormatVolumeOptions) -> Result<(), Error<S::Error>> { | ||
trace!("format_volume"); | ||
debug_assert!(storage.seek(SeekFrom::Current(0))? == 0); | ||
storage.seek(SeekFrom::Start(0))?; | ||
|
||
let bytes_per_sector = options.bytes_per_sector.unwrap_or(512); | ||
let total_sectors = if let Some(total_sectors) = options.total_sectors { | ||
|
@@ -1136,10 +1125,10 @@ pub fn format_volume<S: ReadWriteSeek>(storage: &mut S, options: FormatVolumeOpt | |
if boot.validate::<S::Error>().is_err() { | ||
return Err(Error::InvalidInput); | ||
} | ||
boot.serialize(storage)?; | ||
boot.serialize(&mut storage)?; | ||
// Make sure entire logical sector is updated (serialize method always writes 512 bytes) | ||
let bytes_per_sector = boot.bpb.bytes_per_sector; | ||
write_zeros_until_end_of_sector(storage, bytes_per_sector)?; | ||
write_zeros_until_end_of_sector(&mut storage, bytes_per_sector)?; | ||
|
||
let bpb = &boot.bpb; | ||
if bpb.is_fat32() { | ||
|
@@ -1150,23 +1139,23 @@ pub fn format_volume<S: ReadWriteSeek>(storage: &mut S, options: FormatVolumeOpt | |
dirty: false, | ||
}; | ||
storage.seek(SeekFrom::Start(bpb.bytes_from_sectors(bpb.fs_info_sector())))?; | ||
fs_info_sector.serialize(storage)?; | ||
write_zeros_until_end_of_sector(storage, bytes_per_sector)?; | ||
fs_info_sector.serialize(&mut storage)?; | ||
write_zeros_until_end_of_sector(&mut storage, bytes_per_sector)?; | ||
|
||
// backup boot sector | ||
storage.seek(SeekFrom::Start(bpb.bytes_from_sectors(bpb.backup_boot_sector())))?; | ||
boot.serialize(storage)?; | ||
write_zeros_until_end_of_sector(storage, bytes_per_sector)?; | ||
boot.serialize(&mut storage)?; | ||
write_zeros_until_end_of_sector(&mut storage, bytes_per_sector)?; | ||
} | ||
|
||
// format File Allocation Table | ||
let reserved_sectors = bpb.reserved_sectors(); | ||
let fat_pos = bpb.bytes_from_sectors(reserved_sectors); | ||
let sectors_per_all_fats = bpb.sectors_per_all_fats(); | ||
storage.seek(SeekFrom::Start(fat_pos))?; | ||
write_zeros(storage, bpb.bytes_from_sectors(sectors_per_all_fats))?; | ||
write_zeros(&mut storage, bpb.bytes_from_sectors(sectors_per_all_fats))?; | ||
{ | ||
let mut fat_slice = fat_slice::<S, &mut S>(storage, bpb); | ||
let mut fat_slice = fat_slice::<S, &mut S>(&mut storage, bpb); | ||
let sectors_per_fat = bpb.sectors_per_fat(); | ||
let bytes_per_fat = bpb.bytes_from_sectors(sectors_per_fat); | ||
format_fat(&mut fat_slice, fat_type, bpb.media, bytes_per_fat, bpb.total_clusters())?; | ||
|
@@ -1177,10 +1166,10 @@ pub fn format_volume<S: ReadWriteSeek>(storage: &mut S, options: FormatVolumeOpt | |
let root_dir_sectors = bpb.root_dir_sectors(); | ||
let root_dir_pos = bpb.bytes_from_sectors(root_dir_first_sector); | ||
storage.seek(SeekFrom::Start(root_dir_pos))?; | ||
write_zeros(storage, bpb.bytes_from_sectors(root_dir_sectors))?; | ||
write_zeros(&mut storage, bpb.bytes_from_sectors(root_dir_sectors))?; | ||
if fat_type == FatType::Fat32 { | ||
let root_dir_first_cluster = { | ||
let mut fat_slice = fat_slice::<S, &mut S>(storage, bpb); | ||
let mut fat_slice = fat_slice::<S, &mut S>(&mut storage, bpb); | ||
alloc_cluster(&mut fat_slice, fat_type, None, None, 1)? | ||
}; | ||
assert!(root_dir_first_cluster == bpb.root_dir_first_cluster); | ||
|
@@ -1189,14 +1178,14 @@ pub fn format_volume<S: ReadWriteSeek>(storage: &mut S, options: FormatVolumeOpt | |
let fat32_root_dir_first_sector = first_data_sector + data_sectors_before_root_dir; | ||
let fat32_root_dir_pos = bpb.bytes_from_sectors(fat32_root_dir_first_sector); | ||
storage.seek(SeekFrom::Start(fat32_root_dir_pos))?; | ||
write_zeros(storage, u64::from(bpb.cluster_size()))?; | ||
write_zeros(&mut storage, u64::from(bpb.cluster_size()))?; | ||
} | ||
|
||
// Create volume label directory entry if volume label is specified in options | ||
if let Some(volume_label) = options.volume_label { | ||
storage.seek(SeekFrom::Start(root_dir_pos))?; | ||
let volume_entry = DirFileEntryData::new(volume_label, FileAttributes::VOLUME_ID); | ||
volume_entry.serialize(storage)?; | ||
volume_entry.serialize(&mut storage)?; | ||
} | ||
|
||
storage.seek(SeekFrom::Start(0))?; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is exactly why I made
IntoStorage
trait - to make it possible to passstd::fs::File
directly. Anyway why in some places you usedinto()
and in someStdIoWrapper::new
directly? IMHOinto
way is betterThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could do something like
pub fn new(disk: impl Into<IO>, ...)
to keep making this work.