mirror of
https://github.com/encounter/nod.git
synced 2026-07-10 12:18:48 -07:00
run cargo fmt
This commit is contained in:
+27
-10
@@ -129,7 +129,9 @@ impl GCPartitionBuilder {
|
||||
|
||||
/// A junk file exists in the FST, but is excluded from the disc layout, so junk data will be
|
||||
/// written in its place.
|
||||
pub fn add_junk_file(&mut self, name: String) { self.junk_files.push(name); }
|
||||
pub fn add_junk_file(&mut self, name: String) {
|
||||
self.junk_files.push(name);
|
||||
}
|
||||
|
||||
pub fn build(
|
||||
&self,
|
||||
@@ -630,7 +632,9 @@ impl GCPartitionWriter {
|
||||
}
|
||||
|
||||
pub fn into_cloneable_stream<Cb>(self, file_callback: Cb) -> Result<Box<dyn DiscStream>>
|
||||
where Cb: FileCallback + Clone + 'static {
|
||||
where
|
||||
Cb: FileCallback + Clone + 'static,
|
||||
{
|
||||
Ok(Box::new(CloneableStream::new(GCPartitionStream::new(
|
||||
file_callback,
|
||||
Arc::from(self.write_info),
|
||||
@@ -641,7 +645,9 @@ impl GCPartitionWriter {
|
||||
}
|
||||
|
||||
pub fn into_non_cloneable_stream<Cb>(self, file_callback: Cb) -> Result<Box<dyn DiscStream>>
|
||||
where Cb: FileCallback + 'static {
|
||||
where
|
||||
Cb: FileCallback + 'static,
|
||||
{
|
||||
Ok(Box::new(NonCloneableStream::new(GCPartitionStream::new(
|
||||
file_callback,
|
||||
Arc::from(self.write_info),
|
||||
@@ -658,7 +664,8 @@ struct WriteCursor<W> {
|
||||
}
|
||||
|
||||
impl<W> WriteCursor<W>
|
||||
where W: Write
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
fn write_zeroes_until(&mut self, until: u64) -> io::Result<()> {
|
||||
static ZEROES: [u8; 0x1000] = [0u8; 0x1000];
|
||||
@@ -673,7 +680,8 @@ where W: Write
|
||||
}
|
||||
|
||||
impl<W> Write for WriteCursor<W>
|
||||
where W: Write
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
@@ -683,7 +691,9 @@ where W: Write
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.inner.flush()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -708,14 +718,19 @@ impl<Cb> GCPartitionStream<Cb> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_position(&mut self, pos: u64) { self.pos = pos; }
|
||||
pub fn set_position(&mut self, pos: u64) {
|
||||
self.pos = pos;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn len(&self) -> u64 { self.size }
|
||||
pub fn len(&self) -> u64 {
|
||||
self.size
|
||||
}
|
||||
}
|
||||
|
||||
impl<Cb> Read for GCPartitionStream<Cb>
|
||||
where Cb: FileCallback
|
||||
where
|
||||
Cb: FileCallback,
|
||||
{
|
||||
fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
|
||||
if self.pos >= self.size {
|
||||
@@ -784,7 +799,9 @@ impl<Cb> Seek for GCPartitionStream<Cb> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn gcm_align(n: u64) -> u64 { (n + 31) & !3 }
|
||||
fn gcm_align(n: u64) -> u64 {
|
||||
(n + 31) & !3
|
||||
}
|
||||
|
||||
fn sort_files(files: &mut [WriteInfo]) -> Result<()> {
|
||||
files.sort_unstable_by_key(|info| (info.offset, info.size));
|
||||
|
||||
+15
-5
@@ -66,7 +66,9 @@ impl DirectDiscReader {
|
||||
self.mode = mode;
|
||||
}
|
||||
|
||||
pub fn into_inner(self) -> Box<dyn BlockReader> { self.io }
|
||||
pub fn into_inner(self) -> Box<dyn BlockReader> {
|
||||
self.io
|
||||
}
|
||||
}
|
||||
|
||||
impl BufRead for DirectDiscReader {
|
||||
@@ -115,7 +117,9 @@ impl BufRead for DirectDiscReader {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn consume(&mut self, amt: usize) { self.pos += amt as u64; }
|
||||
fn consume(&mut self, amt: usize) {
|
||||
self.pos += amt as u64;
|
||||
}
|
||||
}
|
||||
|
||||
impl_read_for_bufread!(DirectDiscReader);
|
||||
@@ -135,11 +139,17 @@ impl Seek for DirectDiscReader {
|
||||
Ok(self.pos)
|
||||
}
|
||||
|
||||
fn stream_position(&mut self) -> io::Result<u64> { Ok(self.pos) }
|
||||
fn stream_position(&mut self) -> io::Result<u64> {
|
||||
Ok(self.pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartitionReader for DirectDiscReader {
|
||||
fn is_wii(&self) -> bool { unimplemented!() }
|
||||
fn is_wii(&self) -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn meta(&mut self) -> Result<PartitionMeta> { unimplemented!() }
|
||||
fn meta(&mut self) -> Result<PartitionMeta> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
+18
-6
@@ -77,11 +77,15 @@ impl Node {
|
||||
|
||||
/// Whether the node is a file.
|
||||
#[inline]
|
||||
pub fn is_file(&self) -> bool { self.kind == 0 }
|
||||
pub fn is_file(&self) -> bool {
|
||||
self.kind == 0
|
||||
}
|
||||
|
||||
/// Whether the node is a directory.
|
||||
#[inline]
|
||||
pub fn is_dir(&self) -> bool { self.kind == 1 }
|
||||
pub fn is_dir(&self) -> bool {
|
||||
self.kind == 1
|
||||
}
|
||||
|
||||
/// Offset in the string table to the filename.
|
||||
#[inline]
|
||||
@@ -120,11 +124,15 @@ impl Node {
|
||||
///
|
||||
/// Number of child files and directories recursively is `length - offset`.
|
||||
#[inline]
|
||||
pub fn length(&self) -> u32 { self.length.get() }
|
||||
pub fn length(&self) -> u32 {
|
||||
self.length.get()
|
||||
}
|
||||
|
||||
/// Set the length of the node. See [`Node::length`] for details.
|
||||
#[inline]
|
||||
pub fn set_length(&mut self, length: u32) { self.length.set(length); }
|
||||
pub fn set_length(&mut self, length: u32) {
|
||||
self.length.set(length);
|
||||
}
|
||||
}
|
||||
|
||||
/// A view into the file system table (FST).
|
||||
@@ -154,7 +162,9 @@ impl<'a> Fst<'a> {
|
||||
|
||||
/// Iterate over the nodes in the FST.
|
||||
#[inline]
|
||||
pub fn iter(&self) -> FstIter<'_> { FstIter { fst: self.clone(), idx: 1, segments: vec![] } }
|
||||
pub fn iter(&self) -> FstIter<'_> {
|
||||
FstIter { fst: self.clone(), idx: 1, segments: vec![] }
|
||||
}
|
||||
|
||||
/// Get the name of a node.
|
||||
pub fn get_name(&self, node: Node) -> Result<Cow<'a, str>, String> {
|
||||
@@ -209,7 +219,9 @@ impl<'a> Fst<'a> {
|
||||
}
|
||||
|
||||
/// Count the number of files in the FST.
|
||||
pub fn num_files(&self) -> usize { self.nodes.iter().filter(|n| n.is_file()).count() }
|
||||
pub fn num_files(&self) -> usize {
|
||||
self.nodes.iter().filter(|n| n.is_file()).count()
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator over the nodes in an FST.
|
||||
|
||||
+9
-3
@@ -84,7 +84,9 @@ impl BufRead for PartitionReaderGC {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn consume(&mut self, amt: usize) { self.pos += amt as u64; }
|
||||
fn consume(&mut self, amt: usize) {
|
||||
self.pos += amt as u64;
|
||||
}
|
||||
}
|
||||
|
||||
impl_read_for_bufread!(PartitionReaderGC);
|
||||
@@ -99,11 +101,15 @@ impl Seek for PartitionReaderGC {
|
||||
Ok(self.pos)
|
||||
}
|
||||
|
||||
fn stream_position(&mut self) -> io::Result<u64> { Ok(self.pos) }
|
||||
fn stream_position(&mut self) -> io::Result<u64> {
|
||||
Ok(self.pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartitionReader for PartitionReaderGC {
|
||||
fn is_wii(&self) -> bool { false }
|
||||
fn is_wii(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn meta(&mut self) -> Result<PartitionMeta> {
|
||||
if let Some(meta) = &self.meta {
|
||||
|
||||
+15
-5
@@ -89,7 +89,9 @@ static_assert!(size_of::<DiscHeader>() == 0x400);
|
||||
impl DiscHeader {
|
||||
/// Game ID as a string.
|
||||
#[inline]
|
||||
pub fn game_id_str(&self) -> &str { from_utf8(&self.game_id).unwrap_or("[invalid]") }
|
||||
pub fn game_id_str(&self) -> &str {
|
||||
from_utf8(&self.game_id).unwrap_or("[invalid]")
|
||||
}
|
||||
|
||||
/// Game title as a string.
|
||||
#[inline]
|
||||
@@ -102,19 +104,27 @@ impl DiscHeader {
|
||||
|
||||
/// Whether this is a GameCube disc.
|
||||
#[inline]
|
||||
pub fn is_gamecube(&self) -> bool { self.gcn_magic == GCN_MAGIC }
|
||||
pub fn is_gamecube(&self) -> bool {
|
||||
self.gcn_magic == GCN_MAGIC
|
||||
}
|
||||
|
||||
/// Whether this is a Wii disc.
|
||||
#[inline]
|
||||
pub fn is_wii(&self) -> bool { self.wii_magic == WII_MAGIC }
|
||||
pub fn is_wii(&self) -> bool {
|
||||
self.wii_magic == WII_MAGIC
|
||||
}
|
||||
|
||||
/// Whether the disc has partition data hashes.
|
||||
#[inline]
|
||||
pub fn has_partition_hashes(&self) -> bool { self.no_partition_hashes == 0 }
|
||||
pub fn has_partition_hashes(&self) -> bool {
|
||||
self.no_partition_hashes == 0
|
||||
}
|
||||
|
||||
/// Whether the disc has partition data encryption.
|
||||
#[inline]
|
||||
pub fn has_partition_encryption(&self) -> bool { self.no_partition_encryption == 0 }
|
||||
pub fn has_partition_encryption(&self) -> bool {
|
||||
self.no_partition_encryption == 0
|
||||
}
|
||||
}
|
||||
|
||||
/// The debug block of a disc partition.
|
||||
|
||||
@@ -172,7 +172,9 @@ impl PreloaderCache {
|
||||
self.inflight.remove(&request);
|
||||
}
|
||||
|
||||
fn remove(&mut self, request: &SectorGroupRequest) { self.inflight.remove(request); }
|
||||
fn remove(&mut self, request: &SectorGroupRequest) {
|
||||
self.inflight.remove(request);
|
||||
}
|
||||
|
||||
fn contains(&self, request: &SectorGroupRequest) -> bool {
|
||||
self.lru_cache.contains(request) || self.inflight.contains_key(request)
|
||||
@@ -325,7 +327,9 @@ impl Preloader {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn map_poisoned<T>(_: std::sync::PoisonError<T>) -> io::Error { io::Error::other("Mutex poisoned") }
|
||||
fn map_poisoned<T>(_: std::sync::PoisonError<T>) -> io::Error {
|
||||
io::Error::other("Mutex poisoned")
|
||||
}
|
||||
|
||||
pub struct SectorGroupLoader {
|
||||
io: Box<dyn BlockReader>,
|
||||
|
||||
+15
-5
@@ -163,13 +163,19 @@ impl DiscReader {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reset(&mut self) { self.pos = 0; }
|
||||
pub fn reset(&mut self) {
|
||||
self.pos = 0;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn position(&self) -> u64 { self.pos }
|
||||
pub fn position(&self) -> u64 {
|
||||
self.pos
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn disc_size(&self) -> u64 { self.size }
|
||||
pub fn disc_size(&self) -> u64 {
|
||||
self.size
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn header(&self) -> &DiscHeader {
|
||||
@@ -241,7 +247,9 @@ impl DiscReader {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn meta(&self) -> DiscMeta { self.io.meta() }
|
||||
pub fn meta(&self) -> DiscMeta {
|
||||
self.io.meta()
|
||||
}
|
||||
|
||||
/// Opens a new, decrypted partition read stream for the specified partition index.
|
||||
pub fn open_partition(
|
||||
@@ -400,7 +408,9 @@ impl BufRead for DiscReader {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn consume(&mut self, amt: usize) { self.pos += amt as u64; }
|
||||
fn consume(&mut self, amt: usize) {
|
||||
self.pos += amt as u64;
|
||||
}
|
||||
}
|
||||
|
||||
impl_read_for_bufread!(DiscReader);
|
||||
|
||||
+42
-14
@@ -78,7 +78,9 @@ pub(crate) struct WiiPartEntry {
|
||||
static_assert!(size_of::<WiiPartEntry>() == 8);
|
||||
|
||||
impl WiiPartEntry {
|
||||
pub(crate) fn offset(&self) -> u64 { (self.offset.get() as u64) << 2 }
|
||||
pub(crate) fn offset(&self) -> u64 {
|
||||
(self.offset.get() as u64) << 2
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const WII_PART_GROUP_OFF: u64 = 0x40000;
|
||||
@@ -93,7 +95,9 @@ pub(crate) struct WiiPartGroup {
|
||||
static_assert!(size_of::<WiiPartGroup>() == 8);
|
||||
|
||||
impl WiiPartGroup {
|
||||
pub(crate) fn part_entry_off(&self) -> u64 { (self.part_entry_off.get() as u64) << 2 }
|
||||
pub(crate) fn part_entry_off(&self) -> u64 {
|
||||
(self.part_entry_off.get() as u64) << 2
|
||||
}
|
||||
}
|
||||
|
||||
/// Signed blob header
|
||||
@@ -274,28 +278,44 @@ static_assert!(size_of::<WiiPartitionHeader>() == 0x2C0);
|
||||
|
||||
impl WiiPartitionHeader {
|
||||
/// TMD size in bytes
|
||||
pub fn tmd_size(&self) -> u64 { self.tmd_size.get() as u64 }
|
||||
pub fn tmd_size(&self) -> u64 {
|
||||
self.tmd_size.get() as u64
|
||||
}
|
||||
|
||||
/// TMD offset in bytes (relative to the partition start)
|
||||
pub fn tmd_off(&self) -> u64 { (self.tmd_off.get() as u64) << 2 }
|
||||
pub fn tmd_off(&self) -> u64 {
|
||||
(self.tmd_off.get() as u64) << 2
|
||||
}
|
||||
|
||||
/// Certificate chain size in bytes
|
||||
pub fn cert_chain_size(&self) -> u64 { self.cert_chain_size.get() as u64 }
|
||||
pub fn cert_chain_size(&self) -> u64 {
|
||||
self.cert_chain_size.get() as u64
|
||||
}
|
||||
|
||||
/// Certificate chain offset in bytes (relative to the partition start)
|
||||
pub fn cert_chain_off(&self) -> u64 { (self.cert_chain_off.get() as u64) << 2 }
|
||||
pub fn cert_chain_off(&self) -> u64 {
|
||||
(self.cert_chain_off.get() as u64) << 2
|
||||
}
|
||||
|
||||
/// H3 table offset in bytes (relative to the partition start)
|
||||
pub fn h3_table_off(&self) -> u64 { (self.h3_table_off.get() as u64) << 2 }
|
||||
pub fn h3_table_off(&self) -> u64 {
|
||||
(self.h3_table_off.get() as u64) << 2
|
||||
}
|
||||
|
||||
/// H3 table size in bytes (always H3_TABLE_SIZE)
|
||||
pub fn h3_table_size(&self) -> u64 { H3_TABLE_SIZE as u64 }
|
||||
pub fn h3_table_size(&self) -> u64 {
|
||||
H3_TABLE_SIZE as u64
|
||||
}
|
||||
|
||||
/// Data offset in bytes (relative to the partition start)
|
||||
pub fn data_off(&self) -> u64 { (self.data_off.get() as u64) << 2 }
|
||||
pub fn data_off(&self) -> u64 {
|
||||
(self.data_off.get() as u64) << 2
|
||||
}
|
||||
|
||||
/// Data size in bytes
|
||||
pub fn data_size(&self) -> u64 { (self.data_size.get() as u64) << 2 }
|
||||
pub fn data_size(&self) -> u64 {
|
||||
(self.data_size.get() as u64) << 2
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct PartitionReaderWii {
|
||||
@@ -342,7 +362,9 @@ impl PartitionReaderWii {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn len(&self) -> u64 { self.partition.data_size() }
|
||||
pub fn len(&self) -> u64 {
|
||||
self.partition.data_size()
|
||||
}
|
||||
}
|
||||
|
||||
impl BufRead for PartitionReaderWii {
|
||||
@@ -409,7 +431,9 @@ impl BufRead for PartitionReaderWii {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn consume(&mut self, amt: usize) { self.pos += amt as u64; }
|
||||
fn consume(&mut self, amt: usize) {
|
||||
self.pos += amt as u64;
|
||||
}
|
||||
}
|
||||
|
||||
impl_read_for_bufread!(PartitionReaderWii);
|
||||
@@ -424,7 +448,9 @@ impl Seek for PartitionReaderWii {
|
||||
Ok(self.pos)
|
||||
}
|
||||
|
||||
fn stream_position(&mut self) -> io::Result<u64> { Ok(self.pos) }
|
||||
fn stream_position(&mut self) -> io::Result<u64> {
|
||||
Ok(self.pos)
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_hashes(buf: &[u8; SECTOR_GROUP_SIZE], group_idx: u32, h3_table: &[u8]) -> io::Result<()> {
|
||||
@@ -487,7 +513,9 @@ fn verify_hashes(buf: &[u8; SECTOR_GROUP_SIZE], group_idx: u32, h3_table: &[u8])
|
||||
}
|
||||
|
||||
impl PartitionReader for PartitionReaderWii {
|
||||
fn is_wii(&self) -> bool { true }
|
||||
fn is_wii(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn meta(&mut self) -> Result<PartitionMeta> {
|
||||
if let Some(meta) = &self.meta {
|
||||
|
||||
+3
-1
@@ -116,7 +116,9 @@ pub const WIA_MAGIC: MagicBytes = *b"WIA\x01";
|
||||
pub const RVZ_MAGIC: MagicBytes = *b"RVZ\x01";
|
||||
|
||||
pub fn detect<R>(stream: &mut R) -> io::Result<Option<Format>>
|
||||
where R: Read + ?Sized {
|
||||
where
|
||||
R: Read + ?Sized,
|
||||
{
|
||||
match read_from(stream) {
|
||||
Ok(ref magic) => Ok(detect_internal(magic)),
|
||||
Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => Ok(None),
|
||||
|
||||
+9
-3
@@ -182,7 +182,9 @@ impl BlockReader for BlockReaderGCZ {
|
||||
Ok(Block::new(block_idx, block_size, BlockKind::Raw))
|
||||
}
|
||||
|
||||
fn block_size(&self) -> u32 { self.header.block_size.get() }
|
||||
fn block_size(&self) -> u32 {
|
||||
self.header.block_size.get()
|
||||
}
|
||||
|
||||
fn meta(&self) -> DiscMeta {
|
||||
DiscMeta {
|
||||
@@ -358,7 +360,11 @@ impl DiscWriter for DiscWriterGCZ {
|
||||
Ok(finalization)
|
||||
}
|
||||
|
||||
fn progress_bound(&self) -> u64 { self.header.disc_size.get() }
|
||||
fn progress_bound(&self) -> u64 {
|
||||
self.header.disc_size.get()
|
||||
}
|
||||
|
||||
fn weight(&self) -> DiscWriterWeight { DiscWriterWeight::Heavy }
|
||||
fn weight(&self) -> DiscWriterWeight {
|
||||
DiscWriterWeight::Heavy
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -43,7 +43,9 @@ impl BlockReader for BlockReaderISO {
|
||||
Ok(Block::sector(sector, BlockKind::Raw))
|
||||
}
|
||||
|
||||
fn block_size(&self) -> u32 { SECTOR_SIZE as u32 }
|
||||
fn block_size(&self) -> u32 {
|
||||
SECTOR_SIZE as u32
|
||||
}
|
||||
|
||||
fn meta(&self) -> DiscMeta {
|
||||
DiscMeta {
|
||||
@@ -83,7 +85,11 @@ impl DiscWriter for DiscReader {
|
||||
Ok(finalization)
|
||||
}
|
||||
|
||||
fn progress_bound(&self) -> u64 { self.disc_size() }
|
||||
fn progress_bound(&self) -> u64 {
|
||||
self.disc_size()
|
||||
}
|
||||
|
||||
fn weight(&self) -> DiscWriterWeight { DiscWriterWeight::Light }
|
||||
fn weight(&self) -> DiscWriterWeight {
|
||||
DiscWriterWeight::Light
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -58,7 +58,9 @@ impl NFSHeader {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn lba_ranges(&self) -> &[LBARange] { &self.lba_ranges[..self.num_lba_ranges.get() as usize] }
|
||||
fn lba_ranges(&self) -> &[LBARange] {
|
||||
&self.lba_ranges[..self.num_lba_ranges.get() as usize]
|
||||
}
|
||||
|
||||
fn calculate_num_files(&self) -> u32 {
|
||||
let sector_count =
|
||||
@@ -126,7 +128,9 @@ impl BlockReader for BlockReaderNFS {
|
||||
Ok(Block::sector(sector, BlockKind::PartDecrypted { hash_block: true }))
|
||||
}
|
||||
|
||||
fn block_size(&self) -> u32 { SECTOR_SIZE as u32 }
|
||||
fn block_size(&self) -> u32 {
|
||||
SECTOR_SIZE as u32
|
||||
}
|
||||
|
||||
fn meta(&self) -> DiscMeta {
|
||||
DiscMeta { format: Format::Nfs, decrypted: true, ..Default::default() }
|
||||
@@ -134,7 +138,9 @@ impl BlockReader for BlockReaderNFS {
|
||||
}
|
||||
|
||||
fn get_path<P>(directory: &Path, path: P) -> PathBuf
|
||||
where P: AsRef<Path> {
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let mut buf = directory.to_path_buf();
|
||||
for component in path.as_ref().components() {
|
||||
match component {
|
||||
|
||||
+18
-6
@@ -108,7 +108,9 @@ impl NKitHeader {
|
||||
}
|
||||
|
||||
pub fn read_from<R>(reader: &mut R, block_size: u32, has_junk_bits: bool) -> io::Result<Self>
|
||||
where R: Read + ?Sized {
|
||||
where
|
||||
R: Read + ?Sized,
|
||||
{
|
||||
let version_string: [u8; 8] = read_from(reader)?;
|
||||
if version_string[0..7] != VERSION_PREFIX
|
||||
|| version_string[7] < b'1'
|
||||
@@ -202,7 +204,9 @@ impl NKitHeader {
|
||||
}
|
||||
|
||||
pub fn write_to<W>(&self, w: &mut W) -> io::Result<()>
|
||||
where W: Write + ?Sized {
|
||||
where
|
||||
W: Write + ?Sized,
|
||||
{
|
||||
w.write_all(&VERSION_PREFIX)?;
|
||||
w.write_all(&[b'0' + self.version])?;
|
||||
let flags = self.calc_flags();
|
||||
@@ -266,15 +270,21 @@ impl NKitHeader {
|
||||
pub struct JunkBits(Vec<u8>);
|
||||
|
||||
impl JunkBits {
|
||||
pub fn new(block_size: u32) -> Self { Self(vec![0; Self::len(block_size)]) }
|
||||
pub fn new(block_size: u32) -> Self {
|
||||
Self(vec![0; Self::len(block_size)])
|
||||
}
|
||||
|
||||
pub fn read_from<R>(reader: &mut R, block_size: u32) -> io::Result<Self>
|
||||
where R: Read + ?Sized {
|
||||
where
|
||||
R: Read + ?Sized,
|
||||
{
|
||||
Ok(Self(read_vec(reader, Self::len(block_size))?))
|
||||
}
|
||||
|
||||
pub fn write_to<W>(&self, w: &mut W) -> io::Result<()>
|
||||
where W: Write + ?Sized {
|
||||
where
|
||||
W: Write + ?Sized,
|
||||
{
|
||||
w.write_all(&self.0)
|
||||
}
|
||||
|
||||
@@ -307,7 +317,9 @@ pub struct ReadAdapter<'a> {
|
||||
}
|
||||
|
||||
impl<'a> ReadAdapter<'a> {
|
||||
pub fn new(reader: &'a mut dyn DiscStream, offset: u64) -> Self { Self { reader, pos: offset } }
|
||||
pub fn new(reader: &'a mut dyn DiscStream, offset: u64) -> Self {
|
||||
Self { reader, pos: offset }
|
||||
}
|
||||
}
|
||||
|
||||
impl Read for ReadAdapter<'_> {
|
||||
|
||||
+15
-5
@@ -20,7 +20,9 @@ struct Split<T> {
|
||||
}
|
||||
|
||||
impl<T> Split<T> {
|
||||
fn contains(&self, pos: u64) -> bool { self.begin <= pos && pos < self.begin + self.size }
|
||||
fn contains(&self, pos: u64) -> bool {
|
||||
self.begin <= pos && pos < self.begin + self.size
|
||||
}
|
||||
}
|
||||
|
||||
// .iso.1, .iso.2, etc.
|
||||
@@ -56,7 +58,9 @@ fn split_path_3(input: &Path, index: u32) -> PathBuf {
|
||||
}
|
||||
|
||||
impl SplitFileReader {
|
||||
pub fn empty() -> Self { Self { files: Vec::new(), open_file: Default::default() } }
|
||||
pub fn empty() -> Self {
|
||||
Self { files: Vec::new(), open_file: Default::default() }
|
||||
}
|
||||
|
||||
pub fn new(path: &Path) -> Result<Self> {
|
||||
let mut files = vec![];
|
||||
@@ -97,11 +101,15 @@ impl SplitFileReader {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn len(&self) -> u64 { self.files.last().map_or(0, |f| f.begin + f.size) }
|
||||
pub fn len(&self) -> u64 {
|
||||
self.files.last().map_or(0, |f| f.begin + f.size)
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for SplitFileReader {
|
||||
fn clone(&self) -> Self { Self { files: self.files.clone(), open_file: Default::default() } }
|
||||
fn clone(&self) -> Self {
|
||||
Self { files: self.files.clone(), open_file: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl DiscStream for SplitFileReader {
|
||||
@@ -138,5 +146,7 @@ impl DiscStream for SplitFileReader {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn stream_len(&mut self) -> io::Result<u64> { Ok(self.len()) }
|
||||
fn stream_len(&mut self) -> io::Result<u64> {
|
||||
Ok(self.len())
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -167,7 +167,9 @@ impl BlockReader for BlockReaderTGC {
|
||||
Ok(Block::sectors(sector, count, if read == 0 { BlockKind::None } else { BlockKind::Raw }))
|
||||
}
|
||||
|
||||
fn block_size(&self) -> u32 { SECTOR_SIZE as u32 }
|
||||
fn block_size(&self) -> u32 {
|
||||
SECTOR_SIZE as u32
|
||||
}
|
||||
|
||||
fn meta(&self) -> DiscMeta {
|
||||
DiscMeta { format: Format::Tgc, disc_size: Some(self.inner.len()), ..Default::default() }
|
||||
@@ -329,7 +331,11 @@ impl DiscWriter for DiscWriterTGC {
|
||||
Ok(DiscFinalization::default())
|
||||
}
|
||||
|
||||
fn progress_bound(&self) -> u64 { self.output_size }
|
||||
fn progress_bound(&self) -> u64 {
|
||||
self.output_size
|
||||
}
|
||||
|
||||
fn weight(&self) -> DiscWriterWeight { DiscWriterWeight::Light }
|
||||
fn weight(&self) -> DiscWriterWeight {
|
||||
DiscWriterWeight::Light
|
||||
}
|
||||
}
|
||||
|
||||
+20
-8
@@ -45,11 +45,17 @@ struct WBFSHeader {
|
||||
}
|
||||
|
||||
impl WBFSHeader {
|
||||
fn sector_size(&self) -> u32 { 1 << self.sector_size_shift }
|
||||
fn sector_size(&self) -> u32 {
|
||||
1 << self.sector_size_shift
|
||||
}
|
||||
|
||||
fn block_size(&self) -> u32 { 1 << self.block_size_shift }
|
||||
fn block_size(&self) -> u32 {
|
||||
1 << self.block_size_shift
|
||||
}
|
||||
|
||||
fn max_blocks(&self) -> u32 { NUM_WII_SECTORS >> (self.block_size_shift - 15) }
|
||||
fn max_blocks(&self) -> u32 {
|
||||
NUM_WII_SECTORS >> (self.block_size_shift - 15)
|
||||
}
|
||||
}
|
||||
|
||||
const DISC_HEADER_SIZE: usize = 0x100;
|
||||
@@ -143,7 +149,9 @@ impl BlockReader for BlockReaderWBFS {
|
||||
Ok(Block::new(block_idx, block_size, BlockKind::Raw))
|
||||
}
|
||||
|
||||
fn block_size(&self) -> u32 { self.header.block_size() }
|
||||
fn block_size(&self) -> u32 {
|
||||
self.header.block_size()
|
||||
}
|
||||
|
||||
fn meta(&self) -> DiscMeta {
|
||||
let mut result = DiscMeta {
|
||||
@@ -201,7 +209,7 @@ impl BlockProcessor for BlockProcessorWBFS {
|
||||
&mut self.lfg,
|
||||
self.disc_id,
|
||||
self.disc_num,
|
||||
self.scrub_update_partition
|
||||
self.scrub_update_partition,
|
||||
)? {
|
||||
CheckBlockResult::Normal => {
|
||||
BlockResult { block_idx, disc_data, block_data, meta: CheckBlockResult::Normal }
|
||||
@@ -321,7 +329,7 @@ impl DiscWriter for DiscWriterWBFS {
|
||||
lfg: LaggedFibonacci::default(),
|
||||
disc_id,
|
||||
disc_num,
|
||||
scrub_update_partition: options.scrub_update_partition
|
||||
scrub_update_partition: options.scrub_update_partition,
|
||||
},
|
||||
self.block_count as u32,
|
||||
options.processor_threads,
|
||||
@@ -383,7 +391,11 @@ impl DiscWriter for DiscWriterWBFS {
|
||||
Ok(finalization)
|
||||
}
|
||||
|
||||
fn progress_bound(&self) -> u64 { self.inner.disc_size() }
|
||||
fn progress_bound(&self) -> u64 {
|
||||
self.inner.disc_size()
|
||||
}
|
||||
|
||||
fn weight(&self) -> DiscWriterWeight { DiscWriterWeight::Medium }
|
||||
fn weight(&self) -> DiscWriterWeight {
|
||||
DiscWriterWeight::Medium
|
||||
}
|
||||
}
|
||||
|
||||
+41
-16
@@ -118,7 +118,9 @@ impl WIAFileHeader {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_rvz(&self) -> bool { self.magic == RVZ_MAGIC }
|
||||
pub fn is_rvz(&self) -> bool {
|
||||
self.magic == RVZ_MAGIC
|
||||
}
|
||||
}
|
||||
|
||||
/// Disc kind
|
||||
@@ -140,7 +142,9 @@ impl From<DiscKind> for u32 {
|
||||
}
|
||||
|
||||
impl From<DiscKind> for U32 {
|
||||
fn from(value: DiscKind) -> Self { u32::from(value).into() }
|
||||
fn from(value: DiscKind) -> Self {
|
||||
u32::from(value).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for DiscKind {
|
||||
@@ -186,7 +190,9 @@ impl From<WIACompression> for u32 {
|
||||
}
|
||||
|
||||
impl From<WIACompression> for U32 {
|
||||
fn from(value: WIACompression) -> Self { u32::from(value).into() }
|
||||
fn from(value: WIACompression) -> Self {
|
||||
u32::from(value).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for WIACompression {
|
||||
@@ -332,9 +338,13 @@ pub struct WIAPartitionData {
|
||||
static_assert!(size_of::<WIAPartitionData>() == 0x10);
|
||||
|
||||
impl WIAPartitionData {
|
||||
pub fn start_sector(&self) -> u32 { self.first_sector.get() }
|
||||
pub fn start_sector(&self) -> u32 {
|
||||
self.first_sector.get()
|
||||
}
|
||||
|
||||
pub fn end_sector(&self) -> u32 { self.first_sector.get() + self.num_sectors.get() }
|
||||
pub fn end_sector(&self) -> u32 {
|
||||
self.first_sector.get() + self.num_sectors.get()
|
||||
}
|
||||
|
||||
pub fn contains_sector(&self, sector: u32) -> bool {
|
||||
let start = self.first_sector.get();
|
||||
@@ -399,11 +409,17 @@ pub struct WIARawData {
|
||||
}
|
||||
|
||||
impl WIARawData {
|
||||
pub fn start_offset(&self) -> u64 { self.raw_data_offset.get().align_down(SECTOR_SIZE as u64) }
|
||||
pub fn start_offset(&self) -> u64 {
|
||||
self.raw_data_offset.get().align_down(SECTOR_SIZE as u64)
|
||||
}
|
||||
|
||||
pub fn start_sector(&self) -> u32 { (self.start_offset() / SECTOR_SIZE as u64) as u32 }
|
||||
pub fn start_sector(&self) -> u32 {
|
||||
(self.start_offset() / SECTOR_SIZE as u64) as u32
|
||||
}
|
||||
|
||||
pub fn end_offset(&self) -> u64 { self.raw_data_offset.get() + self.raw_data_size.get() }
|
||||
pub fn end_offset(&self) -> u64 {
|
||||
self.raw_data_offset.get() + self.raw_data_size.get()
|
||||
}
|
||||
|
||||
pub fn end_sector(&self) -> u32 {
|
||||
// Round up for unaligned raw data end offsets
|
||||
@@ -465,10 +481,14 @@ const COMPRESSED_BIT: u32 = 1 << 31;
|
||||
|
||||
impl RVZGroup {
|
||||
#[inline]
|
||||
pub fn data_size(&self) -> u32 { self.data_size_and_flag.get() & !COMPRESSED_BIT }
|
||||
pub fn data_size(&self) -> u32 {
|
||||
self.data_size_and_flag.get() & !COMPRESSED_BIT
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_compressed(&self) -> bool { self.data_size_and_flag.get() & COMPRESSED_BIT != 0 }
|
||||
pub fn is_compressed(&self) -> bool {
|
||||
self.data_size_and_flag.get() & COMPRESSED_BIT != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&WIAGroup> for RVZGroup {
|
||||
@@ -968,10 +988,11 @@ impl BlockReader for BlockReaderWIA {
|
||||
}
|
||||
|
||||
let mut block = if info.in_partition {
|
||||
let mut block =
|
||||
Block::sectors(info.sector, info.num_sectors, BlockKind::PartDecrypted {
|
||||
hash_block: false,
|
||||
});
|
||||
let mut block = Block::sectors(
|
||||
info.sector,
|
||||
info.num_sectors,
|
||||
BlockKind::PartDecrypted { hash_block: false },
|
||||
);
|
||||
block.hash_exceptions = exception_lists.into_boxed_slice();
|
||||
block
|
||||
} else {
|
||||
@@ -981,7 +1002,9 @@ impl BlockReader for BlockReaderWIA {
|
||||
Ok(block)
|
||||
}
|
||||
|
||||
fn block_size(&self) -> u32 { self.disc.chunk_size.get() }
|
||||
fn block_size(&self) -> u32 {
|
||||
self.disc.chunk_size.get()
|
||||
}
|
||||
|
||||
fn meta(&self) -> DiscMeta {
|
||||
let level = self.disc.compression_level.get();
|
||||
@@ -1877,7 +1900,9 @@ impl DiscWriter for DiscWriterWIA {
|
||||
Ok(finalization)
|
||||
}
|
||||
|
||||
fn progress_bound(&self) -> u64 { self.inner.disc_size() }
|
||||
fn progress_bound(&self) -> u64 {
|
||||
self.inner.disc_size()
|
||||
}
|
||||
|
||||
fn weight(&self) -> DiscWriterWeight {
|
||||
if self.disc.compression() == WIACompression::None {
|
||||
|
||||
+21
-8
@@ -173,12 +173,16 @@ pub enum Error {
|
||||
|
||||
impl From<&str> for Error {
|
||||
#[inline]
|
||||
fn from(s: &str) -> Error { Error::Other(s.to_string()) }
|
||||
fn from(s: &str) -> Error {
|
||||
Error::Other(s.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Error {
|
||||
#[inline]
|
||||
fn from(s: String) -> Error { Error::Other(s) }
|
||||
fn from(s: String) -> Error {
|
||||
Error::Other(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<zerocopy::AllocError> for Error {
|
||||
@@ -202,7 +206,9 @@ pub trait ErrorContext {
|
||||
|
||||
impl ErrorContext for std::io::Error {
|
||||
#[inline]
|
||||
fn context(self, context: impl Into<String>) -> Error { Error::Io(context.into(), self) }
|
||||
fn context(self, context: impl Into<String>) -> Error {
|
||||
Error::Io(context.into(), self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper trait for adding context to result errors.
|
||||
@@ -212,11 +218,13 @@ pub trait ResultContext<T> {
|
||||
|
||||
/// Adds context to a result error using a closure.
|
||||
fn with_context<F>(self, f: F) -> Result<T>
|
||||
where F: FnOnce() -> String;
|
||||
where
|
||||
F: FnOnce() -> String;
|
||||
}
|
||||
|
||||
impl<T, E> ResultContext<T> for Result<T, E>
|
||||
where E: ErrorContext
|
||||
where
|
||||
E: ErrorContext,
|
||||
{
|
||||
#[inline]
|
||||
fn context(self, context: impl Into<String>) -> Result<T> {
|
||||
@@ -225,7 +233,9 @@ where E: ErrorContext
|
||||
|
||||
#[inline]
|
||||
fn with_context<F>(self, f: F) -> Result<T>
|
||||
where F: FnOnce() -> String {
|
||||
where
|
||||
F: FnOnce() -> String,
|
||||
{
|
||||
self.map_err(|e| e.context(f()))
|
||||
}
|
||||
}
|
||||
@@ -245,7 +255,8 @@ pub(crate) trait IoResultContext<T> {
|
||||
fn io_context(self, context: impl Into<String>) -> std::io::Result<T>;
|
||||
|
||||
fn io_with_context<F>(self, f: F) -> std::io::Result<T>
|
||||
where F: FnOnce() -> String;
|
||||
where
|
||||
F: FnOnce() -> String;
|
||||
}
|
||||
|
||||
impl<T> IoResultContext<T> for std::io::Result<T> {
|
||||
@@ -256,7 +267,9 @@ impl<T> IoResultContext<T> for std::io::Result<T> {
|
||||
|
||||
#[inline]
|
||||
fn io_with_context<F>(self, f: F) -> std::io::Result<T>
|
||||
where F: FnOnce() -> String {
|
||||
where
|
||||
F: FnOnce() -> String,
|
||||
{
|
||||
self.map_err(|e| e.io_context(f()))
|
||||
}
|
||||
}
|
||||
|
||||
+73
-27
@@ -91,7 +91,8 @@ pub trait DiscStream: DynClone + Send {
|
||||
dyn_clone::clone_trait_object!(DiscStream);
|
||||
|
||||
impl<T> DiscStream for T
|
||||
where T: AsRef<[u8]> + Send + Clone
|
||||
where
|
||||
T: AsRef<[u8]> + Send + Clone,
|
||||
{
|
||||
fn read_exact_at(&mut self, buf: &mut [u8], offset: u64) -> io::Result<()> {
|
||||
let data = self.as_ref();
|
||||
@@ -104,44 +105,60 @@ where T: AsRef<[u8]> + Send + Clone
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn stream_len(&mut self) -> io::Result<u64> { Ok(self.as_ref().len() as u64) }
|
||||
fn stream_len(&mut self) -> io::Result<u64> {
|
||||
Ok(self.as_ref().len() as u64)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct CloneableStream<T>(pub T)
|
||||
where T: Read + Seek + Clone + Send;
|
||||
where
|
||||
T: Read + Seek + Clone + Send;
|
||||
|
||||
impl<T> CloneableStream<T>
|
||||
where T: Read + Seek + Clone + Send
|
||||
where
|
||||
T: Read + Seek + Clone + Send,
|
||||
{
|
||||
pub fn new(stream: T) -> Self { Self(stream) }
|
||||
pub fn new(stream: T) -> Self {
|
||||
Self(stream)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DiscStream for CloneableStream<T>
|
||||
where T: Read + Seek + Clone + Send
|
||||
where
|
||||
T: Read + Seek + Clone + Send,
|
||||
{
|
||||
fn read_exact_at(&mut self, buf: &mut [u8], offset: u64) -> io::Result<()> {
|
||||
self.0.seek(io::SeekFrom::Start(offset))?;
|
||||
self.0.read_exact(buf)
|
||||
}
|
||||
|
||||
fn stream_len(&mut self) -> io::Result<u64> { self.0.seek(io::SeekFrom::End(0)) }
|
||||
fn stream_len(&mut self) -> io::Result<u64> {
|
||||
self.0.seek(io::SeekFrom::End(0))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct NonCloneableStream<T>(pub Arc<Mutex<T>>)
|
||||
where T: Read + Seek + Send;
|
||||
where
|
||||
T: Read + Seek + Send;
|
||||
|
||||
impl<T> Clone for NonCloneableStream<T>
|
||||
where T: Read + Seek + Send
|
||||
where
|
||||
T: Read + Seek + Send,
|
||||
{
|
||||
fn clone(&self) -> Self { Self(self.0.clone()) }
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> NonCloneableStream<T>
|
||||
where T: Read + Seek + Send
|
||||
where
|
||||
T: Read + Seek + Send,
|
||||
{
|
||||
pub fn new(stream: T) -> Self { Self(Arc::new(Mutex::new(stream))) }
|
||||
pub fn new(stream: T) -> Self {
|
||||
Self(Arc::new(Mutex::new(stream)))
|
||||
}
|
||||
|
||||
fn lock(&self) -> io::Result<std::sync::MutexGuard<'_, T>> {
|
||||
self.0.lock().map_err(|_| io::Error::other("NonCloneableStream mutex poisoned"))
|
||||
@@ -149,7 +166,8 @@ where T: Read + Seek + Send
|
||||
}
|
||||
|
||||
impl<T> DiscStream for NonCloneableStream<T>
|
||||
where T: Read + Seek + Send
|
||||
where
|
||||
T: Read + Seek + Send,
|
||||
{
|
||||
fn read_exact_at(&mut self, buf: &mut [u8], offset: u64) -> io::Result<()> {
|
||||
let mut stream = self.lock()?;
|
||||
@@ -194,7 +212,9 @@ impl DiscReader {
|
||||
/// access (e.g. for preloading blocks during reading or parallel block processing during
|
||||
/// conversion).
|
||||
pub fn new_from_cloneable_read<R>(stream: R, options: &DiscOptions) -> Result<DiscReader>
|
||||
where R: Read + Seek + Clone + Send + 'static {
|
||||
where
|
||||
R: Read + Seek + Clone + Send + 'static,
|
||||
{
|
||||
Self::new_stream(Box::new(CloneableStream::new(stream)), options)
|
||||
}
|
||||
|
||||
@@ -203,40 +223,54 @@ impl DiscReader {
|
||||
/// Multithreaded accesses will be synchronized, which will limit performance (e.g. for
|
||||
/// preloading blocks during reading or parallel block processing during conversion).
|
||||
pub fn new_from_non_cloneable_read<R>(stream: R, options: &DiscOptions) -> Result<DiscReader>
|
||||
where R: Read + Seek + Send + 'static {
|
||||
where
|
||||
R: Read + Seek + Send + 'static,
|
||||
{
|
||||
Self::new_stream(Box::new(NonCloneableStream::new(stream)), options)
|
||||
}
|
||||
|
||||
/// Detects the format of a disc image from a read stream.
|
||||
#[inline]
|
||||
pub fn detect<R>(stream: &mut R) -> io::Result<Option<Format>>
|
||||
where R: Read + ?Sized {
|
||||
where
|
||||
R: Read + ?Sized,
|
||||
{
|
||||
block::detect(stream)
|
||||
}
|
||||
|
||||
/// The disc's primary header.
|
||||
#[inline]
|
||||
pub fn header(&self) -> &DiscHeader { self.0.header() }
|
||||
pub fn header(&self) -> &DiscHeader {
|
||||
self.0.header()
|
||||
}
|
||||
|
||||
/// The Wii disc's region information.
|
||||
///
|
||||
/// **GameCube**: This will return `None`.
|
||||
#[inline]
|
||||
pub fn region(&self) -> Option<&[u8; REGION_SIZE]> { self.0.region() }
|
||||
pub fn region(&self) -> Option<&[u8; REGION_SIZE]> {
|
||||
self.0.region()
|
||||
}
|
||||
|
||||
/// Returns extra metadata included in the disc file format, if any.
|
||||
#[inline]
|
||||
pub fn meta(&self) -> DiscMeta { self.0.meta() }
|
||||
pub fn meta(&self) -> DiscMeta {
|
||||
self.0.meta()
|
||||
}
|
||||
|
||||
/// The disc's size in bytes, or an estimate if not stored by the format.
|
||||
#[inline]
|
||||
pub fn disc_size(&self) -> u64 { self.0.disc_size() }
|
||||
pub fn disc_size(&self) -> u64 {
|
||||
self.0.disc_size()
|
||||
}
|
||||
|
||||
/// A list of Wii partitions on the disc.
|
||||
///
|
||||
/// **GameCube**: This will return an empty slice.
|
||||
#[inline]
|
||||
pub fn partitions(&self) -> &[PartitionInfo] { self.0.partitions() }
|
||||
pub fn partitions(&self) -> &[PartitionInfo] {
|
||||
self.0.partitions()
|
||||
}
|
||||
|
||||
/// Opens a decrypted partition read stream for the specified partition index.
|
||||
///
|
||||
@@ -263,25 +297,35 @@ impl DiscReader {
|
||||
self.0.open_partition_kind(kind, options)
|
||||
}
|
||||
|
||||
pub(crate) fn into_inner(self) -> disc::reader::DiscReader { self.0 }
|
||||
pub(crate) fn into_inner(self) -> disc::reader::DiscReader {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl BufRead for DiscReader {
|
||||
#[inline]
|
||||
fn fill_buf(&mut self) -> io::Result<&[u8]> { self.0.fill_buf() }
|
||||
fn fill_buf(&mut self) -> io::Result<&[u8]> {
|
||||
self.0.fill_buf()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn consume(&mut self, amt: usize) { self.0.consume(amt) }
|
||||
fn consume(&mut self, amt: usize) {
|
||||
self.0.consume(amt)
|
||||
}
|
||||
}
|
||||
|
||||
impl Read for DiscReader {
|
||||
#[inline]
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.0.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl Seek for DiscReader {
|
||||
#[inline]
|
||||
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> { self.0.seek(pos) }
|
||||
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
|
||||
self.0.seek(pos)
|
||||
}
|
||||
}
|
||||
|
||||
/// Extra metadata about the underlying disc file format.
|
||||
@@ -475,7 +519,9 @@ impl PartitionMeta {
|
||||
|
||||
/// A view into the file system table (FST).
|
||||
#[inline]
|
||||
pub fn fst(&self) -> Result<Fst<'_>, &'static str> { Fst::new(&self.raw_fst) }
|
||||
pub fn fst(&self) -> Result<Fst<'_>, &'static str> {
|
||||
Fst::new(&self.raw_fst)
|
||||
}
|
||||
|
||||
/// A view into the DOL header.
|
||||
#[inline]
|
||||
|
||||
+61
-21
@@ -31,12 +31,16 @@ pub fn sha1_hash(buf: &[u8]) -> HashBytes {
|
||||
/// Hashes a byte slice with XXH64.
|
||||
#[allow(unused_braces)] // https://github.com/rust-lang/rust/issues/116347
|
||||
#[instrument(skip_all)]
|
||||
pub fn xxh64_hash(buf: &[u8]) -> u64 { xxhash_rust::xxh64::xxh64(buf, 0) }
|
||||
pub fn xxh64_hash(buf: &[u8]) -> u64 {
|
||||
xxhash_rust::xxh64::xxh64(buf, 0)
|
||||
}
|
||||
|
||||
pub type DigestThread = (Sender<Bytes>, JoinHandle<DigestResult>);
|
||||
|
||||
pub fn digest_thread<H>() -> DigestThread
|
||||
where H: Hasher + Send + 'static {
|
||||
where
|
||||
H: Hasher + Send + 'static,
|
||||
{
|
||||
let (tx, rx) = crossbeam_channel::bounded::<Bytes>(1);
|
||||
let handle = thread::Builder::new()
|
||||
.name(format!("Digest {}", H::NAME))
|
||||
@@ -131,43 +135,63 @@ pub trait Hasher {
|
||||
impl Hasher for md5::Md5 {
|
||||
const NAME: &'static str = "MD5";
|
||||
|
||||
fn new() -> Self { Digest::new() }
|
||||
fn new() -> Self {
|
||||
Digest::new()
|
||||
}
|
||||
|
||||
fn finalize(self) -> DigestResult { DigestResult::Md5(Digest::finalize(self).into()) }
|
||||
fn finalize(self) -> DigestResult {
|
||||
DigestResult::Md5(Digest::finalize(self).into())
|
||||
}
|
||||
|
||||
#[allow(unused_braces)] // https://github.com/rust-lang/rust/issues/116347
|
||||
#[instrument(name = "md5::Md5::update", skip_all)]
|
||||
fn update(&mut self, data: &[u8]) { Digest::update(self, data) }
|
||||
fn update(&mut self, data: &[u8]) {
|
||||
Digest::update(self, data)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hasher for sha1::Sha1 {
|
||||
const NAME: &'static str = "SHA-1";
|
||||
|
||||
fn new() -> Self { Digest::new() }
|
||||
fn new() -> Self {
|
||||
Digest::new()
|
||||
}
|
||||
|
||||
fn finalize(self) -> DigestResult { DigestResult::Sha1(Digest::finalize(self).into()) }
|
||||
fn finalize(self) -> DigestResult {
|
||||
DigestResult::Sha1(Digest::finalize(self).into())
|
||||
}
|
||||
|
||||
#[allow(unused_braces)] // https://github.com/rust-lang/rust/issues/116347
|
||||
#[instrument(name = "sha1::Sha1::update", skip_all)]
|
||||
fn update(&mut self, data: &[u8]) { Digest::update(self, data) }
|
||||
fn update(&mut self, data: &[u8]) {
|
||||
Digest::update(self, data)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hasher for crc32fast::Hasher {
|
||||
const NAME: &'static str = "CRC32";
|
||||
|
||||
fn new() -> Self { crc32fast::Hasher::new() }
|
||||
fn new() -> Self {
|
||||
crc32fast::Hasher::new()
|
||||
}
|
||||
|
||||
fn finalize(self) -> DigestResult { DigestResult::Crc32(crc32fast::Hasher::finalize(self)) }
|
||||
fn finalize(self) -> DigestResult {
|
||||
DigestResult::Crc32(crc32fast::Hasher::finalize(self))
|
||||
}
|
||||
|
||||
#[allow(unused_braces)] // https://github.com/rust-lang/rust/issues/116347
|
||||
#[instrument(name = "crc32fast::Hasher::update", skip_all)]
|
||||
fn update(&mut self, data: &[u8]) { crc32fast::Hasher::update(self, data) }
|
||||
fn update(&mut self, data: &[u8]) {
|
||||
crc32fast::Hasher::update(self, data)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hasher for xxhash_rust::xxh64::Xxh64 {
|
||||
const NAME: &'static str = "XXH64";
|
||||
|
||||
fn new() -> Self { xxhash_rust::xxh64::Xxh64::new(0) }
|
||||
fn new() -> Self {
|
||||
xxhash_rust::xxh64::Xxh64::new(0)
|
||||
}
|
||||
|
||||
fn finalize(self) -> DigestResult {
|
||||
DigestResult::Xxh64(xxhash_rust::xxh64::Xxh64::digest(&self))
|
||||
@@ -175,7 +199,9 @@ impl Hasher for xxhash_rust::xxh64::Xxh64 {
|
||||
|
||||
#[allow(unused_braces)] // https://github.com/rust-lang/rust/issues/116347
|
||||
#[instrument(name = "xxhash_rust::xxh64::Xxh64::update", skip_all)]
|
||||
fn update(&mut self, data: &[u8]) { xxhash_rust::xxh64::Xxh64::update(self, data) }
|
||||
fn update(&mut self, data: &[u8]) {
|
||||
xxhash_rust::xxh64::Xxh64::update(self, data)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
@@ -188,14 +214,16 @@ mod openssl_util {
|
||||
pub type HasherSHA1 = HashWrapper<MessageDigestSHA1>;
|
||||
|
||||
pub struct HashWrapper<T>
|
||||
where T: MessageDigest
|
||||
where
|
||||
T: MessageDigest,
|
||||
{
|
||||
hasher: openssl::hash::Hasher,
|
||||
_marker: std::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> HashWrapper<T>
|
||||
where T: MessageDigest
|
||||
where
|
||||
T: MessageDigest,
|
||||
{
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
@@ -212,19 +240,25 @@ mod openssl_util {
|
||||
pub struct MessageDigestMD5;
|
||||
|
||||
impl MessageDigest for MessageDigestMD5 {
|
||||
fn new() -> openssl::hash::MessageDigest { openssl::hash::MessageDigest::md5() }
|
||||
fn new() -> openssl::hash::MessageDigest {
|
||||
openssl::hash::MessageDigest::md5()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MessageDigestSHA1;
|
||||
|
||||
impl MessageDigest for MessageDigestSHA1 {
|
||||
fn new() -> openssl::hash::MessageDigest { openssl::hash::MessageDigest::sha1() }
|
||||
fn new() -> openssl::hash::MessageDigest {
|
||||
openssl::hash::MessageDigest::sha1()
|
||||
}
|
||||
}
|
||||
|
||||
impl Hasher for HasherMD5 {
|
||||
const NAME: &'static str = "MD5";
|
||||
|
||||
fn new() -> Self { Self::new() }
|
||||
fn new() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
|
||||
fn finalize(mut self) -> DigestResult {
|
||||
DigestResult::Md5((*self.hasher.finish().unwrap()).try_into().unwrap())
|
||||
@@ -232,13 +266,17 @@ mod openssl_util {
|
||||
|
||||
#[allow(unused_braces)] // https://github.com/rust-lang/rust/issues/116347
|
||||
#[instrument(name = "openssl_util::HasherMD5::update", skip_all)]
|
||||
fn update(&mut self, data: &[u8]) { self.hasher.update(data).unwrap() }
|
||||
fn update(&mut self, data: &[u8]) {
|
||||
self.hasher.update(data).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Hasher for HasherSHA1 {
|
||||
const NAME: &'static str = "SHA-1";
|
||||
|
||||
fn new() -> Self { Self::new() }
|
||||
fn new() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
|
||||
fn finalize(mut self) -> DigestResult {
|
||||
DigestResult::Sha1((*self.hasher.finish().unwrap()).try_into().unwrap())
|
||||
@@ -246,7 +284,9 @@ mod openssl_util {
|
||||
|
||||
#[allow(unused_braces)] // https://github.com/rust-lang/rust/issues/116347
|
||||
#[instrument(name = "openssl_util::HasherSHA1::update", skip_all)]
|
||||
fn update(&mut self, data: &[u8]) { self.hasher.update(data).unwrap() }
|
||||
fn update(&mut self, data: &[u8]) {
|
||||
self.hasher.update(data).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user