// The literals section of a compressed block (RFC 8878 section 3.1.1.3.1).
///|
/// Makes `literals` hold at least `n` bytes.
fn Decoder::reserve_literals(self : Decoder, n : Int32) -> Unit {
if self.literals.length() < n {
self.literals = FixedArray::make(n, b'\x00')
}
}
///|
/// Decodes the literals section at the start of `block[0:size]` into
/// `literals[0:literals_len]`. Returns where the sequences section starts.
fn Decoder::decode_literals(self : Decoder, size : Int32) -> Int32 raise Stop {
let block = self.block
let section = checked(
@header.parse_literals_header(block[0:size], self.block_max),
)
let header = section.header_len
let regenerated = section.regenerated
let end = header + section.compressed
match section.block_type {
RawLiterals => {
self.reserve_literals(regenerated)
self.literals_len = regenerated
FixedArray::unsafe_blit(self.literals, 0, block, header, regenerated)
}
RleLiterals => {
self.reserve_literals(regenerated)
self.literals_len = regenerated
self.literals.fill(block[header], start=0, end=regenerated)
}
CompressedLiterals | TreelessLiterals as block_type => {
let mut streams = header
if block_type is CompressedLiterals {
streams += self.huffman.read(block, header, end, self.scratch)
self.huffman_valid = true
} else if !self.huffman_valid {
raise corrupt("treeless literals before any Huffman table")
}
self.reserve_literals(regenerated)
self.literals_len = regenerated
self.huffman.decode(
block,
streams,
end,
self.literals,
regenerated,
section.four_streams(),
)
}
}
end
}