tweaks to assertions, do them as soon as relevant fields are available
This commit is contained in:
parent
19e7dfa238
commit
7310755a79
|
@ -30,10 +30,10 @@ const SIZE_OF_ENTRY: u32 = (6 * size_of::<u32>() + SIZE_OF_FILENAME) as u32;
|
|||
|
||||
// not using binread's built-in [br(magic=...)] because it doesn't let me reference self::MAGIC
|
||||
#[derive(BinRead, BinWrite)]
|
||||
#[br(little, assert(magic == self::MAGIC))]
|
||||
#[br(little)]
|
||||
#[binwrite(little)]
|
||||
pub struct JodOne {
|
||||
#[br(pad_size_to = self::SIZE_OF_MAGIC, map = string_binread_helper)]
|
||||
#[br(pad_size_to = self::SIZE_OF_MAGIC, map = string_binread_helper, assert(magic == self::MAGIC))]
|
||||
#[binwrite(preprocessor(string_binwrite_helper(self::SIZE_OF_MAGIC)))]
|
||||
pub magic: String,
|
||||
/// usually 0xCC... archive creator version?
|
||||
|
|
|
@ -14,21 +14,27 @@ const TYPICAL_STRING_TABLE_COUNT: usize = 0x100;
|
|||
|
||||
#[derive(BinRead, BinWrite)]
|
||||
#[br(little, assert(
|
||||
id_archive == 0 && id_string_table == 1 && version == version_again &&
|
||||
entries.iter().enumerate().all(|(i, ent)| ent.id as usize == i + 2)
|
||||
entries.iter().enumerate().all(|(i, ent)| ent.id as usize == i + 2 && ent.version == version) &&
|
||||
archive_size_minus_12 == (
|
||||
entries.iter().map(|e| self::SIZE_OF_ENTRY + e.size_cmp).sum::<u32>() +
|
||||
SIZE_OF_ENTRY + (string_table.len() * SIZE_OF_FILENAME) as u32
|
||||
)
|
||||
))]
|
||||
#[binwrite(little)]
|
||||
pub struct HerOne {
|
||||
/// 0. conceptually the ID of the "entry" containing the entire archive
|
||||
#[br(assert(id_archive == 0))]
|
||||
id_archive: u32,
|
||||
/// the size of the archive, not counting the "pre-header" of these first three u32's
|
||||
/// the size of the archive, not counting the "first entry" of these first three u32's
|
||||
archive_size_minus_12: u32,
|
||||
/// presumably the archiver version. known values: 0x1400ffff from GCN version
|
||||
version: u32,
|
||||
#[br(assert(id_string_table == 1))]
|
||||
/// 1. conceptually the ID of the (uncompressed) array of filenames, indexed by ID.
|
||||
id_string_table: u32,
|
||||
/// usually 0x4000. size of string table in bytes.
|
||||
string_table_size: u32,
|
||||
#[br(assert(version == version_again))]
|
||||
version_again: u32,
|
||||
#[br(count = string_table_size as usize / self::SIZE_OF_FILENAME)]
|
||||
pub string_table: Vec<HerOneFilename>,
|
||||
|
@ -46,8 +52,6 @@ pub struct HerOneFilename {
|
|||
pub inner: String,
|
||||
}
|
||||
|
||||
// there is one file for which the assertion can't be (size_dec == 0) == (is_compressed == 0).
|
||||
// event/event8006_sceneE.one: EVENT8006.CEN, whose size_dec is 0x20, its in-archive size.
|
||||
#[derive(BinRead, BinWrite)]
|
||||
#[br(
|
||||
little,
|
||||
|
|
|
@ -91,11 +91,6 @@ pub fn read_one_archive(mut reader: impl Read + Seek) -> Result<DynOneArchive, B
|
|||
Err(e) => info!("Not a NiGHTS Journey of Dreams archive: {}", e),
|
||||
}
|
||||
reader.seek(SeekFrom::Start(rewind))?;
|
||||
match reader.read_be::<rings::SsrOne>() {
|
||||
Ok(one) => return Ok(DynOneArchive::SsrOne(one)),
|
||||
Err(e) => info!("Not a Sonic and the Secret Rings archive: {}", e),
|
||||
}
|
||||
reader.seek(SeekFrom::Start(rewind))?;
|
||||
match reader.read_le::<shadow::ShadOne>() {
|
||||
Ok(one) => return Ok(DynOneArchive::ShadOne(one)),
|
||||
Err(e) => info!("Not a Shadow the Hedgehog archive: {}", e),
|
||||
|
@ -105,5 +100,11 @@ pub fn read_one_archive(mut reader: impl Read + Seek) -> Result<DynOneArchive, B
|
|||
Ok(one) => return Ok(DynOneArchive::HerOne(one)),
|
||||
Err(e) => info!("Not a Sonic Heroes archive: {}", e),
|
||||
}
|
||||
// last 'cause it's the least-specific in terms of assertions
|
||||
reader.seek(SeekFrom::Start(rewind))?;
|
||||
match reader.read_be::<rings::SsrOne>() {
|
||||
Ok(one) => return Ok(DynOneArchive::SsrOne(one)),
|
||||
Err(e) => info!("Not a Sonic and the Secret Rings archive: {}", e),
|
||||
}
|
||||
Err("No valid .one archive found".into())
|
||||
}
|
||||
|
|
|
@ -24,22 +24,21 @@ const SIZE_OF_ENTRY: u32 = (4 * size_of::<u32>() + SIZE_OF_FILENAME) as u32;
|
|||
// 5105 SsrOneEntry{size_cmp: 1+, size_dec: 1+, ..}
|
||||
|
||||
#[derive(BinRead, BinWrite)]
|
||||
#[br(big, assert(
|
||||
entries.ptr == self::SIZE_OF_HEADER &&
|
||||
data_offset == entries.ptr + count * self::SIZE_OF_ENTRY
|
||||
))]
|
||||
#[br(big)]
|
||||
#[binwrite(big)]
|
||||
pub struct SsrOne {
|
||||
/// number of files stored in the .one
|
||||
pub count: u32,
|
||||
/// the location of the table of contents. always 0x10, just after this header
|
||||
#[br(count = count)]
|
||||
#[br(count = count, assert(entries.ptr == self::SIZE_OF_HEADER))]
|
||||
#[binwrite(preprocessor(|x: &FilePtr<u32, _>| x.ptr))]
|
||||
pub entries: FilePtr<u32, Vec<SsrOneEntry>>,
|
||||
/// location of the end of the toc/beginning of data. TODO: assertion
|
||||
/// location of the end of the toc/beginning of data.
|
||||
#[br(assert(data_offset == entries.ptr + count * self::SIZE_OF_ENTRY))]
|
||||
pub data_offset: u32,
|
||||
/// always 0
|
||||
pub _padding: u32,
|
||||
#[br(assert(_padding == 0))]
|
||||
_padding: u32,
|
||||
}
|
||||
|
||||
#[derive(BinRead, BinWrite)]
|
||||
|
@ -53,7 +52,7 @@ pub struct SsrOneEntry {
|
|||
// note: seek_before/restore_position shenanigans because we need _size_cmp for data's count
|
||||
#[br(seek_before = SeekFrom::Current(4), restore_position)]
|
||||
#[binwrite(ignore)]
|
||||
pub _size_cmp: u32,
|
||||
_size_cmp: u32,
|
||||
#[br(count = _size_cmp)]
|
||||
#[binwrite(preprocessor(|x: &FilePtr<u32, _>| x.ptr))]
|
||||
pub data: FilePtr<u32, Vec<u8>>,
|
||||
|
|
|
@ -52,16 +52,21 @@ fn compute_size_cmp<R: Read + Seek>(
|
|||
}
|
||||
|
||||
#[derive(BinRead, BinWrite)]
|
||||
#[br(little, assert(start == 0 && matches!(magic.as_str(), self::MAGIC_60 | self::MAGIC_50)))]
|
||||
#[br(little)]
|
||||
#[binwrite(little)]
|
||||
pub struct ShadOne {
|
||||
/// 0. presumably where data starts, not counting the "pre-header" of these first three u32's
|
||||
#[br(assert(start == 0))]
|
||||
start: u32,
|
||||
/// the size of the archive, not counting the "pre-header" of these first three u32's
|
||||
archive_size_minus_12: u32,
|
||||
/// presumably the archiver version. known values: 0x1c020037 and 0x1c020020 from GCN version
|
||||
pub version: u32,
|
||||
#[br(pad_size_to = self::SIZE_OF_MAGIC, map = string_binread_helper)]
|
||||
#[br(
|
||||
pad_size_to = self::SIZE_OF_MAGIC,
|
||||
map = string_binread_helper,
|
||||
assert(matches!(magic.as_str(), self::MAGIC_60 | self::MAGIC_50))
|
||||
)]
|
||||
#[binwrite(preprocessor(string_binwrite_helper(self::SIZE_OF_MAGIC)))]
|
||||
pub magic: String,
|
||||
/// number of files stored in the .one
|
||||
|
|
Loading…
Reference in New Issue