Function decodeLiteralsSlice [src]
Decode len bytes of literals into dest.
Errors returned:
error.MalformedLiteralsLength if the number of literal bytes
decoded by self plus len is greater than the regenerated size of
literals
error.UnexpectedEndOfLiteralStream and error.NotFound if there
are problems decoding Huffman compressed literals
Prototype
pub fn decodeLiteralsSlice( self: *DecodeState, dest: []u8, len: usize, ) DecodeLiteralsError!void
Parameters
self: *DecodeState
dest: []u8
len: usize
Possible Errors
Source
pub fn decodeLiteralsSlice(
self: *DecodeState,
dest: []u8,
len: usize,
) DecodeLiteralsError!void {
if (self.literal_written_count + len > self.literal_header.regenerated_size)
return error.MalformedLiteralsLength;
switch (self.literal_header.block_type) {
.raw => {
const literal_data = self.literal_streams.one[self.literal_written_count..][0..len];
@memcpy(dest[0..len], literal_data);
self.literal_written_count += len;
self.written_count += len;
},
.rle => {
for (0..len) |i| {
dest[i] = self.literal_streams.one[0];
}
self.literal_written_count += len;
self.written_count += len;
},
.compressed, .treeless => {
// const written_bytes_per_stream = (literals.header.regenerated_size + 3) / 4;
const huffman_tree = self.huffman_tree orelse unreachable;
const max_bit_count = huffman_tree.max_bit_count;
const starting_bit_count = LiteralsSection.HuffmanTree.weightToBitCount(
huffman_tree.nodes[huffman_tree.symbol_count_minus_one].weight,
max_bit_count,
);
var bits_read: u4 = 0;
var huffman_tree_index: usize = huffman_tree.symbol_count_minus_one;
var bit_count_to_read: u4 = starting_bit_count;
for (0..len) |i| {
var prefix: u16 = 0;
while (true) {
const new_bits = self.readLiteralsBits(bit_count_to_read) catch |err| {
return err;
};
prefix <<= bit_count_to_read;
prefix |= new_bits;
bits_read += bit_count_to_read;
const result = huffman_tree.query(huffman_tree_index, prefix) catch |err| {
return err;
};
switch (result) {
.symbol => |sym| {
dest[i] = sym;
bit_count_to_read = starting_bit_count;
bits_read = 0;
huffman_tree_index = huffman_tree.symbol_count_minus_one;
break;
},
.index => |index| {
huffman_tree_index = index;
const bit_count = LiteralsSection.HuffmanTree.weightToBitCount(
huffman_tree.nodes[index].weight,
max_bit_count,
);
bit_count_to_read = bit_count - bits_read;
},
}
}
}
self.literal_written_count += len;
self.written_count += len;
},
}
}