From aaf9d373069920043b3ed238aaa79ff2c257d04b Mon Sep 17 00:00:00 2001 From: Luke Street Date: Wed, 25 Aug 2021 11:22:17 -0400 Subject: [PATCH] Reformat with rustfmt --- rustfmt.toml | 8 ++++ src/bin.rs | 36 ++++++++++++------ src/disc/gcn.rs | 53 +++++++++++---------------- src/disc/mod.rs | 22 ++++++----- src/disc/wii.rs | 97 ++++++++++++++++++++++++++++++------------------- src/fst.rs | 30 ++++++++++----- src/io/iso.rs | 4 +- src/io/mod.rs | 22 ++++++----- src/io/nfs.rs | 92 ++++++++++++++++++++++------------------------ src/lib.rs | 19 ++++------ src/streams.rs | 85 ++++++++++++++++++++----------------------- 11 files changed, 252 insertions(+), 216 deletions(-) create mode 100644 rustfmt.toml diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..0a9eda5 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,8 @@ +fn_single_line = true +group_imports = "StdExternalCrate" +imports_granularity = "Crate" +overflow_delimited_expr = true +reorder_impl_items = true +use_field_init_shorthand = true +use_small_heuristics = "Max" +where_single_line = true diff --git a/src/bin.rs b/src/bin.rs index 2edf9e6..f547a47 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -1,14 +1,17 @@ -use std::{env, fs, io}; -use std::io::BufWriter; -use std::path::{Path, PathBuf}; +use std::{ + env, fs, io, + io::BufWriter, + path::{Path, PathBuf}, +}; -use clap::{AppSettings, clap_app}; +use clap::{clap_app, AppSettings}; use file_size; - -use nod::disc::{new_disc_base, PartReadStream}; -use nod::fst::NodeType; -use nod::io::{has_extension, new_disc_io}; -use nod::Result; +use nod::{ + disc::{new_disc_base, PartReadStream}, + fst::NodeType, + io::{has_extension, new_disc_io}, + Result, +}; fn main() -> Result<()> { let matches = clap_app!(nodtool => @@ -36,7 +39,8 @@ Phillip Stephens (Antidote)") (@arg DIR: "Output directory (optional)") (@arg quiet: -q "Quiet output") ) - ).get_matches(); + ) + .get_matches(); if let Some(matches) = matches.subcommand_matches("extract") { let file: PathBuf = PathBuf::from(matches.value_of("FILE").unwrap()); let output_dir: PathBuf; @@ -61,12 +65,20 @@ Phillip Stephens (Antidote)") Result::Ok(()) } -fn extract_node(node: &NodeType, partition: &mut dyn PartReadStream, base_path: &Path) -> io::Result<()> { +fn extract_node( + node: &NodeType, + partition: &mut dyn PartReadStream, + base_path: &Path, +) -> io::Result<()> { match node { NodeType::File(v) => { let mut file_path = base_path.to_owned(); file_path.push(v.name.as_ref()); - println!("Extracting {} (size: {})", file_path.to_string_lossy(), file_size::fit_4(v.length as u64)); + println!( + "Extracting {} (size: {})", + file_path.to_string_lossy(), + file_size::fit_4(v.length as u64) + ); let file = fs::File::create(file_path)?; let mut buf_writer = BufWriter::with_capacity(partition.ideal_buffer_size(), file); io::copy(&mut partition.begin_file_stream(v)?, &mut buf_writer)?; diff --git a/src/disc/gcn.rs b/src/disc/gcn.rs index 309f823..15bfd0e 100644 --- a/src/disc/gcn.rs +++ b/src/disc/gcn.rs @@ -1,29 +1,31 @@ -use std::io; -use std::io::{Read, Seek, SeekFrom}; +use std::{ + io, + io::{Read, Seek, SeekFrom}, +}; use binread::prelude::*; -use crate::{div_rem, Result}; -use crate::disc::{BI2Header, BUFFER_SIZE, DiscBase, DiscIO, Header, PartHeader, PartReadStream}; -use crate::fst::{find_node, Node, node_parser, NodeKind, NodeType}; -use crate::streams::{ReadStream, SharedWindowedReadStream}; +use crate::{ + disc::{BI2Header, DiscBase, DiscIO, Header, PartHeader, PartReadStream, BUFFER_SIZE}, + div_rem, + fst::{find_node, node_parser, Node, NodeKind, NodeType}, + streams::{ReadStream, SharedWindowedReadStream}, + Result, +}; pub(crate) struct DiscGCN { pub(crate) header: Header, } -pub(crate) fn new_disc_gcn(header: Header) -> Result { - Result::Ok(DiscGCN { - header - }) -} +pub(crate) fn new_disc_gcn(header: Header) -> Result { Result::Ok(DiscGCN { header }) } impl DiscBase for DiscGCN { - fn get_header(&self) -> &Header { - &self.header - } + fn get_header(&self) -> &Header { &self.header } - fn get_data_partition<'a>(&self, disc_io: &'a mut dyn DiscIO) -> Result> { + fn get_data_partition<'a>( + &self, + disc_io: &'a mut dyn DiscIO, + ) -> Result> { Result::Ok(Box::from(GCPartReadStream { stream: disc_io.begin_read_stream(0)?, offset: 0, @@ -40,7 +42,6 @@ struct GCPartReadStream<'a> { buf: [u8; BUFFER_SIZE], } - impl<'a> Read for GCPartReadStream<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result { let (mut block, mut block_offset) = div_rem(self.offset as usize, BUFFER_SIZE); @@ -86,15 +87,11 @@ impl<'a> Seek for GCPartReadStream<'a> { io::Result::Ok(self.offset) } - fn stream_position(&mut self) -> io::Result { - io::Result::Ok(self.offset) - } + fn stream_position(&mut self) -> io::Result { io::Result::Ok(self.offset) } } impl<'a> ReadStream for GCPartReadStream<'a> { - fn stable_stream_len(&mut self) -> io::Result { - self.stream.stable_stream_len() - } + fn stable_stream_len(&mut self) -> io::Result { self.stream.stable_stream_len() } } impl<'a> PartReadStream for GCPartReadStream<'a> { @@ -108,9 +105,7 @@ impl<'a> PartReadStream for GCPartReadStream<'a> { Result::Ok(Box::from(self.read_be::()?)) } - fn ideal_buffer_size(&self) -> usize { - BUFFER_SIZE - } + fn ideal_buffer_size(&self) -> usize { BUFFER_SIZE } } #[derive(Clone, Debug, PartialEq, BinRead)] @@ -123,11 +118,7 @@ pub(crate) struct GCPartition { } impl PartHeader for GCPartition { - fn root_node(&self) -> &NodeType { - &self.root_node - } + fn root_node(&self) -> &NodeType { &self.root_node } - fn find_node(&self, path: &str) -> Option<&NodeType> { - find_node(&self.root_node, path) - } + fn find_node(&self, path: &str) -> Option<&NodeType> { find_node(&self.root_node, path) } } diff --git a/src/disc/mod.rs b/src/disc/mod.rs index 81d9b8f..0412293 100644 --- a/src/disc/mod.rs +++ b/src/disc/mod.rs @@ -1,15 +1,16 @@ //! Disc type related logic (GameCube, Wii) -use std::fmt::Debug; -use std::io; +use std::{fmt::Debug, io}; -use binread::{BinReaderExt, NullString, prelude::*}; +use binread::{prelude::*, BinReaderExt, NullString}; -use crate::{Error, Result}; -use crate::disc::{gcn::new_disc_gcn, wii::new_disc_wii}; -use crate::fst::{Node, NodeType}; -use crate::io::DiscIO; -use crate::streams::{ReadStream, SharedWindowedReadStream}; +use crate::{ + disc::{gcn::new_disc_gcn, wii::new_disc_wii}, + fst::{Node, NodeType}, + io::DiscIO, + streams::{ReadStream, SharedWindowedReadStream}, + Error, Result, +}; pub(crate) mod gcn; pub(crate) mod wii; @@ -89,7 +90,10 @@ pub trait DiscBase { /// let disc_base = new_disc_base(disc_io.as_mut())?; /// let mut partition = disc_base.get_data_partition(disc_io.as_mut())?; /// ``` - fn get_data_partition<'a>(&self, disc_io: &'a mut dyn DiscIO) -> Result>; + fn get_data_partition<'a>( + &self, + disc_io: &'a mut dyn DiscIO, + ) -> Result>; } /// Creates a new [`DiscBase`] instance. diff --git a/src/disc/wii.rs b/src/disc/wii.rs index b72b423..63e2770 100644 --- a/src/disc/wii.rs +++ b/src/disc/wii.rs @@ -1,19 +1,27 @@ -use std::{io, io::{Read, Seek, SeekFrom}}; +use std::{ + io, + io::{Read, Seek, SeekFrom}, +}; -use aes::{Aes128, NewBlockCipher, Block}; +use aes::{Aes128, Block, NewBlockCipher}; use binread::prelude::*; use block_modes::{block_padding::NoPadding, BlockMode, Cbc}; use sha1::{digest, Digest, Sha1}; -use crate::disc::{BI2Header, BUFFER_SIZE, DiscBase, DiscIO, Header, PartHeader, PartReadStream}; -use crate::{Error, div_rem, Result, array_ref}; -use crate::fst::{find_node, Node, NodeKind, NodeType, node_parser}; -use crate::streams::{OwningWindowedReadStream, ReadStream, SharedWindowedReadStream, wrap_windowed}; +use crate::{ + array_ref, + disc::{BI2Header, DiscBase, DiscIO, Header, PartHeader, PartReadStream, BUFFER_SIZE}, + div_rem, + fst::{find_node, node_parser, Node, NodeKind, NodeType}, + streams::{wrap_windowed, OwningWindowedReadStream, ReadStream, SharedWindowedReadStream}, + Error, Result, +}; type Aes128Cbc = Cbc; const BLOCK_SIZE: usize = 0x7c00; const BUFFER_OFFSET: usize = BUFFER_SIZE - BLOCK_SIZE; +#[rustfmt::skip] const COMMON_KEYS: [[u8; 16]; 2] = [ /* Normal */ [0xeb, 0xe4, 0x2a, 0x22, 0x5e, 0x85, 0x93, 0xe4, 0x48, 0xd9, 0xc5, 0x45, 0x73, 0x81, 0xaa, 0xf7], @@ -185,10 +193,7 @@ pub(crate) struct DiscWii { } pub(crate) fn new_disc_wii(mut stream: &mut dyn ReadStream, header: Header) -> Result { - let mut disc = DiscWii { - header, - part_info: stream.read_be()?, - }; + let mut disc = DiscWii { header, part_info: stream.read_be()? }; disc.decrypt_partition_keys()?; Result::Ok(disc) } @@ -202,29 +207,38 @@ impl DiscWii { Aes128Cbc::new( Aes128::new(&COMMON_KEYS[ticket.common_key_idx as usize].into()), &iv.into(), - ).decrypt(&mut ticket.enc_key)?; + ) + .decrypt(&mut ticket.enc_key)?; } Result::Ok(()) } } impl DiscBase for DiscWii { - fn get_header(&self) -> &Header { - &self.header - } + fn get_header(&self) -> &Header { &self.header } - fn get_data_partition<'a>(&self, disc_io: &'a mut dyn DiscIO) -> Result> { - let part = self.part_info.parts.iter().find(|v| v.part_type == WiiPartType::Data) + fn get_data_partition<'a>( + &self, + disc_io: &'a mut dyn DiscIO, + ) -> Result> { + let part = self + .part_info + .parts + .iter() + .find(|v| v.part_type == WiiPartType::Data) .ok_or(Error::DiscFormat("Failed to locate data partition".to_string()))?; let data_off = part.part_header.data_off; let result = Box::new(WiiPartReadStream { stream: wrap_windowed( disc_io.begin_read_stream(data_off)?, - data_off, part.part_header.data_size, + data_off, + part.part_header.data_size, )?, crypto: if disc_io.has_wii_crypto() { Aes128::new(&part.part_header.ticket.enc_key.into()).into() - } else { Option::None }, + } else { + Option::None + }, offset: 0, cur_block: u64::MAX, buf: [0; 0x8000], @@ -254,9 +268,7 @@ impl<'a> PartReadStream for WiiPartReadStream<'a> { Result::Ok(Box::from(self.read_be::()?)) } - fn ideal_buffer_size(&self) -> usize { - BLOCK_SIZE - } + fn ideal_buffer_size(&self) -> usize { BLOCK_SIZE } } #[inline(always)] @@ -277,7 +289,9 @@ fn decrypt_block(part: &mut WiiPartReadStream, cluster: usize) -> io::Result<()> .decrypt(&mut part.buf[BUFFER_OFFSET..]) .expect("Failed to decrypt block"); } - if part.validate_hashes && part.crypto.is_some() /* FIXME NFS validation? */ { + if part.validate_hashes && part.crypto.is_some() + /* FIXME NFS validation? */ + { let (mut group, sub_group) = div_rem(cluster, 8); group %= 8; // H0 hashes @@ -287,7 +301,12 @@ fn decrypt_block(part: &mut WiiPartReadStream, cluster: usize) -> io::Result<()> let expected = as_digest(array_ref![part.buf, i * 20, 20]); let output = hash.finalize(); if output != expected { - panic!("Invalid hash! (block {:?}) {:?}\n\texpected {:?}", i, output.as_slice(), expected); + panic!( + "Invalid hash! (block {:?}) {:?}\n\texpected {:?}", + i, + output.as_slice(), + expected + ); } } // H1 hash @@ -297,7 +316,12 @@ fn decrypt_block(part: &mut WiiPartReadStream, cluster: usize) -> io::Result<()> let expected = as_digest(array_ref![part.buf, 0x280 + sub_group * 20, 20]); let output = hash.finalize(); if output != expected { - panic!("Invalid hash! (subgroup {:?}) {:?}\n\texpected {:?}", sub_group, output.as_slice(), expected); + panic!( + "Invalid hash! (subgroup {:?}) {:?}\n\texpected {:?}", + sub_group, + output.as_slice(), + expected + ); } } // H2 hash @@ -307,7 +331,12 @@ fn decrypt_block(part: &mut WiiPartReadStream, cluster: usize) -> io::Result<()> let expected = as_digest(array_ref![part.buf, 0x340 + group * 20, 20]); let output = hash.finalize(); if output != expected { - panic!("Invalid hash! (group {:?}) {:?}\n\texpected {:?}", group, output.as_slice(), expected); + panic!( + "Invalid hash! (group {:?}) {:?}\n\texpected {:?}", + group, + output.as_slice(), + expected + ); } } } @@ -331,9 +360,9 @@ impl<'a> Read for WiiPartReadStream<'a> { cache_size = BLOCK_SIZE - block_offset; } - buf[read..read + cache_size] - .copy_from_slice(&self.buf[BUFFER_OFFSET + block_offset.. - BUFFER_OFFSET + block_offset + cache_size]); + buf[read..read + cache_size].copy_from_slice( + &self.buf[BUFFER_OFFSET + block_offset..BUFFER_OFFSET + block_offset + cache_size], + ); read += cache_size; rem -= cache_size; block_offset = 0; @@ -365,9 +394,7 @@ impl<'a> Seek for WiiPartReadStream<'a> { io::Result::Ok(self.offset) } - fn stream_position(&mut self) -> io::Result { - io::Result::Ok(self.offset) - } + fn stream_position(&mut self) -> io::Result { io::Result::Ok(self.offset) } } impl<'a> ReadStream for WiiPartReadStream<'a> { @@ -386,11 +413,7 @@ pub(crate) struct WiiPartition { } impl PartHeader for WiiPartition { - fn root_node(&self) -> &NodeType { - &self.root_node - } + fn root_node(&self) -> &NodeType { &self.root_node } - fn find_node(&self, path: &str) -> Option<&NodeType> { - find_node(&self.root_node, path) - } + fn find_node(&self, path: &str) -> Option<&NodeType> { find_node(&self.root_node, path) } } diff --git a/src/fst.rs b/src/fst.rs index e09cc7d..fa47d70 100644 --- a/src/fst.rs +++ b/src/fst.rs @@ -2,7 +2,7 @@ use std::io::{Read, Seek, SeekFrom}; -use binread::{derive_binread, NullString, prelude::*, ReadOptions}; +use binread::{derive_binread, prelude::*, NullString, ReadOptions}; use encoding_rs::SHIFT_JIS; /// File system node kind. @@ -64,7 +64,13 @@ fn read_node(reader: &mut R, ro: &ReadOptions, i: &mut u32) -> B }) } -fn read_node_name(reader: &mut R, ro: &ReadOptions, base: u64, node: &mut NodeType, root: bool) -> BinResult<()> { +fn read_node_name( + reader: &mut R, + ro: &ReadOptions, + base: u64, + node: &mut NodeType, + root: bool, +) -> BinResult<()> { let mut decode_name = |v: &mut Node| -> BinResult<()> { if !root { let offset = base + v.name_offset as u64; @@ -82,7 +88,9 @@ fn read_node_name(reader: &mut R, ro: &ReadOptions, base: u64, n BinResult::Ok(()) }; match node { - NodeType::File(v) => { decode_name(v)?; } + NodeType::File(v) => { + decode_name(v)?; + } NodeType::Directory(v, c) => { decode_name(v)?; for x in c { @@ -93,7 +101,11 @@ fn read_node_name(reader: &mut R, ro: &ReadOptions, base: u64, n BinResult::Ok(()) } -pub(crate) fn node_parser(reader: &mut R, ro: &ReadOptions, _: ()) -> BinResult { +pub(crate) fn node_parser( + reader: &mut R, + ro: &ReadOptions, + _: (), +) -> BinResult { let mut node = read_node(reader, ro, &mut 0)?; let base = reader.stream_position()?; read_node_name(reader, ro, base, &mut node, true)?; @@ -103,7 +115,9 @@ pub(crate) fn node_parser(reader: &mut R, ro: &ReadOptions, _: ( fn matches_name(node: &NodeType, name: &str) -> bool { match node { NodeType::File(v) => v.name.as_ref().eq_ignore_ascii_case(name), - NodeType::Directory(v, _) => v.name.is_empty() /* root */ || v.name.as_ref().eq_ignore_ascii_case(name), + NodeType::Directory(v, _) => { + v.name.is_empty() /* root */ || v.name.as_ref().eq_ignore_ascii_case(name) + } } } @@ -114,11 +128,7 @@ pub(crate) fn find_node<'a>(mut node: &'a NodeType, path: &str) -> Option<&'a No if matches_name(node, current.unwrap()) { match node { NodeType::File(_) => { - return if split.next().is_none() { - Option::Some(node) - } else { - Option::None - }; + return if split.next().is_none() { Option::Some(node) } else { Option::None }; } NodeType::Directory(v, c) => { // Find child diff --git a/src/io/iso.rs b/src/io/iso.rs index d817032..43417d7 100644 --- a/src/io/iso.rs +++ b/src/io/iso.rs @@ -1,11 +1,11 @@ use std::fs::File; use std::io::{Seek, SeekFrom}; use std::io; -use std::path::{PathBuf, Path}; +use std::path::{Path, PathBuf}; use crate::io::DiscIO; -use crate::streams::ReadStream; use crate::Result; +use crate::streams::ReadStream; pub(crate) struct DiscIOISO { pub(crate) filename: PathBuf, diff --git a/src/io/mod.rs b/src/io/mod.rs index 7ea8b2c..ce479f6 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -1,11 +1,12 @@ //! Disc file format related logic (ISO, NFS, etc) -use std::{fs, io}; -use std::path::Path; +use std::{fs, io, path::Path}; -use crate::{Error, Result}; -use crate::io::{iso::new_disc_io_iso, nfs::new_disc_io_nfs}; -use crate::streams::ReadStream; +use crate::{ + io::{iso::new_disc_io_iso, nfs::new_disc_io_nfs}, + streams::ReadStream, + Error, Result, +}; pub(crate) mod iso; pub(crate) mod nfs; @@ -27,7 +28,9 @@ pub fn has_extension(filename: &Path, extension: &str) -> bool { // TODO use with Rust 1.53+ // ext.eq_ignore_ascii_case(extension) ext.to_str().unwrap_or("").eq_ignore_ascii_case(extension) - } else { false } + } else { + false + } } /// Creates a new [`DiscIO`] instance. @@ -57,9 +60,10 @@ pub fn new_disc_io(filename: &Path) -> Result> { )); } if !meta.unwrap().is_file() { - return Result::Err(Error::DiscFormat( - format!("Input is not a file: {}", filename.to_string_lossy()) - )); + return Result::Err(Error::DiscFormat(format!( + "Input is not a file: {}", + filename.to_string_lossy() + ))); } if has_extension(path, "iso") { Result::Ok(Box::from(new_disc_io_iso(path)?)) diff --git a/src/io/nfs.rs b/src/io/nfs.rs index b6401f1..e1419da 100644 --- a/src/io/nfs.rs +++ b/src/io/nfs.rs @@ -1,13 +1,15 @@ -use std::{fs::File, io, io::{Read, Seek, SeekFrom}, path::{Path, PathBuf}}; +use std::{ + fs::File, + io, + io::{Read, Seek, SeekFrom}, + path::{Path, PathBuf}, +}; use aes::{Aes128, NewBlockCipher}; use binread::{derive_binread, prelude::*}; use block_modes::{block_padding::NoPadding, BlockMode, Cbc}; -use crate::disc::{BUFFER_SIZE}; -use crate::io::DiscIO; -use crate::{Error,Result}; -use crate::streams::ReadStream; +use crate::{disc::BUFFER_SIZE, io::DiscIO, streams::ReadStream, Error, Result}; type Aes128Cbc = Cbc; @@ -39,18 +41,18 @@ pub(crate) struct FBO { pub(crate) offset: u32, } -pub(crate) fn fbo_max() -> FBO { - FBO { - file: u32::MAX, - block: u32::MAX, - l_block: u32::MAX, - offset: u32::MAX, +impl Default for FBO { + fn default() -> Self { + FBO { file: u32::MAX, block: u32::MAX, l_block: u32::MAX, offset: u32::MAX } } } impl NFSHeader { pub(crate) fn calculate_num_files(&self) -> u32 { - let total_block_count = self.lba_ranges.iter().take(self.lba_range_count as usize) + let total_block_count = self + .lba_ranges + .iter() + .take(self.lba_range_count as usize) .fold(0u32, |acc, range| acc + range.num_blocks); (((total_block_count as u64) * 0x8000u64 + (0x200u64 + 0xF9FFFFFu64)) / 0xFA00000u64) as u32 } @@ -68,14 +70,9 @@ impl NFSHeader { physical_block += range.num_blocks; } if block == u32::MAX { - fbo_max() + FBO::default() } else { - FBO { - file: block / 8000, - block: block % 8000, - l_block: block_div, - offset: block_off, - } + FBO { file: block / 8000, block: block % 8000, l_block: block_div, offset: block_off } } } } @@ -87,11 +84,8 @@ pub(crate) struct DiscIONFS { } pub(crate) fn new_disc_io_nfs(directory: &Path) -> Result { - let mut disc_io = DiscIONFS { - directory: directory.to_owned(), - key: [0; 16], - header: Option::None, - }; + let mut disc_io = + DiscIONFS { directory: directory.to_owned(), key: [0; 16], header: Option::None }; disc_io.validate_files()?; Result::Ok(disc_io) } @@ -124,9 +118,10 @@ impl<'a> NFSReadStream<'a> { fn set_cur_block(&mut self, cur_block: u32) -> io::Result<()> { self.cur_block = cur_block; - self.file.as_ref().unwrap().seek( - SeekFrom::Start(self.cur_block as u64 * BUFFER_SIZE as u64 + 0x200u64) - )?; + self.file + .as_ref() + .unwrap() + .seek(SeekFrom::Start(self.cur_block as u64 * BUFFER_SIZE as u64 + 0x200u64))?; io::Result::Ok(()) } @@ -164,6 +159,7 @@ impl<'a> NFSReadStream<'a> { } // Decrypt + #[rustfmt::skip] let iv: [u8; 16] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (phys_addr.l_block & 0xFF) as u8, @@ -171,8 +167,7 @@ impl<'a> NFSReadStream<'a> { ((phys_addr.l_block >> 16) & 0xFF) as u8, ((phys_addr.l_block >> 24) & 0xFF) as u8, ]; - Aes128Cbc::new(self.crypto.clone(), &iv.into()) - .decrypt(&mut self.buf)?; + Aes128Cbc::new(self.crypto.clone(), &iv.into()).decrypt(&mut self.buf)?; Result::Ok(()) } @@ -188,7 +183,8 @@ impl<'a> Read for NFSReadStream<'a> { let mut read: usize = 0; while rem > 0 { let mut read_size = rem; - let block_offset: usize = if self.phys_addr.offset == u32::MAX { 0 } else { self.phys_addr.offset as usize }; + let block_offset: usize = + if self.phys_addr.offset == u32::MAX { 0 } else { self.phys_addr.offset as usize }; if read_size + block_offset > BUFFER_SIZE { read_size = BUFFER_SIZE - block_offset } @@ -197,11 +193,10 @@ impl<'a> Read for NFSReadStream<'a> { read += read_size; rem -= read_size; self.offset += read_size as u64; - self.set_logical_addr(self.offset) - .map_err(|v| match v { - Error::Io(_, v) => v, - _ => io::Error::from(io::ErrorKind::Other) - })?; + self.set_logical_addr(self.offset).map_err(|v| match v { + Error::Io(_, v) => v, + _ => io::Error::from(io::ErrorKind::Other), + })?; } io::Result::Ok(read) } @@ -214,23 +209,18 @@ impl<'a> Seek for NFSReadStream<'a> { SeekFrom::End(v) => (self.stable_stream_len()? as i64 + v) as u64, SeekFrom::Current(v) => (self.offset as i64 + v) as u64, }; - self.set_logical_addr(self.offset) - .map_err(|v| match v { - Error::Io(_, v) => v, - _ => io::Error::from(io::ErrorKind::Other) - })?; + self.set_logical_addr(self.offset).map_err(|v| match v { + Error::Io(_, v) => v, + _ => io::Error::from(io::ErrorKind::Other), + })?; io::Result::Ok(self.offset) } - fn stream_position(&mut self) -> io::Result { - io::Result::Ok(self.offset) - } + fn stream_position(&mut self) -> io::Result { io::Result::Ok(self.offset) } } impl<'a> ReadStream for NFSReadStream<'a> { - fn stable_stream_len(&mut self) -> io::Result { - todo!() - } + fn stable_stream_len(&mut self) -> io::Result { todo!() } } impl DiscIO for DiscIONFS { @@ -239,7 +229,7 @@ impl DiscIO for DiscIONFS { disc_io: self, file: Option::None, crypto: Aes128::new(&self.key.into()), - phys_addr: fbo_max(), + phys_addr: FBO::default(), offset, cur_file: u32::MAX, cur_block: u32::MAX, @@ -282,9 +272,13 @@ impl DiscIONFS { ))); } File::open(key_path.as_path()) - .map_err(|v| Error::Io(format!("Failed to open {}", key_path.to_string_lossy()), v))? + .map_err(|v| { + Error::Io(format!("Failed to open {}", key_path.to_string_lossy()), v) + })? .read(&mut self.key) - .map_err(|v| Error::Io(format!("Failed to read {}", key_path.to_string_lossy()), v))?; + .map_err(|v| { + Error::Io(format!("Failed to read {}", key_path.to_string_lossy()), v) + })?; } { // Load header from first file diff --git a/src/lib.rs b/src/lib.rs index abfef3c..c8e3eb8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,8 +26,8 @@ //! println!(s); //! } //! ``` -pub mod fst; pub mod disc; +pub mod fst; pub mod io; pub mod streams; @@ -42,25 +42,22 @@ pub enum Error { pub type Result = std::result::Result; impl From 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 for Error { - fn from(v: binread::Error) -> Self { - Error::BinaryFormat(v) - } + fn from(v: binread::Error) -> Self { Error::BinaryFormat(v) } } impl From for Error { - fn from(v: block_modes::BlockModeError) -> Self { - Error::Encryption(v) - } + fn from(v: block_modes::BlockModeError) -> Self { Error::Encryption(v) } } #[inline(always)] -pub(crate) fn div_rem + std::ops::Rem + Copy>(x: T, y: T) -> (T, T) { +pub(crate) fn div_rem + std::ops::Rem + Copy>( + x: T, + y: T, +) -> (T, T) { let quot = x / y; let rem = x % y; (quot, rem) diff --git a/src/streams.rs b/src/streams.rs index b46a7ef..a3f4345 100644 --- a/src/streams.rs +++ b/src/streams.rs @@ -1,9 +1,13 @@ //! Common stream types -use std::{fs::File, io, io::{Read, Seek, SeekFrom}}; -use std::ops::DerefMut; +use std::{ + fs::File, + io, + io::{Read, Seek, SeekFrom}, + ops::DerefMut, +}; -/// Creates a fixed-size array from a slice. +/// Creates a fixed-size array reference from a slice. #[macro_export] macro_rules! array_ref { ($slice:expr, $offset:expr, $size:expr) => {{ @@ -12,7 +16,19 @@ macro_rules! array_ref { unsafe { &*(slice.as_ptr() as *const [_; $size]) } } to_array(&$slice[$offset..$offset + $size]) - }} + }}; +} + +/// Creates a mutable fixed-size array reference from a slice. +#[macro_export] +macro_rules! array_ref_mut { + ($slice:expr, $offset:expr, $size:expr) => {{ + #[inline] + fn to_array(slice: &mut [T]) -> &mut [T; $size] { + unsafe { &mut *(slice.as_ptr() as *mut [_; $size]) } + } + to_array(&mut $slice[$offset..$offset + $size]) + }}; } pub trait ReadStream: Read + Seek { @@ -24,13 +40,10 @@ 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 where Self: Sized { + fn new_window(&mut self, offset: u64, size: u64) -> io::Result + where Self: Sized { self.seek(SeekFrom::Start(offset))?; - io::Result::Ok(SharedWindowedReadStream { - base: self, - begin: offset, - end: offset + size, - }) + io::Result::Ok(SharedWindowedReadStream { base: self, begin: offset, end: offset + size }) } } @@ -56,13 +69,13 @@ pub struct OwningWindowedReadStream<'a> { } /// Takes ownership of & wraps a read stream into a windowed read stream. -pub fn wrap_windowed<'a>(mut base: Box, offset: u64, size: u64) -> io::Result> { +pub fn wrap_windowed<'a>( + mut base: Box, + offset: u64, + size: u64, +) -> io::Result> { base.seek(SeekFrom::Start(offset))?; - io::Result::Ok(OwningWindowedReadStream { - base, - begin: offset, - end: offset + size, - }) + io::Result::Ok(OwningWindowedReadStream { base, begin: offset, end: offset + size }) } pub struct SharedWindowedReadStream<'a> { @@ -98,15 +111,11 @@ fn windowed_seek(stream: &mut dyn WindowedReadStream, pos: SeekFrom) -> io::Resu } impl<'a> Read for OwningWindowedReadStream<'a> { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - windowed_read(self, buf) - } + fn read(&mut self, buf: &mut [u8]) -> io::Result { windowed_read(self, buf) } } impl<'a> Seek for OwningWindowedReadStream<'a> { - fn seek(&mut self, pos: SeekFrom) -> io::Result { - windowed_seek(self, pos) - } + fn seek(&mut self, pos: SeekFrom) -> io::Result { windowed_seek(self, pos) } fn stream_position(&mut self) -> io::Result { Result::Ok(self.base.stream_position()? - self.begin) @@ -114,31 +123,21 @@ impl<'a> Seek for OwningWindowedReadStream<'a> { } impl<'a> ReadStream for OwningWindowedReadStream<'a> { - fn stable_stream_len(&mut self) -> io::Result { - Result::Ok(self.end - self.begin) - } + fn stable_stream_len(&mut self) -> io::Result { Result::Ok(self.end - self.begin) } } impl<'a> WindowedReadStream for OwningWindowedReadStream<'a> { - fn base_stream(&mut self) -> &mut dyn ReadStream { - self.base.deref_mut() - } + fn base_stream(&mut self) -> &mut dyn ReadStream { self.base.deref_mut() } - fn window(&self) -> (u64, u64) { - (self.begin, self.end) - } + fn window(&self) -> (u64, u64) { (self.begin, self.end) } } impl<'a> Read for SharedWindowedReadStream<'a> { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - windowed_read(self, buf) - } + fn read(&mut self, buf: &mut [u8]) -> io::Result { windowed_read(self, buf) } } impl<'a> Seek for SharedWindowedReadStream<'a> { - fn seek(&mut self, pos: SeekFrom) -> io::Result { - windowed_seek(self, pos) - } + fn seek(&mut self, pos: SeekFrom) -> io::Result { windowed_seek(self, pos) } fn stream_position(&mut self) -> io::Result { Result::Ok(self.base.stream_position()? - self.begin) @@ -146,17 +145,11 @@ impl<'a> Seek for SharedWindowedReadStream<'a> { } impl<'a> ReadStream for SharedWindowedReadStream<'a> { - fn stable_stream_len(&mut self) -> io::Result { - Result::Ok(self.end - self.begin) - } + fn stable_stream_len(&mut self) -> io::Result { Result::Ok(self.end - self.begin) } } impl<'a> WindowedReadStream for SharedWindowedReadStream<'a> { - fn base_stream(&mut self) -> &mut dyn ReadStream { - self.base - } + fn base_stream(&mut self) -> &mut dyn ReadStream { self.base } - fn window(&self) -> (u64, u64) { - (self.begin, self.end) - } + fn window(&self) -> (u64, u64) { (self.begin, self.end) } }