From 3b567fb3e2d2abbde73aa2e282040bc6d4abc0d7 Mon Sep 17 00:00:00 2001 From: bunnie Date: Wed, 20 Nov 2024 21:40:25 +0800 Subject: [PATCH] modularize SliceCursor --- .../src/platform/cramium/usb/slice_cursor.rs | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 loader/src/platform/cramium/usb/slice_cursor.rs diff --git a/loader/src/platform/cramium/usb/slice_cursor.rs b/loader/src/platform/cramium/usb/slice_cursor.rs new file mode 100644 index 000000000..e01fd7b2f --- /dev/null +++ b/loader/src/platform/cramium/usb/slice_cursor.rs @@ -0,0 +1,117 @@ +use core::fmt::Display; + +use simple_fatfs::io::{IOBase, Read, Seek, SeekFrom, Write}; +use simple_fatfs::{IOError, IOErrorKind}; + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +pub enum IOErrorFatfs { + UnexpectedEof, + Interrupted, + InvalidData, + Description, + SeekUnderflow, + SeekOverflow, + SeekOutOfBounds, +} + +impl Display for IOErrorFatfs { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + IOErrorFatfs::UnexpectedEof => write!(f, "Unexpected EOF"), + IOErrorFatfs::Interrupted => write!(f, "Interrupted"), + IOErrorFatfs::InvalidData => write!(f, "Invalid Data"), + IOErrorFatfs::Description => write!(f, "Unsupported string description"), + IOErrorFatfs::SeekOutOfBounds => write!(f, "Seek out of bounds"), + IOErrorFatfs::SeekOverflow => write!(f, "Seek overflow"), + IOErrorFatfs::SeekUnderflow => write!(f, "Seek underflow"), + } + } +} + +impl From<&str> for IOErrorFatfs { + fn from(_value: &str) -> Self { IOErrorFatfs::Description } +} +impl IOErrorKind for IOErrorFatfs { + fn new_unexpected_eof() -> Self { Self::UnexpectedEof } + + fn new_invalid_data() -> Self { Self::InvalidData } + + fn new_interrupted() -> Self { Self::Interrupted } +} +impl IOError for IOErrorFatfs { + type Kind = IOErrorFatfs; + + fn new(kind: Self::Kind, _msg: M) -> Self + where + M: core::fmt::Display, + { + kind + } + + fn kind(&self) -> Self::Kind { *self } +} + +impl simple_fatfs::Error for IOErrorFatfs {} + +impl IOBase for SliceCursor<'_> { + type Error = IOErrorFatfs; +} +pub struct SliceCursor<'a> { + slice: &'a mut [u8], + pos: u64, +} + +impl<'a> SliceCursor<'a> { + pub fn new(slice: &'a mut [u8]) -> Self { Self { slice, pos: 0 } } +} + +impl Seek for SliceCursor<'_> { + fn seek(&mut self, seek_from: simple_fatfs::io::SeekFrom) -> Result { + let new_pos = match seek_from { + SeekFrom::Start(offset) => offset, + SeekFrom::End(offset) => { + let result = if offset < 0 { + self.slice.len().checked_sub((-offset) as usize).ok_or(IOErrorFatfs::SeekUnderflow)? + } else { + self.slice.len().checked_add(offset as usize).ok_or(IOErrorFatfs::SeekOverflow)? + }; + result as u64 + } + SeekFrom::Current(offset) => { + if offset < 0 { + self.pos.checked_sub((-offset) as u64).ok_or(IOErrorFatfs::SeekUnderflow)? + } else { + self.pos.checked_add(offset as u64).ok_or(IOErrorFatfs::SeekUnderflow)? + } + } + }; + + if new_pos > self.slice.len() as u64 { + Err(IOErrorFatfs::SeekOutOfBounds) + } else { + self.pos = new_pos; + Ok(self.pos) + } + } +} + +impl Read for SliceCursor<'_> { + fn read(&mut self, buf: &mut [u8]) -> Result { + let available = &self.slice[self.pos as usize..]; + let to_read = buf.len().min(available.len()); + buf[..to_read].copy_from_slice(&available[..to_read]); + self.pos += to_read as u64; + Ok(to_read) + } +} +impl Write for SliceCursor<'_> { + fn write(&mut self, buf: &[u8]) -> Result { + let available = &mut self.slice[self.pos as usize..]; + let to_write = buf.len().min(available.len()); + available[..to_write].copy_from_slice(&buf[..to_write]); + self.pos += to_write as u64; + Ok(to_write) + } + + fn flush(&mut self) -> Result<(), Self::Error> { Ok(()) } +}