mirror of
https://github.com/redstrate/Physis.git
synced 2025-04-21 12:17:45 +00:00
Add basic write support for Index1 file entries
This commit is contained in:
parent
fe6712b5bf
commit
0479dac52d
1 changed files with 39 additions and 7 deletions
46
src/index.rs
46
src/index.rs
|
@ -7,13 +7,16 @@
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::io::Seek;
|
use std::io::Seek;
|
||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
use crate::common::Platform;
|
use crate::common::Platform;
|
||||||
use crate::common::Region;
|
use crate::common::Region;
|
||||||
use crate::crc::Jamcrc;
|
use crate::crc::Jamcrc;
|
||||||
use binrw::BinRead;
|
use binrw::BinRead;
|
||||||
use binrw::BinResult;
|
use binrw::BinResult;
|
||||||
|
use binrw::BinWrite;
|
||||||
use binrw::Endian;
|
use binrw::Endian;
|
||||||
|
use binrw::Error;
|
||||||
use binrw::binrw;
|
use binrw::binrw;
|
||||||
|
|
||||||
/// The type of this SqPack file.
|
/// The type of this SqPack file.
|
||||||
|
@ -116,25 +119,40 @@ impl BinRead for FileEntryData {
|
||||||
|
|
||||||
fn read_options<R: Read + Seek>(
|
fn read_options<R: Read + Seek>(
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
_options: Endian,
|
endian: Endian,
|
||||||
(): Self::Args<'_>,
|
(): Self::Args<'_>,
|
||||||
) -> BinResult<Self> {
|
) -> BinResult<Self> {
|
||||||
let data = <u8>::read(reader)?;
|
let data = <u32>::read_options(reader, endian, ())?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
is_synonym: (data & 0b1) == 0b1,
|
is_synonym: (data & 0b1) == 0b1,
|
||||||
data_file_id: (data & 0b1110) >> 1 as u8,
|
data_file_id: ((data & 0b1110) >> 1) as u8,
|
||||||
offset: (data & !0xF) as u64 * 0x08,
|
offset: (data & !0xF) as u64 * 0x08,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BinWrite for FileEntryData {
|
||||||
|
type Args<'a> = ();
|
||||||
|
|
||||||
|
fn write_options<W: Write + Seek>(
|
||||||
|
&self,
|
||||||
|
writer: &mut W,
|
||||||
|
endian: Endian,
|
||||||
|
(): Self::Args<'_>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
// TODO: support synonym and data_file_id
|
||||||
|
let data: u32 = self.offset.wrapping_div(0x08) as u32;
|
||||||
|
|
||||||
|
data.write_options(writer, endian, ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[br(import(index_type: &IndexType))]
|
#[brw(import(index_type: &IndexType))]
|
||||||
pub struct FileEntry {
|
pub struct FileEntry {
|
||||||
#[br(args(index_type))]
|
#[br(args(index_type))]
|
||||||
pub hash: Hash,
|
pub hash: Hash,
|
||||||
|
|
||||||
#[bw(ignore)]
|
|
||||||
pub data: FileEntryData,
|
pub data: FileEntryData,
|
||||||
|
|
||||||
#[br(temp)]
|
#[br(temp)]
|
||||||
|
@ -176,6 +194,7 @@ pub struct IndexFile {
|
||||||
index_header: SqPackIndexHeader,
|
index_header: SqPackIndexHeader,
|
||||||
|
|
||||||
#[br(seek_before = SeekFrom::Start(index_header.file_descriptor.offset.into()), count = index_header.file_descriptor.size / 16, args { inner: (&index_header.index_type,) })]
|
#[br(seek_before = SeekFrom::Start(index_header.file_descriptor.offset.into()), count = index_header.file_descriptor.size / 16, args { inner: (&index_header.index_type,) })]
|
||||||
|
#[bw(args(&index_header.index_type,))]
|
||||||
pub entries: Vec<FileEntry>,
|
pub entries: Vec<FileEntry>,
|
||||||
|
|
||||||
#[br(seek_before = SeekFrom::Start(index_header.data_descriptor.offset.into()))]
|
#[br(seek_before = SeekFrom::Start(index_header.data_descriptor.offset.into()))]
|
||||||
|
@ -262,6 +281,8 @@ impl IndexFile {
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::{io::Cursor, path::PathBuf};
|
use std::{io::Cursor, path::PathBuf};
|
||||||
|
|
||||||
|
use binrw::BinWrite;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -275,7 +296,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn read_index1_file_entry() {
|
fn readwrite_index1_file_entry() {
|
||||||
let data = [
|
let data = [
|
||||||
0xEF, 0x02, 0x50, 0x1C, 0x68, 0xCF, 0x4E, 0x00, 0x60, 0x01, 0x6E, 0x00, 0x00, 0x00,
|
0xEF, 0x02, 0x50, 0x1C, 0x68, 0xCF, 0x4E, 0x00, 0x60, 0x01, 0x6E, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00,
|
0x00, 0x00,
|
||||||
|
@ -293,6 +314,17 @@ mod tests {
|
||||||
assert_eq!(file_entry.hash, expected_hash);
|
assert_eq!(file_entry.hash, expected_hash);
|
||||||
assert_eq!(file_entry.data.is_synonym, false);
|
assert_eq!(file_entry.data.is_synonym, false);
|
||||||
assert_eq!(file_entry.data.data_file_id, 0);
|
assert_eq!(file_entry.data.data_file_id, 0);
|
||||||
assert_eq!(file_entry.data.offset, 768);
|
assert_eq!(file_entry.data.offset, 57674496);
|
||||||
|
|
||||||
|
// Ensure if we write this it's identica'
|
||||||
|
let mut new_data = Vec::new();
|
||||||
|
{
|
||||||
|
let mut write_cursor = Cursor::new(&mut new_data);
|
||||||
|
file_entry
|
||||||
|
.write_options(&mut write_cursor, Endian::Little, (&IndexType::Index1,))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(new_data, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue