mirror of https://github.com/encounter/nod-rs.git
Various updates
- Use thiserror for nod::Error - Use anyhow for error context chaining - Stream logic fixes
This commit is contained in:
parent
4b32388fa5
commit
8b3f655dc2
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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)?))
|
||||
|
|
24
src/lib.rs
24
src/lib.rs
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue