Change io crate & add a small shell
This commit is contained in:
@@ -4,7 +4,7 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
io = { path = "../io" }
|
||||
io = { package = "no-std-io", path = "../io" }
|
||||
bitflags = "2"
|
||||
|
||||
[features]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::error::Error;
|
||||
use io::{Read, ReadLeExt};
|
||||
use io::Read;
|
||||
|
||||
use crate::io_ext::ReadLeExt;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Fat32BootSector {
|
||||
@@ -94,7 +95,7 @@ impl Fat32BootSector {
|
||||
}
|
||||
|
||||
impl Fat32BootSector {
|
||||
pub fn deserialize<T: Read>(disk: &mut T) -> Result<Self, Error<T::Error>> {
|
||||
pub fn deserialize<T: Read>(disk: &mut T) -> Result<Self, io::Error> {
|
||||
let mut jump_boot = [0u8; _];
|
||||
disk.read_exact(&mut jump_boot)?;
|
||||
let mut oem_name = [0u8; _];
|
||||
|
||||
@@ -1,36 +1,32 @@
|
||||
use crate::{
|
||||
Fat32FileSystem, ReadSeek, ReadWriteSeek,
|
||||
entry::{DirEntry, DirectoryIterator},
|
||||
error::Error,
|
||||
file::{File, RawFile},
|
||||
path::Path,
|
||||
};
|
||||
use io::{self, IoBase, Read, Seek, Write};
|
||||
use io::{self, Read, Seek, Write};
|
||||
|
||||
pub struct Dir<'a, T> {
|
||||
raw: RawFile<'a, T>,
|
||||
fs: &'a Fat32FileSystem<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: IoBase> IoBase for Dir<'a, T> {
|
||||
type Error = Error<T::Error>;
|
||||
}
|
||||
impl<'a, T: ReadSeek> Seek for Dir<'a, T> {
|
||||
fn seek(&mut self, pos: io::SeekFrom) -> Result<u64, Self::Error> {
|
||||
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
|
||||
self.raw.seek(pos)
|
||||
}
|
||||
}
|
||||
impl<'a, T: ReadSeek> Read for Dir<'a, T> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.raw.read(buf)
|
||||
}
|
||||
}
|
||||
impl<'a, T: ReadWriteSeek> Write for Dir<'a, T> {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.raw.write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.raw.flush()
|
||||
}
|
||||
}
|
||||
@@ -44,7 +40,7 @@ impl<'a, T> Dir<'a, T> {
|
||||
}
|
||||
}
|
||||
impl<'a, T: ReadSeek> Dir<'a, T> {
|
||||
pub fn open_entry<P: AsRef<Path>>(&self, path: P) -> Result<DirEntry<'a, T>, Error<T::Error>> {
|
||||
pub fn open_entry<P: AsRef<Path>>(&self, path: P) -> Result<DirEntry<'a, T>, io::Error> {
|
||||
if path.as_ref().is_absolute() {
|
||||
return self.fs.open_entry(path);
|
||||
}
|
||||
@@ -56,16 +52,16 @@ impl<'a, T: ReadSeek> Dir<'a, T> {
|
||||
if f.is_dir() {
|
||||
return f.to_dir().open_entry(entry_name);
|
||||
} else {
|
||||
return Err(Error::NotFound);
|
||||
return Err(io::Error::from(io::ErrorKind::NotFound));
|
||||
}
|
||||
} else {
|
||||
return Ok(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(Error::NotFound)
|
||||
Err(io::Error::from(io::ErrorKind::NotFound))
|
||||
}
|
||||
pub fn open_file<P: AsRef<Path>>(&self, path: P) -> Result<File<'a, T>, Error<T::Error>> {
|
||||
pub fn open_file<P: AsRef<Path>>(&self, path: P) -> Result<File<'a, T>, io::Error> {
|
||||
if path.as_ref().is_absolute() {
|
||||
return self.fs.open_file(path);
|
||||
}
|
||||
@@ -74,19 +70,19 @@ impl<'a, T: ReadSeek> Dir<'a, T> {
|
||||
match dirname {
|
||||
Some(name) => {
|
||||
if !entry.is_dir() {
|
||||
return Err(Error::NotFound);
|
||||
return Err(io::Error::from(io::ErrorKind::NotFound));
|
||||
}
|
||||
entry.to_dir().open_file(name)
|
||||
}
|
||||
None => {
|
||||
if !entry.is_file() {
|
||||
return Err(Error::NotFound);
|
||||
return Err(io::Error::from(io::ErrorKind::NotFound));
|
||||
}
|
||||
Ok(entry.to_file())
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn open_dir<P: AsRef<Path>>(&self, path: P) -> Result<Self, Error<T::Error>> {
|
||||
pub fn open_dir<P: AsRef<Path>>(&self, path: P) -> Result<Self, io::Error> {
|
||||
let path = path.as_ref();
|
||||
if path.is_absolute() {
|
||||
return self.fs.open_dir(path);
|
||||
@@ -94,7 +90,7 @@ impl<'a, T: ReadSeek> Dir<'a, T> {
|
||||
let (start, dirname) = path.split_path();
|
||||
let entry = self.open_entry(start)?;
|
||||
if !entry.is_dir() {
|
||||
return Err(Error::NotFound);
|
||||
return Err(io::Error::from(io::ErrorKind::NotFound));
|
||||
}
|
||||
match dirname {
|
||||
Some(name) => entry.to_dir().open_dir(name),
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
use core::{array::IntoIter, iter::Copied, str::Utf8Error};
|
||||
use core::{char::DecodeUtf16, marker::PhantomData, slice::Iter};
|
||||
|
||||
use crate::io_ext::ReadLeExt;
|
||||
use crate::{
|
||||
Fat32FileSystem, ReadSeek,
|
||||
consts::FATAttr,
|
||||
dir::Dir,
|
||||
error::Error,
|
||||
file::{File, RawFile},
|
||||
};
|
||||
|
||||
use io::{IoBase, Read, ReadLeExt};
|
||||
use io::Read;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::borrow::ToOwned;
|
||||
@@ -33,7 +33,7 @@ pub struct FatDirEntry {
|
||||
}
|
||||
|
||||
impl FatDirEntry {
|
||||
pub fn deserialize<T: Read>(reader: &mut T) -> Result<Self, T::Error> {
|
||||
pub fn deserialize<T: Read>(reader: &mut T) -> Result<Self, io::Error> {
|
||||
let mut name = [0u8; _];
|
||||
reader.read_exact(&mut name)?;
|
||||
let attr = reader.read_u8()?;
|
||||
@@ -131,7 +131,7 @@ pub struct LongFileNameBuilder<T> {
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: IoBase> LongFileNameBuilder<T> {
|
||||
impl<T> LongFileNameBuilder<T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
inner: [0; _],
|
||||
@@ -160,12 +160,12 @@ impl<T: IoBase> LongFileNameBuilder<T> {
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn to_string(&self) -> Result<String, Error<T::Error>> {
|
||||
pub fn to_string(&self) -> Result<String, io::Error> {
|
||||
self.iter().try_collect::<String>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IoBase> IntoIterator for LongFileNameBuilder<T> {
|
||||
impl<T> IntoIterator for LongFileNameBuilder<T> {
|
||||
type Item = <LongFileNameIterator<T, IntoIter<u16, 256>> as Iterator>::Item;
|
||||
|
||||
type IntoIter = LongFileNameIterator<T, IntoIter<u16, 256>>;
|
||||
@@ -178,7 +178,7 @@ impl<T: IoBase> IntoIterator for LongFileNameBuilder<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IoBase> LongFileNameBuilder<T> {
|
||||
impl<T> LongFileNameBuilder<T> {
|
||||
pub fn iter(&self) -> LongFileNameIterator<T, Copied<Iter<'_, u16>>> {
|
||||
LongFileNameIterator {
|
||||
iterator: char::decode_utf16(self.inner.iter().copied()),
|
||||
@@ -192,8 +192,8 @@ pub struct LongFileNameIterator<T, I: Iterator<Item = u16>> {
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: IoBase, I: Iterator<Item = u16>> Iterator for LongFileNameIterator<T, I> {
|
||||
type Item = Result<char, Error<T::Error>>;
|
||||
impl<T, I: Iterator<Item = u16>> Iterator for LongFileNameIterator<T, I> {
|
||||
type Item = Result<char, io::Error>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.iterator.next()? {
|
||||
@@ -204,12 +204,15 @@ impl<T: IoBase, I: Iterator<Item = u16>> Iterator for LongFileNameIterator<T, I>
|
||||
Some(Ok(value))
|
||||
}
|
||||
}
|
||||
Err(_) => Some(Err(Error::UnsupportedFileNameCharacter)),
|
||||
Err(_) => Some(Err(io::Error::new(
|
||||
io::ErrorKind::Unsupported,
|
||||
"Unsupported file name character",
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IoBase> Default for LongFileNameBuilder<T> {
|
||||
impl<T> Default for LongFileNameBuilder<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
@@ -226,7 +229,7 @@ impl<'a, T> DirectoryIterator<'a, T> {
|
||||
}
|
||||
|
||||
impl<'a, T: ReadSeek + 'a> Iterator for DirectoryIterator<'a, T> {
|
||||
type Item = Result<DirEntry<'a, T>, Error<T::Error>>;
|
||||
type Item = Result<DirEntry<'a, T>, io::Error>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let mut lfn_builder = LongFileNameBuilder::new();
|
||||
@@ -283,7 +286,7 @@ pub struct DirEntry<'a, T> {
|
||||
fs: &'a Fat32FileSystem<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: IoBase> DirEntry<'a, T> {
|
||||
impl<'a, T> DirEntry<'a, T> {
|
||||
fn new(
|
||||
entry: FatDirEntry,
|
||||
short_name: [u8; 11],
|
||||
@@ -298,13 +301,16 @@ impl<'a, T: IoBase> DirEntry<'a, T> {
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn name(&self) -> Result<String, Error<T::Error>> {
|
||||
pub fn name(&self) -> Result<String, io::Error> {
|
||||
if let Some(long_name) = self.long_name() {
|
||||
long_name.to_string()
|
||||
} else {
|
||||
self.short_name()
|
||||
.map(|n| n.to_owned())
|
||||
.map_err(|_| Error::UnsupportedFileNameCharacter)
|
||||
self.short_name().map(|n| n.to_owned()).map_err(|_| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::Unsupported,
|
||||
"Unsupported file name character",
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
pub fn long_name(&self) -> Option<&LongFileNameBuilder<T>> {
|
||||
|
||||
@@ -1,79 +1 @@
|
||||
use io::error::IoError;
|
||||
|
||||
/// Error enum with all errors that can be returned by functions from this crate
|
||||
///
|
||||
/// Generic parameter `T` is a type of external error returned by the user provided storage
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum Error<T> {
|
||||
/// A user provided storage instance returned an error during an input/output operation.
|
||||
Io(T),
|
||||
/// A read operation cannot be completed because an end of a file has been reached prematurely.
|
||||
UnexpectedEof,
|
||||
/// A write operation cannot be completed because `Write::write` returned 0.
|
||||
WriteZero,
|
||||
/// A parameter was incorrect.
|
||||
InvalidInput,
|
||||
/// A requested file or directory has not been found.
|
||||
NotFound,
|
||||
/// A file or a directory with the same name already exists.
|
||||
AlreadyExists,
|
||||
/// An operation cannot be finished because a directory is not empty.
|
||||
DirectoryIsNotEmpty,
|
||||
/// File system internal structures are corrupted/invalid.
|
||||
CorruptedFileSystem,
|
||||
/// There is not enough free space on the storage to finish the requested operation.
|
||||
NotEnoughSpace,
|
||||
/// The provided file name is either too long or empty.
|
||||
InvalidFileNameLength,
|
||||
/// The provided file name contains an invalid character.
|
||||
UnsupportedFileNameCharacter,
|
||||
/// The file content contains invalid UTF-8 characters.
|
||||
InvalidUTF8,
|
||||
}
|
||||
|
||||
impl<T: IoError> From<T> for Error<T> {
|
||||
fn from(error: T) -> Self {
|
||||
Error::Io(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: core::fmt::Display> core::fmt::Display for Error<T> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
Error::Io(io_error) => write!(f, "IO error: {}", io_error),
|
||||
Error::UnexpectedEof => write!(f, "Unexpected end of file"),
|
||||
Error::NotEnoughSpace => write!(f, "Not enough space"),
|
||||
Error::WriteZero => write!(f, "Write zero"),
|
||||
Error::InvalidInput => write!(f, "Invalid input"),
|
||||
Error::InvalidFileNameLength => write!(f, "Invalid file name length"),
|
||||
Error::UnsupportedFileNameCharacter => write!(f, "Unsupported file name character"),
|
||||
Error::DirectoryIsNotEmpty => write!(f, "Directory is not empty"),
|
||||
Error::NotFound => write!(f, "No such file or directory"),
|
||||
Error::AlreadyExists => write!(f, "File or directory already exists"),
|
||||
Error::CorruptedFileSystem => write!(f, "Corrupted file system"),
|
||||
Error::InvalidUTF8 => write!(f, "File contains invalid UTF-8 characters"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: core::fmt::Debug + IoError> IoError for Error<T> {
|
||||
fn is_interrupted(&self) -> bool {
|
||||
match self {
|
||||
Error::<T>::Io(io_error) => io_error.is_interrupted(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn new_unexpected_eof_error() -> Self {
|
||||
Error::<T>::UnexpectedEof
|
||||
}
|
||||
|
||||
fn new_write_zero_error() -> Self {
|
||||
Error::<T>::WriteZero
|
||||
}
|
||||
|
||||
fn new_invalid_utf8_error() -> Self {
|
||||
Error::<T>::InvalidUTF8
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use crate::{
|
||||
Fat32FileSystem, ReadSeek, ReadWriteSeek,
|
||||
consts::{FAT32_BAD_CLUSTER, FAT32_END_OF_CHAIN},
|
||||
error::Error,
|
||||
};
|
||||
|
||||
use io::{self, IoBase, Read, Seek, Write};
|
||||
use io::{self, Read, Seek, Write};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RawFile<'a, T> {
|
||||
@@ -30,12 +29,8 @@ impl<'a, T> RawFile<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: IoBase> IoBase for RawFile<'a, T> {
|
||||
type Error = Error<T::Error>;
|
||||
}
|
||||
|
||||
impl<'a, T: ReadSeek> Seek for RawFile<'a, T> {
|
||||
fn seek(&mut self, pos: io::SeekFrom) -> Result<u64, Self::Error> {
|
||||
fn seek(&mut self, pos: io::SeekFrom) -> Result<u64, io::Error> {
|
||||
let new_pos = match pos {
|
||||
io::SeekFrom::Start(s) => s,
|
||||
io::SeekFrom::Current(c) => (self.pos as i64 + c) as u64,
|
||||
@@ -67,7 +62,7 @@ impl<'a, T: ReadSeek> Seek for RawFile<'a, T> {
|
||||
}
|
||||
|
||||
impl<'a, T: ReadSeek> Read for RawFile<'a, T> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
|
||||
let max_len = self
|
||||
.size
|
||||
.map(|size| core::cmp::min(buf.len(), size as usize - self.pos as usize))
|
||||
@@ -116,11 +111,11 @@ impl<'a, T: ReadSeek> Read for RawFile<'a, T> {
|
||||
}
|
||||
}
|
||||
impl<'a, T: ReadWriteSeek> Write for RawFile<'a, T> {
|
||||
fn write(&mut self, _buf: &[u8]) -> Result<usize, Self::Error> {
|
||||
fn write(&mut self, _buf: &[u8]) -> Result<usize, io::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||
fn flush(&mut self) -> Result<(), io::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@@ -132,25 +127,22 @@ pub struct File<'a, T> {
|
||||
fs: &'a Fat32FileSystem<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: IoBase> IoBase for File<'a, T> {
|
||||
type Error = Error<T::Error>;
|
||||
}
|
||||
impl<'a, T: ReadSeek> Seek for File<'a, T> {
|
||||
fn seek(&mut self, pos: io::SeekFrom) -> Result<u64, Self::Error> {
|
||||
fn seek(&mut self, pos: io::SeekFrom) -> Result<u64, io::Error> {
|
||||
self.raw.seek(pos)
|
||||
}
|
||||
}
|
||||
impl<'a, T: ReadSeek> Read for File<'a, T> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
|
||||
self.raw.read(buf)
|
||||
}
|
||||
}
|
||||
impl<'a, T: ReadWriteSeek> Write for File<'a, T> {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
|
||||
self.raw.write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||
fn flush(&mut self) -> Result<(), io::Error> {
|
||||
self.raw.flush()
|
||||
}
|
||||
}
|
||||
|
||||
27
crates/bffs/src/io_ext.rs
Normal file
27
crates/bffs/src/io_ext.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
use io::{Read, Result};
|
||||
|
||||
pub trait ReadLeExt {
|
||||
fn read_u8(&mut self) -> Result<u8>;
|
||||
fn read_u16_le(&mut self) -> Result<u16>;
|
||||
fn read_u32_le(&mut self) -> Result<u32>;
|
||||
}
|
||||
|
||||
impl<T: Read> ReadLeExt for T {
|
||||
fn read_u8(&mut self) -> Result<u8> {
|
||||
let mut buf = [0_u8; 1];
|
||||
self.read_exact(&mut buf)?;
|
||||
Ok(buf[0])
|
||||
}
|
||||
|
||||
fn read_u16_le(&mut self) -> Result<u16> {
|
||||
let mut buf = [0_u8; 2];
|
||||
self.read_exact(&mut buf)?;
|
||||
Ok(u16::from_le_bytes(buf))
|
||||
}
|
||||
|
||||
fn read_u32_le(&mut self) -> Result<u32> {
|
||||
let mut buf = [0_u8; 4];
|
||||
self.read_exact(&mut buf)?;
|
||||
Ok(u32::from_le_bytes(buf))
|
||||
}
|
||||
}
|
||||
@@ -6,16 +6,10 @@ use core::cell::RefCell;
|
||||
use core::fmt::Display;
|
||||
|
||||
use crate::{
|
||||
boot_sector::Fat32BootSector,
|
||||
consts::FAT32_CLUSTER_MASK,
|
||||
dir::Dir,
|
||||
entry::{DirEntry, FatEntry},
|
||||
error::Error,
|
||||
file::{File, RawFile},
|
||||
path::Path,
|
||||
boot_sector::Fat32BootSector, consts::FAT32_CLUSTER_MASK, dir::Dir, entry::{DirEntry, FatEntry}, file::{File, RawFile}, io_ext::ReadLeExt, path::Path
|
||||
};
|
||||
|
||||
use io::{Read, ReadLeExt, Seek, Write};
|
||||
use io::{Read, Seek, Write};
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
extern crate alloc;
|
||||
@@ -24,8 +18,8 @@ pub mod boot_sector;
|
||||
pub mod consts;
|
||||
pub mod dir;
|
||||
pub mod entry;
|
||||
pub mod error;
|
||||
pub mod file;
|
||||
pub mod io_ext;
|
||||
pub mod path;
|
||||
|
||||
pub trait ReadSeek: Read + Seek {}
|
||||
@@ -47,7 +41,7 @@ pub struct Fat32FsInfo {
|
||||
}
|
||||
|
||||
impl Fat32FsInfo {
|
||||
pub fn deserialize<T: Read>(disk: &mut T) -> Result<Self, Error<T::Error>> {
|
||||
pub fn deserialize<T: Read>(disk: &mut T) -> Result<Self, io::Error> {
|
||||
let lead_signature = disk.read_u32_le()?;
|
||||
let mut reserved1 = [0u8; _];
|
||||
disk.read_exact(&mut reserved1)?;
|
||||
@@ -82,7 +76,7 @@ impl<T> Display for Fat32FileSystem<T> {
|
||||
}
|
||||
|
||||
impl<T: ReadSeek> Fat32FileSystem<T> {
|
||||
pub fn new(mut device: T) -> Result<Self, Error<T::Error>> {
|
||||
pub fn new(mut device: T) -> Result<Self, io::Error> {
|
||||
device.seek(io::SeekFrom::Start(0))?;
|
||||
|
||||
let boot_sector = Fat32BootSector::deserialize(&mut device)?;
|
||||
@@ -92,7 +86,7 @@ impl<T: ReadSeek> Fat32FileSystem<T> {
|
||||
})
|
||||
}
|
||||
/// Get the next cluster from the current one
|
||||
fn get_next_cluster(&self, current_cluster: u32) -> Result<u32, Error<T::Error>> {
|
||||
fn get_next_cluster(&self, current_cluster: u32) -> Result<u32, io::Error> {
|
||||
let fat_offset =
|
||||
self.fat_start_offset() + (current_cluster as u64 * size_of::<FatEntry>() as u64);
|
||||
self.device
|
||||
@@ -137,15 +131,15 @@ impl<T> Fat32FileSystem<T> {
|
||||
}
|
||||
}
|
||||
impl<T: ReadSeek> Fat32FileSystem<T> {
|
||||
pub fn open_entry<P: AsRef<Path>>(&self, path: P) -> Result<DirEntry<'_, T>, Error<T::Error>> {
|
||||
pub fn open_entry<P: AsRef<Path>>(&self, path: P) -> Result<DirEntry<'_, T>, io::Error> {
|
||||
let path = path.as_ref().as_str().trim_start_matches("/");
|
||||
self.root_directory().open_entry(path)
|
||||
}
|
||||
pub fn open_dir<P: AsRef<Path>>(&self, path: P) -> Result<Dir<'_, T>, Error<T::Error>> {
|
||||
pub fn open_dir<P: AsRef<Path>>(&self, path: P) -> Result<Dir<'_, T>, io::Error> {
|
||||
let path = path.as_ref().as_str().trim_start_matches("/");
|
||||
self.root_directory().open_dir(path)
|
||||
}
|
||||
pub fn open_file<P: AsRef<Path>>(&self, path: P) -> Result<File<'_, T>, Error<T::Error>> {
|
||||
pub fn open_file<P: AsRef<Path>>(&self, path: P) -> Result<File<'_, T>, io::Error> {
|
||||
let path = path.as_ref().as_str().trim_start_matches("/");
|
||||
self.root_directory().open_file(path)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ pub fn main() {
|
||||
|
||||
// walk(fs.root_directory());
|
||||
|
||||
let mut f = fs.open_file("/usr/bin/test_pic").unwrap();
|
||||
let mut f = fs.open_file("/usr/bin/agetty").unwrap();
|
||||
let mut content = Vec::new();
|
||||
f.read_to_end(&mut content).unwrap();
|
||||
println!("file content len: {}", content.len());
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use core::fmt::Display;
|
||||
#[cfg(feature = "alloc")]
|
||||
use core::{borrow::Borrow, ops::Deref};
|
||||
|
||||
@@ -12,6 +13,12 @@ pub struct Path {
|
||||
inner: str,
|
||||
}
|
||||
|
||||
impl Display for Path {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{}", &self.inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for &Path {
|
||||
fn from(value: &str) -> Self {
|
||||
unsafe { &*(value as *const str as *const Path) }
|
||||
|
||||
Reference in New Issue
Block a user