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]
|
[package]
|
||||||
name = "nod"
|
name = "nod"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
authors = ["Luke Street <luke@street.dev>"]
|
authors = ["Luke Street <luke@street.dev>"]
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
@ -19,9 +19,11 @@ path = "src/bin.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aes = "0.7.4"
|
aes = "0.7.4"
|
||||||
|
anyhow = "1.0.53"
|
||||||
binread = "2.1.1"
|
binread = "2.1.1"
|
||||||
block-modes = "0.8.1"
|
block-modes = "0.8.1"
|
||||||
clap = "2.33.3"
|
clap = "2.33.3"
|
||||||
encoding_rs = "0.8.28"
|
encoding_rs = "0.8.28"
|
||||||
file-size = "1.0.3"
|
file-size = "1.0.3"
|
||||||
sha-1 = "0.9.7"
|
sha-1 = "0.9.7"
|
||||||
|
thiserror = "1.0.30"
|
||||||
|
|
|
@ -73,7 +73,7 @@ pub(crate) struct BI2Header {
|
||||||
pub(crate) const BUFFER_SIZE: usize = 0x8000;
|
pub(crate) const BUFFER_SIZE: usize = 0x8000;
|
||||||
|
|
||||||
/// Contains a disc's header & partition information.
|
/// Contains a disc's header & partition information.
|
||||||
pub trait DiscBase {
|
pub trait DiscBase: Send + Sync {
|
||||||
/// Retrieves the disc's header.
|
/// Retrieves the disc's header.
|
||||||
fn get_header(&self) -> &Header;
|
fn get_header(&self) -> &Header;
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ pub trait PartReadStream: ReadStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disc partition header with file system table.
|
/// Disc partition header with file system table.
|
||||||
pub trait PartHeader: Debug {
|
pub trait PartHeader: Debug + Send + Sync {
|
||||||
/// The root node for the filesystem.
|
/// The root node for the filesystem.
|
||||||
fn root_node(&self) -> &NodeType;
|
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>> {
|
fn begin_read_stream<'a>(&'a mut self, offset: u64) -> io::Result<Box<dyn ReadStream + 'a>> {
|
||||||
let size = self.stream.stable_stream_len()?;
|
let size = self.stream.stable_stream_len()?;
|
||||||
let mut stream = self.stream.new_window(0, size)?;
|
let mut stream = self.stream.new_window(0, size)?;
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub(crate) mod iso;
|
||||||
pub(crate) mod nfs;
|
pub(crate) mod nfs;
|
||||||
|
|
||||||
/// Abstraction over supported disc file types.
|
/// Abstraction over supported disc file types.
|
||||||
pub trait DiscIO {
|
pub trait DiscIO: Send + Sync {
|
||||||
/// Opens a new read stream for the disc file(s).
|
/// Opens a new read stream for the disc file(s).
|
||||||
/// Generally does _not_ need to be used directly.
|
/// Generally does _not_ need to be used directly.
|
||||||
fn begin_read_stream(&mut self, offset: u64) -> io::Result<Box<dyn ReadStream + '_>>;
|
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 })?))
|
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,
|
stream: T,
|
||||||
) -> Result<Box<dyn DiscIO + 'a>> {
|
) -> Result<Box<dyn DiscIO + 'a>> {
|
||||||
Ok(Box::from(DiscIOISOStream::new(stream)?))
|
Ok(Box::from(DiscIOISOStream::new(stream)?))
|
||||||
|
|
24
src/lib.rs
24
src/lib.rs
|
@ -26,33 +26,31 @@
|
||||||
//! println!(s);
|
//! println!(s);
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
pub mod disc;
|
pub mod disc;
|
||||||
pub mod fst;
|
pub mod fst;
|
||||||
pub mod io;
|
pub mod io;
|
||||||
pub mod streams;
|
pub mod streams;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
BinaryFormat(binread::Error),
|
#[error("binary format")]
|
||||||
Encryption(block_modes::BlockModeError),
|
BinaryFormat(#[from] binread::Error),
|
||||||
Io(String, std::io::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),
|
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 {
|
impl From<std::io::Error> for Error {
|
||||||
fn from(v: std::io::Error) -> Self { Error::Io("I/O error".to_string(), v) }
|
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)]
|
#[inline(always)]
|
||||||
pub(crate) fn div_rem<T: std::ops::Div<Output = T> + std::ops::Rem<Output = T> + Copy>(
|
pub(crate) fn div_rem<T: std::ops::Div<Output = T> + std::ops::Rem<Output = T> + Copy>(
|
||||||
x: T,
|
x: T,
|
||||||
|
|
|
@ -57,7 +57,14 @@ impl ReadStream for File {
|
||||||
let before = self.stream_position()?;
|
let before = self.stream_position()?;
|
||||||
let result = self.seek(SeekFrom::End(0));
|
let result = self.seek(SeekFrom::End(0));
|
||||||
// Try to restore position even if the above failed
|
// 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
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +111,9 @@ impl<'a> SharedWindowedReadStream<'a> {
|
||||||
fn windowed_read(stream: &mut dyn WindowedReadStream, buf: &mut [u8]) -> io::Result<usize> {
|
fn windowed_read(stream: &mut dyn WindowedReadStream, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
let pos = stream.stream_position()?;
|
let pos = stream.stream_position()?;
|
||||||
let size = stream.stable_stream_len()?;
|
let size = stream.stable_stream_len()?;
|
||||||
|
if pos == size {
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
stream.base_stream().read(if pos + buf.len() as u64 > size {
|
stream.base_stream().read(if pos + buf.len() as u64 > size {
|
||||||
&mut buf[..(size - pos) as usize]
|
&mut buf[..(size - pos) as usize]
|
||||||
} else {
|
} else {
|
||||||
|
@ -185,8 +195,10 @@ impl Read for ByteReadStream<'_> {
|
||||||
let total = self.bytes.len();
|
let total = self.bytes.len();
|
||||||
let pos = self.position as usize;
|
let pos = self.position as usize;
|
||||||
if len + pos > total {
|
if len + pos > total {
|
||||||
if pos >= total {
|
if pos > total {
|
||||||
return Err(io::Error::from(io::ErrorKind::UnexpectedEof));
|
return Err(io::Error::from(io::ErrorKind::UnexpectedEof));
|
||||||
|
} else if pos == total {
|
||||||
|
return Ok(0);
|
||||||
}
|
}
|
||||||
len = total - pos;
|
len = total - pos;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue