mirror of https://github.com/encounter/nod-rs.git
Cleanup & add as_dyn to ReadStream
This commit is contained in:
parent
dc5217dd04
commit
35388db458
|
@ -7,9 +7,9 @@ use std::{
|
|||
use clap::{clap_app, AppSettings};
|
||||
use file_size;
|
||||
use nod::{
|
||||
disc::{new_disc_base, PartReadStream},
|
||||
disc::{new_disc_base, DiscBase, PartReadStream},
|
||||
fst::NodeType,
|
||||
io::{has_extension, new_disc_io},
|
||||
io::{has_extension, new_disc_io, DiscIO},
|
||||
Result,
|
||||
};
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@ pub(crate) struct DiscGCN {
|
|||
pub(crate) header: Header,
|
||||
}
|
||||
|
||||
pub(crate) fn new_disc_gcn(header: Header) -> Result<DiscGCN> { Result::Ok(DiscGCN { header }) }
|
||||
impl DiscGCN {
|
||||
pub(crate) fn new(header: Header) -> Result<DiscGCN> { Result::Ok(DiscGCN { header }) }
|
||||
}
|
||||
|
||||
impl DiscBase for DiscGCN {
|
||||
fn get_header(&self) -> &Header { &self.header }
|
||||
|
@ -92,6 +94,8 @@ impl<'a> Seek for GCPartReadStream<'a> {
|
|||
|
||||
impl<'a> ReadStream for GCPartReadStream<'a> {
|
||||
fn stable_stream_len(&mut self) -> io::Result<u64> { self.stream.stable_stream_len() }
|
||||
|
||||
fn as_dyn(&mut self) -> &mut dyn ReadStream { self }
|
||||
}
|
||||
|
||||
impl<'a> PartReadStream for GCPartReadStream<'a> {
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::{fmt::Debug, io};
|
|||
use binread::{prelude::*, BinReaderExt, NullString};
|
||||
|
||||
use crate::{
|
||||
disc::{gcn::new_disc_gcn, wii::new_disc_wii},
|
||||
disc::{gcn::DiscGCN, wii::DiscWii},
|
||||
fst::{Node, NodeType},
|
||||
io::DiscIO,
|
||||
streams::{ReadStream, SharedWindowedReadStream},
|
||||
|
@ -113,9 +113,9 @@ pub fn new_disc_base(disc_io: &mut dyn DiscIO) -> Result<Box<dyn DiscBase>> {
|
|||
let mut stream = disc_io.begin_read_stream(0)?;
|
||||
let header: Header = stream.read_be()?;
|
||||
if header.wii_magic == 0x5D1C9EA3 {
|
||||
Result::Ok(Box::from(new_disc_wii(stream.as_mut(), header)?))
|
||||
Result::Ok(Box::from(DiscWii::new(stream.as_mut(), header)?))
|
||||
} else if header.gcn_magic == 0xC2339F3D {
|
||||
Result::Ok(Box::from(new_disc_gcn(header)?))
|
||||
Result::Ok(Box::from(DiscGCN::new(header)?))
|
||||
} else {
|
||||
Result::Err(Error::DiscFormat("Invalid GC/Wii magic".to_string()))
|
||||
}
|
||||
|
|
|
@ -192,10 +192,12 @@ pub(crate) struct DiscWii {
|
|||
part_info: WiiPartInfo,
|
||||
}
|
||||
|
||||
pub(crate) fn new_disc_wii(mut stream: &mut dyn ReadStream, header: Header) -> Result<DiscWii> {
|
||||
impl DiscWii {
|
||||
pub(crate) fn new(mut stream: &mut dyn ReadStream, header: Header) -> Result<DiscWii> {
|
||||
let mut disc = DiscWii { header, part_info: stream.read_be()? };
|
||||
disc.decrypt_partition_keys()?;
|
||||
Result::Ok(disc)
|
||||
}
|
||||
}
|
||||
|
||||
impl DiscWii {
|
||||
|
@ -401,6 +403,8 @@ impl<'a> ReadStream for WiiPartReadStream<'a> {
|
|||
fn stable_stream_len(&mut self) -> io::Result<u64> {
|
||||
io::Result::Ok(to_block_size(self.stream.stable_stream_len()?))
|
||||
}
|
||||
|
||||
fn as_dyn(&mut self) -> &mut dyn ReadStream { self }
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, BinRead)]
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
use std::fs::File;
|
||||
use std::io::{Seek, SeekFrom};
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{
|
||||
fs::File,
|
||||
io,
|
||||
io::{Seek, SeekFrom},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use crate::io::DiscIO;
|
||||
use crate::Result;
|
||||
use crate::streams::ReadStream;
|
||||
use crate::{io::DiscIO, streams::ReadStream, Result};
|
||||
|
||||
pub(crate) struct DiscIOISO {
|
||||
pub(crate) filename: PathBuf,
|
||||
}
|
||||
|
||||
pub(crate) fn new_disc_io_iso(filename: &Path) -> Result<DiscIOISO> {
|
||||
Result::Ok(DiscIOISO {
|
||||
filename: filename.to_owned(),
|
||||
})
|
||||
impl DiscIOISO {
|
||||
pub(crate) fn new(filename: &Path) -> Result<DiscIOISO> {
|
||||
Result::Ok(DiscIOISO { filename: filename.to_owned() })
|
||||
}
|
||||
}
|
||||
|
||||
impl DiscIO for DiscIOISO {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use std::{fs, io, path::Path};
|
||||
|
||||
use crate::{
|
||||
io::{iso::new_disc_io_iso, nfs::new_disc_io_nfs},
|
||||
io::{iso::DiscIOISO, nfs::DiscIONFS},
|
||||
streams::ReadStream,
|
||||
Error, Result,
|
||||
};
|
||||
|
@ -21,18 +21,6 @@ pub trait DiscIO {
|
|||
fn has_wii_crypto(&self) -> bool { true }
|
||||
}
|
||||
|
||||
/// Helper function for checking a file extension.
|
||||
#[inline(always)]
|
||||
pub fn has_extension(filename: &Path, extension: &str) -> bool {
|
||||
if let Some(ext) = filename.extension() {
|
||||
// TODO use with Rust 1.53+
|
||||
// ext.eq_ignore_ascii_case(extension)
|
||||
ext.to_str().unwrap_or("").eq_ignore_ascii_case(extension)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new [`DiscIO`] instance.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -66,10 +54,10 @@ pub fn new_disc_io(filename: &Path) -> Result<Box<dyn DiscIO>> {
|
|||
)));
|
||||
}
|
||||
if has_extension(path, "iso") {
|
||||
Result::Ok(Box::from(new_disc_io_iso(path)?))
|
||||
Result::Ok(Box::from(DiscIOISO::new(path)?))
|
||||
} else if has_extension(path, "nfs") {
|
||||
if matches!(path.parent(), Some(parent) if parent.is_dir()) {
|
||||
Result::Ok(Box::from(new_disc_io_nfs(path.parent().unwrap())?))
|
||||
Result::Ok(Box::from(DiscIONFS::new(path.parent().unwrap())?))
|
||||
} else {
|
||||
Result::Err(Error::DiscFormat("Failed to locate NFS parent directory".to_string()))
|
||||
}
|
||||
|
@ -77,3 +65,15 @@ pub fn new_disc_io(filename: &Path) -> Result<Box<dyn DiscIO>> {
|
|||
Result::Err(Error::DiscFormat("Unknown file type".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function for checking a file extension.
|
||||
#[inline(always)]
|
||||
pub fn has_extension(filename: &Path, extension: &str) -> bool {
|
||||
if let Some(ext) = filename.extension() {
|
||||
// TODO use with Rust 1.53+
|
||||
// ext.eq_ignore_ascii_case(extension)
|
||||
ext.to_str().unwrap_or("").eq_ignore_ascii_case(extension)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,11 +83,13 @@ pub(crate) struct DiscIONFS {
|
|||
pub(crate) header: Option<NFSHeader>,
|
||||
}
|
||||
|
||||
pub(crate) fn new_disc_io_nfs(directory: &Path) -> Result<DiscIONFS> {
|
||||
impl DiscIONFS {
|
||||
pub(crate) fn new(directory: &Path) -> Result<DiscIONFS> {
|
||||
let mut disc_io =
|
||||
DiscIONFS { directory: directory.to_owned(), key: [0; 16], header: Option::None };
|
||||
disc_io.validate_files()?;
|
||||
Result::Ok(disc_io)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct NFSReadStream<'a> {
|
||||
|
@ -221,6 +223,8 @@ impl<'a> Seek for NFSReadStream<'a> {
|
|||
|
||||
impl<'a> ReadStream for NFSReadStream<'a> {
|
||||
fn stable_stream_len(&mut self) -> io::Result<u64> { todo!() }
|
||||
|
||||
fn as_dyn(&mut self) -> &mut dyn ReadStream { self }
|
||||
}
|
||||
|
||||
impl DiscIO for DiscIONFS {
|
||||
|
|
|
@ -40,11 +40,16 @@ pub trait ReadStream: Read + Seek {
|
|||
/// Creates a windowed read sub-stream with offset and size.
|
||||
///
|
||||
/// Seeks underlying stream immediately.
|
||||
fn new_window(&mut self, offset: u64, size: u64) -> io::Result<SharedWindowedReadStream>
|
||||
where Self: Sized {
|
||||
fn new_window(&mut self, offset: u64, size: u64) -> io::Result<SharedWindowedReadStream> {
|
||||
self.seek(SeekFrom::Start(offset))?;
|
||||
io::Result::Ok(SharedWindowedReadStream { base: self, begin: offset, end: offset + size })
|
||||
io::Result::Ok(SharedWindowedReadStream {
|
||||
base: self.as_dyn(),
|
||||
begin: offset,
|
||||
end: offset + size,
|
||||
})
|
||||
}
|
||||
|
||||
fn as_dyn(&mut self) -> &mut dyn ReadStream;
|
||||
}
|
||||
|
||||
impl ReadStream for File {
|
||||
|
@ -55,6 +60,8 @@ impl ReadStream for File {
|
|||
self.seek(SeekFrom::Start(before))?;
|
||||
result
|
||||
}
|
||||
|
||||
fn as_dyn(&mut self) -> &mut dyn ReadStream { self }
|
||||
}
|
||||
|
||||
trait WindowedReadStream: ReadStream {
|
||||
|
@ -84,6 +91,15 @@ pub struct SharedWindowedReadStream<'a> {
|
|||
pub end: u64,
|
||||
}
|
||||
|
||||
impl<'a> SharedWindowedReadStream<'a> {
|
||||
pub fn set_window(&mut self, begin: u64, end: u64) -> io::Result<()> {
|
||||
self.base.seek(SeekFrom::Start(begin))?;
|
||||
self.begin = begin;
|
||||
self.end = end;
|
||||
io::Result::Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn windowed_read(stream: &mut dyn WindowedReadStream, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let pos = stream.stream_position()?;
|
||||
|
@ -124,6 +140,8 @@ impl<'a> Seek for OwningWindowedReadStream<'a> {
|
|||
|
||||
impl<'a> ReadStream for OwningWindowedReadStream<'a> {
|
||||
fn stable_stream_len(&mut self) -> io::Result<u64> { Result::Ok(self.end - self.begin) }
|
||||
|
||||
fn as_dyn(&mut self) -> &mut dyn ReadStream { self }
|
||||
}
|
||||
|
||||
impl<'a> WindowedReadStream for OwningWindowedReadStream<'a> {
|
||||
|
@ -146,6 +164,8 @@ impl<'a> Seek for SharedWindowedReadStream<'a> {
|
|||
|
||||
impl<'a> ReadStream for SharedWindowedReadStream<'a> {
|
||||
fn stable_stream_len(&mut self) -> io::Result<u64> { Result::Ok(self.end - self.begin) }
|
||||
|
||||
fn as_dyn(&mut self) -> &mut dyn ReadStream { self }
|
||||
}
|
||||
|
||||
impl<'a> WindowedReadStream for SharedWindowedReadStream<'a> {
|
||||
|
|
Loading…
Reference in New Issue