#[doc(hidden)]
pub mod wire {
pub use crate::chunk::adir::AddDirectory;
pub use crate::chunk::afsp::ApplyFreeSpace;
pub use crate::chunk::aply::{ApplyOption, ApplyOptionKind};
pub use crate::chunk::ddir::DeleteDirectory;
pub use crate::chunk::fhdr::{FileHeader, FileHeaderV2, FileHeaderV3};
pub use crate::chunk::sqpk::add_data::SqpkAddData;
pub use crate::chunk::sqpk::delete_data::SqpkDeleteData;
pub use crate::chunk::sqpk::expand_data::SqpkExpandData;
pub use crate::chunk::sqpk::file::{SqpkFile, SqpkFileOperation};
pub use crate::chunk::sqpk::header::{
SqpkHeader, SqpkHeaderTarget, TargetFileKind, TargetHeaderKind,
};
pub use crate::chunk::sqpk::index::{IndexCommand, SqpkIndex, SqpkPatchInfo};
pub use crate::chunk::sqpk::target_info::SqpkTargetInfo;
}
#[doc(hidden)]
pub use crate::index::source::MemoryPatchSource;
pub const MAGIC: [u8; 12] = [
0x91, 0x5A, 0x49, 0x50, 0x41, 0x54, 0x43, 0x48, 0x0D, 0x0A, 0x1A, 0x0A,
];
#[must_use]
pub fn make_chunk(tag: &[u8; 4], body: &[u8]) -> Vec<u8> {
let mut crc_input = Vec::with_capacity(4 + body.len());
crc_input.extend_from_slice(tag);
crc_input.extend_from_slice(body);
let crc = crc32fast::hash(&crc_input);
let mut out = Vec::with_capacity(4 + 4 + body.len() + 4);
let body_len = u32::try_from(body.len()).expect("chunk body fits in u32");
out.extend_from_slice(&body_len.to_be_bytes());
out.extend_from_slice(tag);
out.extend_from_slice(body);
out.extend_from_slice(&crc.to_be_bytes());
out
}
#[must_use]
pub fn make_patch(chunks: &[Vec<u8>]) -> Vec<u8> {
let total: usize = MAGIC.len() + chunks.iter().map(Vec::len).sum::<usize>();
let mut out = Vec::with_capacity(total);
out.extend_from_slice(&MAGIC);
for chunk in chunks {
out.extend_from_slice(chunk);
}
out
}