Upgrade to zerocopy 0.8

This commit is contained in:
Luke Street 2024-10-03 20:57:02 -06:00
parent 5f537f0e7b
commit 30bcf4936b
23 changed files with 170 additions and 168 deletions

92
Cargo.lock generated
View File

@ -85,12 +85,6 @@ dependencies = [
"generic-array",
]
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bzip2"
version = "0.4.4"
@ -123,9 +117,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.1.18"
version = "1.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476"
checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938"
dependencies = [
"jobserver",
"libc",
@ -352,9 +346,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.158"
version = "0.2.159"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
[[package]]
name = "liblzma"
@ -367,9 +361,9 @@ dependencies = [
[[package]]
name = "liblzma-sys"
version = "0.3.7"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "885d379719f1be90c51852451dc658009c1aab2eb867cae8d5eb7f83bfaaca96"
checksum = "6630cb23edeb2e563cd6c30d4117554c69646871455843c33ddcb1d9aef82ecf"
dependencies = [
"cc",
"libc",
@ -515,9 +509,12 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "once_cell"
version = "1.19.0"
version = "1.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1"
dependencies = [
"portable-atomic",
]
[[package]]
name = "overload"
@ -533,15 +530,15 @@ checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "pkg-config"
version = "0.3.30"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "portable-atomic"
version = "1.7.0"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265"
checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2"
[[package]]
name = "proc-macro2"
@ -566,9 +563,9 @@ dependencies = [
[[package]]
name = "quick-xml"
version = "0.36.1"
version = "0.36.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96a05e2e8efddfa51a84ca47cec303fac86c8541b686d37cac5efc0e094417bc"
checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe"
dependencies = [
"memchr",
"serde",
@ -605,14 +602,14 @@ dependencies = [
[[package]]
name = "regex"
version = "1.10.6"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.4.7",
"regex-syntax 0.8.4",
"regex-automata 0.4.8",
"regex-syntax 0.8.5",
]
[[package]]
@ -626,13 +623,13 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.4.7"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.8.4",
"regex-syntax 0.8.5",
]
[[package]]
@ -643,9 +640,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.8.4"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "serde"
@ -664,7 +661,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@ -737,9 +734,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.77"
version = "2.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
dependencies = [
"proc-macro2",
"quote",
@ -748,22 +745,22 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.63"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.63"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@ -795,7 +792,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@ -854,15 +851,15 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.12"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "unicode-width"
version = "0.1.13"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
name = "valuable"
@ -1036,23 +1033,22 @@ checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984"
[[package]]
name = "zerocopy"
version = "0.7.35"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
checksum = "df7885ffcb82507a0f213c593e77c5f13d12cb96588d4e835ad7e9423ba034db"
dependencies = [
"byteorder",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
checksum = "930ad75608219e8ffdb8962a5433cb2b30064c7ccb564d3b76c2963390b1e435"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]

View File

@ -38,5 +38,5 @@ miniz_oxide = { version = "0.8", optional = true }
rayon = "1.10"
sha1 = "0.10"
thiserror = "1.0"
zerocopy = { version = "0.7", features = ["alloc", "derive"] }
zerocopy = { version = "0.8", features = ["alloc", "derive"] }
zstd = { version = "0.13", optional = true }

View File

@ -3,7 +3,7 @@
use std::{borrow::Cow, ffi::CStr, mem::size_of};
use encoding_rs::SHIFT_JIS;
use zerocopy::{big_endian::*, AsBytes, FromBytes, FromZeroes};
use zerocopy::{big_endian::*, FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{static_assert, Result};
@ -19,7 +19,7 @@ pub enum NodeKind {
}
/// An individual file system node.
#[derive(Copy, Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Copy, Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct Node {
kind: u8,
@ -89,7 +89,7 @@ impl<'a> Fst<'a> {
/// Create a new FST view from a buffer.
#[allow(clippy::missing_inline_in_public_items)]
pub fn new(buf: &'a [u8]) -> Result<Self, &'static str> {
let Some(root_node) = Node::ref_from_prefix(buf) else {
let Ok((root_node, _)) = Node::ref_from_prefix(buf) else {
return Err("FST root node not found");
};
// String table starts after the last node
@ -98,7 +98,7 @@ impl<'a> Fst<'a> {
return Err("FST string table out of bounds");
}
let (node_buf, string_table) = buf.split_at(string_base as usize);
let nodes = Node::slice_from(node_buf).unwrap();
let nodes = <[Node]>::ref_from_bytes(node_buf).unwrap();
Ok(Self { nodes, string_table })
}

View File

@ -4,7 +4,7 @@ use std::{
mem::size_of,
};
use zerocopy::{FromBytes, FromZeroes};
use zerocopy::{FromBytes, FromZeros};
use super::{
ApploaderHeader, DiscHeader, DolHeader, FileStream, Node, PartitionBase, PartitionHeader,
@ -33,9 +33,9 @@ impl Clone for PartitionGC {
Self {
io: self.io.clone(),
block: Block::default(),
block_buf: <u8>::new_box_slice_zeroed(self.block_buf.len()),
block_buf: <[u8]>::new_box_zeroed_with_elems(self.block_buf.len()).unwrap(),
block_idx: u32::MAX,
sector_buf: <[u8; SECTOR_SIZE]>::new_box_zeroed(),
sector_buf: <[u8; SECTOR_SIZE]>::new_box_zeroed().unwrap(),
sector: u32::MAX,
pos: 0,
disc_header: self.disc_header.clone(),
@ -49,9 +49,9 @@ impl PartitionGC {
Ok(Box::new(Self {
io: inner,
block: Block::default(),
block_buf: <u8>::new_box_slice_zeroed(block_size as usize),
block_buf: <[u8]>::new_box_zeroed_with_elems(block_size as usize).unwrap(),
block_idx: u32::MAX,
sector_buf: <[u8; SECTOR_SIZE]>::new_box_zeroed(),
sector_buf: <[u8; SECTOR_SIZE]>::new_box_zeroed().unwrap(),
sector: u32::MAX,
pos: 0,
disc_header,
@ -151,7 +151,8 @@ pub(crate) fn read_part_meta(
) -> Result<Box<PartitionMeta>> {
// boot.bin
let raw_boot: Box<[u8; BOOT_SIZE]> = read_box(reader).context("Reading boot.bin")?;
let partition_header = PartitionHeader::ref_from(&raw_boot[size_of::<DiscHeader>()..]).unwrap();
let partition_header =
PartitionHeader::ref_from_bytes(&raw_boot[size_of::<DiscHeader>()..]).unwrap();
// bi2.bin
let raw_bi2: Box<[u8; BI2_SIZE]> = read_box(reader).context("Reading bi2.bin")?;
@ -159,7 +160,7 @@ pub(crate) fn read_part_meta(
// apploader.bin
let mut raw_apploader: Vec<u8> =
read_vec(reader, size_of::<ApploaderHeader>()).context("Reading apploader header")?;
let apploader_header = ApploaderHeader::ref_from(raw_apploader.as_slice()).unwrap();
let apploader_header = ApploaderHeader::ref_from_bytes(raw_apploader.as_slice()).unwrap();
raw_apploader.resize(
size_of::<ApploaderHeader>()
+ apploader_header.size.get() as usize
@ -189,7 +190,7 @@ pub(crate) fn read_part_meta(
.context("Seeking to DOL offset")?;
let mut raw_dol: Vec<u8> =
read_vec(reader, size_of::<DolHeader>()).context("Reading DOL header")?;
let dol_header = DolHeader::ref_from(raw_dol.as_slice()).unwrap();
let dol_header = DolHeader::ref_from_bytes(raw_dol.as_slice()).unwrap();
let dol_size = dol_header
.text_offs
.iter()

View File

@ -6,7 +6,7 @@ use std::{
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use sha1::{Digest, Sha1};
use zerocopy::FromZeroes;
use zerocopy::FromZeros;
use crate::{
array_ref, array_ref_mut,
@ -39,7 +39,7 @@ pub struct HashTable {
pub h3_hashes: Box<[HashBytes]>,
}
#[derive(Clone, FromZeroes)]
#[derive(Clone, FromZeros)]
struct HashResult {
h0_hashes: [HashBytes; 1984],
h1_hashes: [HashBytes; 64],
@ -54,10 +54,10 @@ impl HashTable {
let num_subgroups = num_sectors / 8;
let num_groups = num_subgroups / 8;
Self {
h0_hashes: HashBytes::new_box_slice_zeroed(num_data_hashes),
h1_hashes: HashBytes::new_box_slice_zeroed(num_sectors),
h2_hashes: HashBytes::new_box_slice_zeroed(num_subgroups),
h3_hashes: HashBytes::new_box_slice_zeroed(num_groups),
h0_hashes: <[HashBytes]>::new_box_zeroed_with_elems(num_data_hashes).unwrap(),
h1_hashes: <[HashBytes]>::new_box_zeroed_with_elems(num_sectors).unwrap(),
h2_hashes: <[HashBytes]>::new_box_zeroed_with_elems(num_subgroups).unwrap(),
h3_hashes: <[HashBytes]>::new_box_zeroed_with_elems(num_groups).unwrap(),
}
}
@ -100,8 +100,8 @@ pub fn rebuild_hashes(reader: &mut DiscReader) -> Result<()> {
(0..group_count).into_par_iter().try_for_each_with(
(reader.open_partition(part.index, &OpenOptions::default())?, mutex.clone()),
|(stream, mutex), h3_index| -> Result<()> {
let mut result = HashResult::new_box_zeroed();
let mut data_buf = <u8>::new_box_slice_zeroed(SECTOR_DATA_SIZE);
let mut result = HashResult::new_box_zeroed()?;
let mut data_buf = <[u8]>::new_box_zeroed_with_elems(SECTOR_DATA_SIZE)?;
let mut h3_hasher = Sha1::new();
for h2_index in 0..8 {
let mut h2_hasher = Sha1::new();

View File

@ -11,7 +11,7 @@ use std::{
};
use dyn_clone::DynClone;
use zerocopy::{big_endian::*, AsBytes, FromBytes, FromZeroes};
use zerocopy::{big_endian::*, FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{io::MagicBytes, static_assert, Result};
@ -38,7 +38,7 @@ pub const GCN_MAGIC: MagicBytes = [0xC2, 0x33, 0x9F, 0x3D];
/// Shared GameCube & Wii disc header.
///
/// This header is always at the start of the disc image and within each Wii partition.
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct DiscHeader {
/// Game ID (e.g. GM8E01 for Metroid Prime)
@ -97,7 +97,7 @@ impl DiscHeader {
/// **GameCube**: Always follows the disc header.
///
/// **Wii**: Follows the disc header within each partition.
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct PartitionHeader {
/// Debug monitor offset
@ -169,7 +169,7 @@ impl PartitionHeader {
}
/// Apploader header.
#[derive(Debug, PartialEq, Clone, FromBytes, FromZeroes, AsBytes)]
#[derive(Debug, PartialEq, Clone, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct ApploaderHeader {
/// Apploader build date
@ -198,7 +198,7 @@ pub const DOL_MAX_TEXT_SECTIONS: usize = 7;
pub const DOL_MAX_DATA_SECTIONS: usize = 11;
/// Dolphin executable (DOL) header.
#[derive(Debug, Clone, FromBytes, FromZeroes)]
#[derive(Debug, Clone, FromBytes, Immutable, KnownLayout)]
pub struct DolHeader {
/// Text section offsets
pub text_offs: [U32; DOL_MAX_TEXT_SECTIONS],
@ -379,19 +379,19 @@ impl PartitionMeta {
/// A view into the disc header.
#[inline]
pub fn header(&self) -> &DiscHeader {
DiscHeader::ref_from(&self.raw_boot[..size_of::<DiscHeader>()]).unwrap()
DiscHeader::ref_from_bytes(&self.raw_boot[..size_of::<DiscHeader>()]).unwrap()
}
/// A view into the partition header.
#[inline]
pub fn partition_header(&self) -> &PartitionHeader {
PartitionHeader::ref_from(&self.raw_boot[size_of::<DiscHeader>()..]).unwrap()
PartitionHeader::ref_from_bytes(&self.raw_boot[size_of::<DiscHeader>()..]).unwrap()
}
/// A view into the apploader header.
#[inline]
pub fn apploader_header(&self) -> &ApploaderHeader {
ApploaderHeader::ref_from_prefix(&self.raw_apploader).unwrap()
ApploaderHeader::ref_from_prefix(&self.raw_apploader).unwrap().0
}
/// A view into the file system table (FST).
@ -400,18 +400,18 @@ impl PartitionMeta {
/// A view into the DOL header.
#[inline]
pub fn dol_header(&self) -> &DolHeader { DolHeader::ref_from_prefix(&self.raw_dol).unwrap() }
pub fn dol_header(&self) -> &DolHeader { DolHeader::ref_from_prefix(&self.raw_dol).unwrap().0 }
/// A view into the ticket. (Wii only)
#[inline]
pub fn ticket(&self) -> Option<&Ticket> {
self.raw_ticket.as_ref().and_then(|v| Ticket::ref_from(v))
self.raw_ticket.as_ref().and_then(|v| Ticket::ref_from_bytes(v).ok())
}
/// A view into the TMD. (Wii only)
#[inline]
pub fn tmd_header(&self) -> Option<&TmdHeader> {
self.raw_tmd.as_ref().and_then(|v| TmdHeader::ref_from_prefix(v))
self.raw_tmd.as_ref().and_then(|v| TmdHeader::ref_from_prefix(v).ok().map(|(v, _)| v))
}
}

View File

@ -3,7 +3,7 @@ use std::{
io::{BufRead, Read, Seek, SeekFrom},
};
use zerocopy::FromZeroes;
use zerocopy::FromZeros;
use super::{
gcn::PartitionGC,
@ -43,9 +43,9 @@ impl Clone for DiscReader {
Self {
io: self.io.clone(),
block: Block::default(),
block_buf: <u8>::new_box_slice_zeroed(self.block_buf.len()),
block_buf: <[u8]>::new_box_zeroed_with_elems(self.block_buf.len()).unwrap(),
block_idx: u32::MAX,
sector_buf: <[u8; SECTOR_SIZE]>::new_box_zeroed(),
sector_buf: <[u8; SECTOR_SIZE]>::new_box_zeroed().unwrap(),
sector_idx: u32::MAX,
pos: 0,
mode: self.mode,
@ -63,9 +63,9 @@ impl DiscReader {
let mut reader = Self {
io: inner,
block: Block::default(),
block_buf: <u8>::new_box_slice_zeroed(block_size as usize),
block_buf: <[u8]>::new_box_zeroed_with_elems(block_size as usize)?,
block_idx: u32::MAX,
sector_buf: <[u8; SECTOR_SIZE]>::new_box_zeroed(),
sector_buf: <[u8; SECTOR_SIZE]>::new_box_zeroed()?,
sector_idx: u32::MAX,
pos: 0,
mode: if options.rebuild_encryption {
@ -73,7 +73,7 @@ impl DiscReader {
} else {
EncryptionMode::Decrypted
},
disc_header: DiscHeader::new_box_zeroed(),
disc_header: DiscHeader::new_box_zeroed()?,
partitions: vec![],
hash_tables: vec![],
};
@ -278,8 +278,8 @@ fn read_partition_info(reader: &mut DiscReader) -> Result<Vec<PartitionInfo>> {
data_end_sector: (data_end_offset / SECTOR_SIZE as u64) as u32,
key,
header,
disc_header: DiscHeader::new_box_zeroed(),
partition_header: PartitionHeader::new_box_zeroed(),
disc_header: DiscHeader::new_box_zeroed()?,
partition_header: PartitionHeader::new_box_zeroed()?,
hash_table: None,
};

View File

@ -6,7 +6,7 @@ use std::{
};
use sha1::{Digest, Sha1};
use zerocopy::{big_endian::*, AsBytes, FromBytes, FromZeroes};
use zerocopy::{big_endian::*, FromBytes, FromZeros, Immutable, IntoBytes, KnownLayout};
use super::{
gcn::{read_part_meta, PartitionGC},
@ -55,7 +55,7 @@ const DEBUG_COMMON_KEYS: [KeyBytes; 3] = [
[0x2f, 0x5c, 0x1b, 0x29, 0x44, 0xe7, 0xfd, 0x6f, 0xc3, 0x97, 0x96, 0x4b, 0x05, 0x76, 0x91, 0xfa],
];
#[derive(Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub(crate) struct WiiPartEntry {
pub(crate) offset: U32,
@ -70,7 +70,7 @@ impl WiiPartEntry {
pub(crate) const WII_PART_GROUP_OFF: u64 = 0x40000;
#[derive(Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub(crate) struct WiiPartGroup {
pub(crate) part_count: U32,
@ -84,7 +84,7 @@ impl WiiPartGroup {
}
/// Signed blob header
#[derive(Debug, Clone, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Debug, Clone, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct SignedHeader {
/// Signature type, always 0x00010001 (RSA-2048)
@ -97,7 +97,7 @@ pub struct SignedHeader {
static_assert!(size_of::<SignedHeader>() == 0x140);
/// Ticket limit
#[derive(Debug, Clone, PartialEq, Default, FromBytes, FromZeroes, AsBytes)]
#[derive(Debug, Clone, PartialEq, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct TicketLimit {
/// Limit type
@ -109,7 +109,7 @@ pub struct TicketLimit {
static_assert!(size_of::<TicketLimit>() == 8);
/// Wii ticket
#[derive(Debug, Clone, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Debug, Clone, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct Ticket {
/// Signed blob header
@ -179,7 +179,7 @@ impl Ticket {
}
/// Title metadata header
#[derive(Debug, Clone, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Debug, Clone, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct TmdHeader {
/// Signed blob header
@ -227,7 +227,7 @@ static_assert!(size_of::<TmdHeader>() == 0x1E4);
pub const H3_TABLE_SIZE: usize = 0x18000;
#[derive(Debug, Clone, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Debug, Clone, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct WiiPartitionHeader {
pub ticket: Ticket,
@ -281,9 +281,9 @@ impl Clone for PartitionWii {
io: self.io.clone(),
partition: self.partition.clone(),
block: Block::default(),
block_buf: <u8>::new_box_slice_zeroed(self.block_buf.len()),
block_buf: <[u8]>::new_box_zeroed_with_elems(self.block_buf.len()).unwrap(),
block_idx: u32::MAX,
sector_buf: <[u8; SECTOR_SIZE]>::new_box_zeroed(),
sector_buf: <[u8; SECTOR_SIZE]>::new_box_zeroed().unwrap(),
sector: u32::MAX,
pos: 0,
verify: self.verify,
@ -327,9 +327,9 @@ impl PartitionWii {
io: reader.into_inner(),
partition: partition.clone(),
block: Block::default(),
block_buf: <u8>::new_box_slice_zeroed(block_size as usize),
block_buf: <[u8]>::new_box_zeroed_with_elems(block_size as usize)?,
block_idx: u32::MAX,
sector_buf: <[u8; SECTOR_SIZE]>::new_box_zeroed(),
sector_buf: <[u8; SECTOR_SIZE]>::new_box_zeroed()?,
sector: u32::MAX,
pos: 0,
verify: options.validate_hashes,

View File

@ -4,7 +4,7 @@ use std::{
mem::size_of,
};
use zerocopy::{little_endian::*, AsBytes, FromBytes, FromZeroes};
use zerocopy::{little_endian::*, FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{
disc::SECTOR_SIZE,
@ -21,7 +21,7 @@ use crate::{
pub const CISO_MAP_SIZE: usize = SECTOR_SIZE - 8;
/// CISO header (little endian)
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
struct CISOHeader {
magic: MagicBytes,

View File

@ -6,7 +6,7 @@ use std::{
use adler::adler32_slice;
use miniz_oxide::{inflate, inflate::core::inflate_flags};
use zerocopy::{little_endian::*, AsBytes, FromBytes, FromZeroes};
use zerocopy::{little_endian::*, FromBytes, FromZeros, Immutable, IntoBytes, KnownLayout};
use zstd::zstd_safe::WriteBuf;
use crate::{
@ -20,7 +20,7 @@ use crate::{
};
/// GCZ header (little endian)
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
struct GCZHeader {
magic: MagicBytes,
@ -49,7 +49,7 @@ impl Clone for DiscIOGCZ {
header: self.header.clone(),
block_map: self.block_map.clone(),
block_hashes: self.block_hashes.clone(),
block_buf: <u8>::new_box_slice_zeroed(self.block_buf.len()),
block_buf: <[u8]>::new_box_zeroed_with_elems(self.block_buf.len()).unwrap(),
data_offset: self.data_offset,
}
}
@ -73,7 +73,7 @@ impl DiscIOGCZ {
// header + block_count * (u64 + u32)
let data_offset = size_of::<GCZHeader>() as u64 + block_count as u64 * 12;
let block_buf = <u8>::new_box_slice_zeroed(header.block_size.get() as usize);
let block_buf = <[u8]>::new_box_zeroed_with_elems(header.block_size.get() as usize)?;
Ok(Box::new(Self { inner, header, block_map, block_hashes, block_buf, data_offset }))
}
}

View File

@ -6,7 +6,7 @@ use std::{
path::{Component, Path, PathBuf},
};
use zerocopy::{big_endian::U32, AsBytes, FromBytes, FromZeroes};
use zerocopy::{big_endian::U32, FromBytes, FromZeros, Immutable, IntoBytes, KnownLayout};
use crate::{
disc::SECTOR_SIZE,
@ -23,14 +23,14 @@ use crate::{
pub const NFS_END_MAGIC: MagicBytes = *b"SGGE";
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
struct LBARange {
start_sector: U32,
num_sectors: U32,
}
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
struct NFSHeader {
magic: MagicBytes,

View File

@ -4,7 +4,7 @@ use std::{
mem::size_of,
};
use zerocopy::{big_endian::U32, AsBytes, FromBytes, FromZeroes};
use zerocopy::{big_endian::U32, FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{
disc::SECTOR_SIZE,
@ -17,7 +17,7 @@ use crate::{
};
/// TGC header (big endian)
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
struct TGCHeader {
/// Magic bytes
@ -75,11 +75,11 @@ impl DiscIOTGC {
.context("Seeking to TGC FST")?;
let mut fst = read_box_slice(inner.as_mut(), header.fst_size.get() as usize)
.context("Reading TGC FST")?;
let root_node = Node::ref_from_prefix(&fst)
.ok_or_else(|| Error::DiscFormat("Invalid TGC FST".to_string()))?;
let (root_node, _) = Node::ref_from_prefix(&fst)
.map_err(|_| Error::DiscFormat("Invalid TGC FST".to_string()))?;
let node_count = root_node.length() as usize;
let (nodes, _) = Node::mut_slice_from_prefix(&mut fst, node_count)
.ok_or_else(|| Error::DiscFormat("Invalid TGC FST".to_string()))?;
let (nodes, _) = <[Node]>::mut_from_prefix_with_elems(&mut fst, node_count)
.map_err(|_| Error::DiscFormat("Invalid TGC FST".to_string()))?;
for node in nodes {
if node.is_file() {
node.offset = node.offset - header.gcm_user_offset
@ -116,7 +116,7 @@ impl BlockIO for DiscIOTGC {
// Adjust internal GCM header
if block == 0 {
let partition_header = PartitionHeader::mut_from(
let partition_header = PartitionHeader::mut_from_bytes(
&mut out[size_of::<DiscHeader>()
..size_of::<DiscHeader>() + size_of::<PartitionHeader>()],
)

View File

@ -4,7 +4,7 @@ use std::{
mem::size_of,
};
use zerocopy::{big_endian::*, AsBytes, FromBytes, FromZeroes};
use zerocopy::{big_endian::*, FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{
io::{
@ -16,7 +16,7 @@ use crate::{
Error, Result, ResultContext,
};
#[derive(Debug, Clone, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Debug, Clone, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
struct WBFSHeader {
magic: MagicBytes,

View File

@ -4,7 +4,7 @@ use std::{
mem::size_of,
};
use zerocopy::{big_endian::*, AsBytes, FromBytes, FromZeroes};
use zerocopy::{big_endian::*, FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{
disc::{
@ -28,7 +28,7 @@ use crate::{
/// This struct is stored at offset 0x0 and is 0x48 bytes long. The wit source code says its format
/// will never be changed.
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct WIAFileHeader {
pub magic: MagicBytes,
@ -142,7 +142,7 @@ impl TryFrom<u32> for WIACompression {
const DISC_HEAD_SIZE: usize = 0x80;
/// This struct is stored at offset 0x48, immediately after [WIAFileHeader].
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct WIADisc {
/// The disc type. (1 = GameCube, 2 = Wii)
@ -236,7 +236,7 @@ impl WIADisc {
}
}
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct WIAPartitionData {
/// The sector on the disc at which this data starts.
@ -271,7 +271,7 @@ impl WIAPartitionData {
/// the reading program must first recalculate the hashes as done when creating a Wii disc image
/// from scratch (see <https://wiibrew.org/wiki/Wii_Disc>), and must then apply the hash exceptions
/// which are stored along with the data (see the [WIAExceptionList] section).
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct WIAPartition {
/// The title key for this partition (128-bit AES), which can be used for re-encrypting the
@ -298,7 +298,7 @@ static_assert!(size_of::<WIAPartition>() == 0x30);
/// should be read from [WIADisc] instead.) This should be handled by rounding the offset down to
/// the previous multiple of 0x8000 (and adding the equivalent amount to the size so that the end
/// offset stays the same), not by special casing the first [WIARawData].
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct WIARawData {
/// The offset on the disc at which this data starts.
@ -336,7 +336,7 @@ impl WIARawData {
/// counting any [WIAExceptionList] structs. However, the last [WIAGroup] of a [WIAPartitionData]
/// or [WIARawData] contains less data than that if `num_sectors * 0x8000` (for [WIAPartitionData])
/// or `raw_data_size` (for [WIARawData]) is not evenly divisible by `chunk_size`.
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct WIAGroup {
/// The offset in the file where the compressed data is stored.
@ -351,7 +351,7 @@ pub struct WIAGroup {
/// Compared to [WIAGroup], [RVZGroup] changes the meaning of the most significant bit of
/// [data_size](Self::data_size) and adds one additional attribute.
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
pub struct RVZGroup {
/// The offset in the file where the compressed data is stored, divided by 4.
@ -398,7 +398,7 @@ impl From<&WIAGroup> for RVZGroup {
/// write [WIAException] structs for a padding area which is 32 bytes long, it writes one which
/// covers the first 20 bytes of the padding area and one which covers the last 20 bytes of the
/// padding area, generating 12 bytes of overlap between the [WIAException] structs.
#[derive(Clone, Debug, PartialEq, FromBytes, FromZeroes, AsBytes)]
#[derive(Clone, Debug, PartialEq, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(2))]
pub struct WIAException {
/// The offset among the hashes. The offsets 0x0000-0x0400 here map to the offsets 0x0000-0x0400
@ -559,7 +559,7 @@ impl DiscIOWIA {
.context("Reading WIA/RVZ disc header")?;
verify_hash(&disc_buf, &header.disc_hash)?;
disc_buf.resize(size_of::<WIADisc>(), 0);
let disc = WIADisc::read_from(disc_buf.as_slice()).unwrap();
let disc = WIADisc::read_from_bytes(disc_buf.as_slice()).unwrap();
disc.validate()?;
// if !options.rebuild_hashes {
// // If we're not rebuilding hashes, disable partition hashes in disc header

View File

@ -89,6 +89,9 @@ pub enum Error {
/// An unknown error.
#[error("error: {0}")]
Other(String),
/// An error occurred while allocating memory.
#[error("allocation failed")]
Alloc(zerocopy::AllocError),
}
impl From<&str> for Error {
@ -101,6 +104,11 @@ impl From<String> for Error {
fn from(s: String) -> Error { Error::Other(s) }
}
impl From<zerocopy::AllocError> for Error {
#[inline]
fn from(e: zerocopy::AllocError) -> Error { Error::Alloc(e) }
}
/// Helper result type for [`Error`].
pub type Result<T, E = Error> = core::result::Result<T, E>;

View File

@ -1,6 +1,6 @@
use std::{cmp::min, io, io::Read};
use zerocopy::{transmute_ref, AsBytes};
use zerocopy::{transmute_ref, IntoBytes};
use crate::disc::SECTOR_SIZE;
@ -64,7 +64,7 @@ impl LaggedFibonacci {
pub fn init_with_reader<R>(&mut self, reader: &mut R) -> io::Result<()>
where R: Read + ?Sized {
reader.read_exact(self.buffer[..SEED_SIZE].as_bytes_mut())?;
reader.read_exact(self.buffer[..SEED_SIZE].as_mut_bytes())?;
for x in self.buffer[..SEED_SIZE].iter_mut() {
*x = u32::from_be(*x);
}

View File

@ -1,48 +1,50 @@
use std::{io, io::Read};
use zerocopy::{AsBytes, FromBytes, FromZeroes};
use zerocopy::{FromBytes, FromZeros, IntoBytes};
#[inline(always)]
pub fn read_from<T, R>(reader: &mut R) -> io::Result<T>
where
T: FromBytes + FromZeroes + AsBytes,
T: FromBytes + IntoBytes,
R: Read + ?Sized,
{
let mut ret = <T>::new_zeroed();
reader.read_exact(ret.as_bytes_mut())?;
reader.read_exact(ret.as_mut_bytes())?;
Ok(ret)
}
#[inline(always)]
pub fn read_vec<T, R>(reader: &mut R, count: usize) -> io::Result<Vec<T>>
where
T: FromBytes + FromZeroes + AsBytes,
T: FromBytes + IntoBytes,
R: Read + ?Sized,
{
let mut ret = <T>::new_vec_zeroed(count);
reader.read_exact(ret.as_mut_slice().as_bytes_mut())?;
let mut ret =
<T>::new_vec_zeroed(count).map_err(|_| io::Error::from(io::ErrorKind::OutOfMemory))?;
reader.read_exact(ret.as_mut_slice().as_mut_bytes())?;
Ok(ret)
}
#[inline(always)]
pub fn read_box<T, R>(reader: &mut R) -> io::Result<Box<T>>
where
T: FromBytes + FromZeroes + AsBytes,
T: FromBytes + IntoBytes,
R: Read + ?Sized,
{
let mut ret = <T>::new_box_zeroed();
reader.read_exact(ret.as_mut().as_bytes_mut())?;
let mut ret = <T>::new_box_zeroed().map_err(|_| io::Error::from(io::ErrorKind::OutOfMemory))?;
reader.read_exact(ret.as_mut().as_mut_bytes())?;
Ok(ret)
}
#[inline(always)]
pub fn read_box_slice<T, R>(reader: &mut R, count: usize) -> io::Result<Box<[T]>>
where
T: FromBytes + FromZeroes + AsBytes,
T: FromBytes + IntoBytes,
R: Read + ?Sized,
{
let mut ret = <T>::new_box_slice_zeroed(count);
reader.read_exact(ret.as_mut().as_bytes_mut())?;
let mut ret = <[T]>::new_box_zeroed_with_elems(count)
.map_err(|_| io::Error::from(io::ErrorKind::OutOfMemory))?;
reader.read_exact(ret.as_mut().as_mut_bytes())?;
Ok(ret)
}

View File

@ -40,7 +40,7 @@ tracing = "0.1"
tracing-attributes = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
xxhash-rust = { version = "0.8", features = ["xxh64"] }
zerocopy = { version = "0.7", features = ["alloc", "derive"] }
zerocopy = { version = "0.8", features = ["alloc", "derive"] }
zstd = "0.13"
[target.'cfg(target_env = "musl")'.dependencies]
@ -50,5 +50,5 @@ mimalloc = "0.1"
hex = { version = "0.4", features = ["serde"] }
quick-xml = { version = "0.36", features = ["serialize"] }
serde = { version = "1.0", features = ["derive"] }
zerocopy = { version = "0.7", features = ["alloc", "derive"] }
zerocopy = { version = "0.8", features = ["alloc", "derive"] }
zstd = "0.13"

View File

@ -8,10 +8,10 @@ use std::{
use hex::deserialize as deserialize_hex;
use serde::Deserialize;
use zerocopy::AsBytes;
use zerocopy::{Immutable, IntoBytes, KnownLayout};
// Keep in sync with build.rs
#[derive(Clone, Debug, AsBytes)]
#[derive(Clone, Debug, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
struct Header {
entry_count: u32,
@ -19,7 +19,7 @@ struct Header {
}
// Keep in sync with redump.rs
#[derive(Clone, Debug, AsBytes)]
#[derive(Clone, Debug, IntoBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
struct GameEntry {
crc32: u32,

View File

@ -11,7 +11,7 @@ use std::{
use argp::FromArgs;
use indicatif::{ProgressBar, ProgressState, ProgressStyle};
use nod::{Disc, OpenOptions, Result, ResultContext};
use zerocopy::FromZeroes;
use zerocopy::FromZeros;
use crate::util::{
digest::{digest_thread, DigestResult},
@ -199,7 +199,7 @@ fn load_disc(path: &Path, name: &str, full_verify: bool) -> Result<DiscHashes> {
});
let mut total_read = 0u64;
let mut buf = <u8>::new_box_slice_zeroed(BUFFER_SIZE);
let mut buf = <[u8]>::new_box_zeroed_with_elems(BUFFER_SIZE)?;
while total_read < disc_size {
let read = min(BUFFER_SIZE as u64, disc_size - total_read) as usize;
disc.read_exact(&mut buf[..read]).with_context(|| {

View File

@ -13,7 +13,7 @@ use nod::{
ResultContext,
};
use size::{Base, Size};
use zerocopy::AsBytes;
use zerocopy::IntoBytes;
use crate::util::{display, has_extension};

View File

@ -10,7 +10,7 @@ use std::{
use hex::deserialize as deserialize_hex;
use nod::{array_ref, Result};
use serde::Deserialize;
use zerocopy::{AsBytes, FromBytes, FromZeroes};
use zerocopy::{FromBytes, FromZeros, Immutable, IntoBytes, KnownLayout};
#[derive(Clone, Debug)]
pub struct GameResult<'a> {
@ -33,18 +33,15 @@ impl<'a> Iterator for EntryIter<'a> {
type Item = GameResult<'a>;
fn next(&mut self) -> Option<Self::Item> {
let header: &Header = Header::ref_from_prefix(self.data).unwrap();
let (header, remaining) = Header::ref_from_prefix(self.data).ok()?;
assert_eq!(header.entry_size as usize, size_of::<GameEntry>());
if self.index >= header.entry_count as usize {
return None;
}
let entries_size = header.entry_count as usize * size_of::<GameEntry>();
let entries: &[GameEntry] = GameEntry::slice_from(
&self.data[size_of::<Header>()..size_of::<Header>() + entries_size],
)
.unwrap();
let string_table: &[u8] = &self.data[size_of::<Header>() + entries_size..];
let entries = <[GameEntry]>::ref_from_bytes(&remaining[..entries_size]).ok()?;
let string_table = &self.data[size_of::<Header>() + entries_size..];
let entry = &entries[self.index];
let offset = entry.string_table_offset as usize;
@ -57,14 +54,12 @@ impl<'a> Iterator for EntryIter<'a> {
pub fn find_by_crc32(crc32: u32) -> Option<GameResult<'static>> {
let data = loaded_data();
let header: &Header = Header::ref_from_prefix(data).unwrap();
let (header, remaining) = Header::ref_from_prefix(data).ok()?;
assert_eq!(header.entry_size as usize, size_of::<GameEntry>());
let entries_size = header.entry_count as usize * size_of::<GameEntry>();
let entries: &[GameEntry] =
GameEntry::slice_from(&data[size_of::<Header>()..size_of::<Header>() + entries_size])
.unwrap();
let string_table: &[u8] = &data[size_of::<Header>() + entries_size..];
let (entries_buf, string_table) = remaining.split_at(entries_size);
let entries = <[GameEntry]>::ref_from_bytes(entries_buf).ok()?;
// Binary search by CRC32
let index = entries.binary_search_by_key(&crc32, |entry| entry.crc32).ok()?;
@ -84,7 +79,7 @@ fn loaded_data() -> &'static [u8] {
LOADED
.get_or_init(|| {
let size = zstd::zstd_safe::get_frame_content_size(BUILTIN).unwrap().unwrap() as usize;
let mut out = <u8>::new_box_slice_zeroed(size);
let mut out = <[u8]>::new_box_zeroed_with_elems(size).unwrap();
let out_size = zstd::bulk::Decompressor::new()
.unwrap()
.decompress_to_buffer(BUILTIN, out.as_mut())
@ -126,7 +121,7 @@ pub fn load_dats<'a>(paths: impl Iterator<Item = &'a Path>) -> Result<()> {
let entries_size = entries.len() * size_of::<GameEntry>();
let string_table_size = entries.iter().map(|(_, name)| name.len() + 4).sum::<usize>();
let total_size = size_of::<Header>() + entries_size + string_table_size;
let mut result = <u8>::new_box_slice_zeroed(total_size);
let mut result = <[u8]>::new_box_zeroed_with_elems(total_size)?;
let mut out = Cursor::new(result.as_mut());
// Write game entries
@ -152,7 +147,7 @@ pub fn load_dats<'a>(paths: impl Iterator<Item = &'a Path>) -> Result<()> {
}
// Keep in sync with build.rs
#[derive(Clone, Debug, AsBytes, FromBytes, FromZeroes)]
#[derive(Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
struct Header {
entry_count: u32,
@ -160,7 +155,7 @@ struct Header {
}
// Keep in sync with build.rs
#[derive(Clone, Debug, AsBytes, FromBytes, FromZeroes)]
#[derive(Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
#[repr(C, align(4))]
struct GameEntry {
crc32: u32,

View File

@ -11,7 +11,7 @@ use std::{
use indicatif::{ProgressBar, ProgressState, ProgressStyle};
use nod::{Compression, Disc, DiscHeader, DiscMeta, OpenOptions, Result, ResultContext};
use size::Size;
use zerocopy::FromZeroes;
use zerocopy::FromZeros;
use crate::util::{
digest::{digest_thread, DigestResult},
@ -117,7 +117,7 @@ pub fn convert_and_verify(in_file: &Path, out_file: Option<&Path>, md5: bool) ->
});
let mut total_read = 0u64;
let mut buf = <u8>::new_box_slice_zeroed(BUFFER_SIZE);
let mut buf = <[u8]>::new_box_zeroed_with_elems(BUFFER_SIZE)?;
while total_read < disc_size {
let read = min(BUFFER_SIZE as u64, disc_size - total_read) as usize;
disc.read_exact(&mut buf[..read]).with_context(|| {