Various updates

- Use thiserror for nod::Error
- Use anyhow for error context chaining
- Stream logic fixes
This commit is contained in:
Luke Street 2022-02-02 17:42:34 -05:00
parent 4b32388fa5
commit 8b3f655dc2
6 changed files with 33 additions and 21 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "nod"
version = "0.1.1"
version = "0.1.2"
edition = "2018"
authors = ["Luke Street <luke@street.dev>"]
license = "MIT OR Apache-2.0"
@ -19,9 +19,11 @@ path = "src/bin.rs"
[dependencies]
aes = "0.7.4"
anyhow = "1.0.53"
binread = "2.1.1"
block-modes = "0.8.1"
clap = "2.33.3"
encoding_rs = "0.8.28"
file-size = "1.0.3"
sha-1 = "0.9.7"
thiserror = "1.0.30"

View File

@ -73,7 +73,7 @@ pub(crate) struct BI2Header {
pub(crate) const BUFFER_SIZE: usize = 0x8000;
/// Contains a disc's header & partition information.
pub trait DiscBase {
pub trait DiscBase: Send + Sync {
/// Retrieves the disc's header.
fn get_header(&self) -> &Header;
@ -157,7 +157,7 @@ pub trait PartReadStream: ReadStream {
}
/// Disc partition header with file system table.
pub trait PartHeader: Debug {
pub trait PartHeader: Debug + Send + Sync {
/// The root node for the filesystem.
fn root_node(&self) -> &NodeType;

View File

@ -39,7 +39,7 @@ impl<T: ReadStream + Sized> DiscIOISOStream<T> {
}
}
impl<T: ReadStream + Sized> DiscIO for DiscIOISOStream<T> {
impl<T: ReadStream + Sized + Send + Sync> DiscIO for DiscIOISOStream<T> {
fn begin_read_stream<'a>(&'a mut self, offset: u64) -> io::Result<Box<dyn ReadStream + 'a>> {
let size = self.stream.stable_stream_len()?;
let mut stream = self.stream.new_window(0, size)?;

View File

@ -15,7 +15,7 @@ pub(crate) mod iso;
pub(crate) mod nfs;
/// Abstraction over supported disc file types.
pub trait DiscIO {
pub trait DiscIO: Send + Sync {
/// Opens a new read stream for the disc file(s).
/// Generally does _not_ need to be used directly.
fn begin_read_stream(&mut self, offset: u64) -> io::Result<Box<dyn ReadStream + '_>>;
@ -73,7 +73,7 @@ pub fn new_disc_io_from_buf(buf: &[u8]) -> Result<Box<dyn DiscIO + '_>> {
Ok(Box::from(DiscIOISOStream::new(ByteReadStream { bytes: buf, position: 0 })?))
}
pub fn new_disc_io_from_stream<'a, T: 'a + ReadStream + Sized>(
pub fn new_disc_io_from_stream<'a, T: 'a + ReadStream + Sized + Send + Sync>(
stream: T,
) -> Result<Box<dyn DiscIO + 'a>> {
Ok(Box::from(DiscIOISOStream::new(stream)?))

View File

@ -26,33 +26,31 @@
//! println!(s);
//! }
//! ```
use thiserror::Error;
pub mod disc;
pub mod fst;
pub mod io;
pub mod streams;
#[derive(Debug)]
#[derive(Error, Debug)]
pub enum Error {
BinaryFormat(binread::Error),
Encryption(block_modes::BlockModeError),
Io(String, std::io::Error),
#[error("binary format")]
BinaryFormat(#[from] binread::Error),
#[error("encryption")]
Encryption(#[from] block_modes::BlockModeError),
#[error("io error: `{0}`")]
Io(String, #[source] std::io::Error),
#[error("disc format error: `{0}`")]
DiscFormat(String),
}
pub type Result<T> = std::result::Result<T, Error>;
pub type Result<T> = anyhow::Result<T, Error>;
impl From<std::io::Error> for Error {
fn from(v: std::io::Error) -> Self { Error::Io("I/O error".to_string(), v) }
}
impl From<binread::Error> for Error {
fn from(v: binread::Error) -> Self { Error::BinaryFormat(v) }
}
impl From<block_modes::BlockModeError> for Error {
fn from(v: block_modes::BlockModeError) -> Self { Error::Encryption(v) }
}
#[inline(always)]
pub(crate) fn div_rem<T: std::ops::Div<Output = T> + std::ops::Rem<Output = T> + Copy>(
x: T,

View File

@ -57,7 +57,14 @@ impl ReadStream for File {
let before = self.stream_position()?;
let result = self.seek(SeekFrom::End(0));
// Try to restore position even if the above failed
self.seek(SeekFrom::Start(before))?;
let seek_result = self.seek(SeekFrom::Start(before));
if seek_result.is_err() {
return if result.is_err() {
result
} else {
seek_result
}
}
result
}
@ -104,6 +111,9 @@ impl<'a> SharedWindowedReadStream<'a> {
fn windowed_read(stream: &mut dyn WindowedReadStream, buf: &mut [u8]) -> io::Result<usize> {
let pos = stream.stream_position()?;
let size = stream.stable_stream_len()?;
if pos == size {
return Ok(0);
}
stream.base_stream().read(if pos + buf.len() as u64 > size {
&mut buf[..(size - pos) as usize]
} else {
@ -185,8 +195,10 @@ impl Read for ByteReadStream<'_> {
let total = self.bytes.len();
let pos = self.position as usize;
if len + pos > total {
if pos >= total {
if pos > total {
return Err(io::Error::from(io::ErrorKind::UnexpectedEof));
} else if pos == total {
return Ok(0);
}
len = total - pos;
}