pub struct SqpkCompressedBlock { /* private fields */ }Expand description
One block of a SqpkFile AddFile payload, which may be DEFLATE-compressed
or stored raw.
SqpkFile payloads are split into a sequence of these blocks. Each block
begins with a 16-byte little-endian header that describes the compressed
and decompressed sizes, followed by the data bytes padded to a 128-byte
boundary.
§Compression sentinel
The compressed_size field in the wire header uses the value 0x7d00
(decimal 32000) as a sentinel meaning “this block is not compressed”.
Any other value means the data bytes are a raw DEFLATE stream
(no zlib wrapper, no gzip header — just RFC 1951 raw deflate).
§Wire format of one block (all little-endian)
┌─────────────────────────────────────────────────────────────────────┐
│ header_size : i32 LE always 16 in practice │ bytes 0–3
│ <pad> : u32 LE always zero │ bytes 4–7
│ compressed_size : i32 LE byte count of DEFLATE data │ bytes 8–11
│ OR 0x7d00 (32000) if uncompressed │
│ decompressed_size : i32 LE byte count of decompressed output │ bytes 12–15
│ data : [u8] compressed or raw bytes │ bytes 16–…
│ <alignment> : [u8] zero-padding to 128-byte boundary │
└─────────────────────────────────────────────────────────────────────┘§128-byte alignment formula
The total byte count to read for a block’s data + alignment is:
block_len = (data_len + 143) & !127where data_len is compressed_size if compressed, or decompressed_size
if uncompressed. The constant 143 is 128 - 1 + 16 (subtract the 16-byte
header that is not included in data_len, then round up to the next
128-byte boundary). The number of data bytes actually read is
block_len - header_size; the alignment padding is consumed but discarded.
§pub(crate) visibility
SqpkCompressedBlock is pub so that it appears in rustdoc and can be
named in SqpkFile::blocks, but it can only be constructed via
new (for tests) or by parsing a SqpkFile.
See SqpkFile.cs / ZiPatchConfig.cs in the XIVLauncher reference implementation.
Implementations§
Source§impl SqpkCompressedBlock
impl SqpkCompressedBlock
Sourcepub fn new(is_compressed: bool, decompressed_size: usize, data: Vec<u8>) -> Self
pub fn new(is_compressed: bool, decompressed_size: usize, data: Vec<u8>) -> Self
Construct a block directly from its component parts.
This constructor exists primarily for unit tests. Production code
creates blocks by parsing a SqpkFile from a patch byte stream.
is_compressed:trueifdatais a raw DEFLATE stream.decompressed_size: the expected number of bytes after decompression; used to pre-allocate the output buffer indecompress.data: raw compressed bytes or exact uncompressed bytes, depending onis_compressed.
Sourcepub fn decompress_into(&self, w: &mut impl Write) -> Result<()>
pub fn decompress_into(&self, w: &mut impl Write) -> Result<()>
Stream the block’s decompressed bytes into w.
For uncompressed blocks, w.write_all(&self.data) is called directly.
For compressed blocks, the data is piped through DeflateDecoder (raw
DEFLATE, RFC 1951 — no zlib or gzip wrapper) before being written.
This is the primary write path used by the apply layer: each block in a
SqpkFile AddFile operation is streamed into the target file handle
in sequence.
§Errors
ZiPatchError::Decompress— the DEFLATE stream is malformed or truncated.ZiPatchError::Io—w.write_allfailed.
Sourcepub fn decompress(&self) -> Result<Cow<'_, [u8]>>
pub fn decompress(&self) -> Result<Cow<'_, [u8]>>
Return the block’s decompressed bytes as a Cow.
Uncompressed blocks return Cow::Borrowed(&self.data) — a zero-copy
borrow into the block’s existing buffer. Compressed blocks decompress
into a newly allocated Vec and return Cow::Owned.
Use decompress_into instead
when writing to a file handle, to avoid the intermediate allocation.
§Errors
ZiPatchError::Decompress— the DEFLATE stream is malformed or truncated (compressed blocks only).
Trait Implementations§
Source§impl Clone for SqpkCompressedBlock
impl Clone for SqpkCompressedBlock
Source§fn clone(&self) -> SqpkCompressedBlock
fn clone(&self) -> SqpkCompressedBlock
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for SqpkCompressedBlock
impl Debug for SqpkCompressedBlock
Source§impl PartialEq for SqpkCompressedBlock
impl PartialEq for SqpkCompressedBlock
Source§fn eq(&self, other: &SqpkCompressedBlock) -> bool
fn eq(&self, other: &SqpkCompressedBlock) -> bool
self and other values to be equal, and is used by ==.