Function decodeBlock [src]

Decode a single block from src into dest. The beginning of src must be the start of the block content (i.e. directly after the block header). Increments consumed_count by the number of bytes read from src to decode the block and returns the decompressed size of the block. Errors returned: error.BlockSizeOverMaximum if block's size is larger than 1 << 17 or dest[written_count..].len error.MalformedBlockSize if src.len is smaller than the block size and the block is a raw or compressed block error.ReservedBlock if the block is a reserved block error.MalformedRleBlock if the block is an RLE block and src.len < 1 error.MalformedCompressedBlock if there are errors decoding a compressed block error.DestTooSmall is dest is not large enough to hold the decompressed block

Prototype

pub fn decodeBlock( dest: []u8, src: []const u8, block_header: frame.Zstandard.Block.Header, decode_state: *DecodeState, consumed_count: *usize, block_size_max: usize, written_count: usize, ) (error{DestTooSmall} || Error)!usize

Parameters

dest: []u8src: []const u8block_header: frame.Zstandard.Block.Headerdecode_state: *DecodeStateconsumed_count: *usizeblock_size_max: usizewritten_count: usize

Source

pub fn decodeBlock( dest: []u8, src: []const u8, block_header: frame.Zstandard.Block.Header, decode_state: *DecodeState, consumed_count: *usize, block_size_max: usize, written_count: usize, ) (error{DestTooSmall} || Error)!usize { const block_size = block_header.block_size; if (block_size_max < block_size) return error.BlockSizeOverMaximum; switch (block_header.block_type) { .raw => { if (src.len < block_size) return error.MalformedBlockSize; if (dest[written_count..].len < block_size) return error.DestTooSmall; @memcpy(dest[written_count..][0..block_size], src[0..block_size]); consumed_count.* += block_size; decode_state.written_count += block_size; return block_size; }, .rle => { if (src.len < 1) return error.MalformedRleBlock; if (dest[written_count..].len < block_size) return error.DestTooSmall; for (written_count..block_size + written_count) |write_pos| { dest[write_pos] = src[0]; } consumed_count.* += 1; decode_state.written_count += block_size; return block_size; }, .compressed => { if (src.len < block_size) return error.MalformedBlockSize; var bytes_read: usize = 0; const literals = decodeLiteralsSectionSlice(src[0..block_size], &bytes_read) catch return error.MalformedCompressedBlock; var fbs = std.io.fixedBufferStream(src[bytes_read..block_size]); const fbs_reader = fbs.reader(); const sequences_header = decodeSequencesHeader(fbs_reader) catch return error.MalformedCompressedBlock; decode_state.prepare(fbs_reader, literals, sequences_header) catch return error.MalformedCompressedBlock; bytes_read += fbs.pos; var bytes_written: usize = 0; { const bit_stream_bytes = src[bytes_read..block_size]; var bit_stream: readers.ReverseBitReader = undefined; bit_stream.init(bit_stream_bytes) catch return error.MalformedCompressedBlock; if (sequences_header.sequence_count > 0) { decode_state.readInitialFseState(&bit_stream) catch return error.MalformedCompressedBlock; var sequence_size_limit = block_size_max; for (0..sequences_header.sequence_count) |i| { const write_pos = written_count + bytes_written; const decompressed_size = decode_state.decodeSequenceSlice( dest, write_pos, &bit_stream, sequence_size_limit, i == sequences_header.sequence_count - 1, ) catch |err| switch (err) { error.DestTooSmall => return error.DestTooSmall, else => return error.MalformedCompressedBlock, }; bytes_written += decompressed_size; sequence_size_limit -= decompressed_size; } } if (!bit_stream.isEmpty()) { return error.MalformedCompressedBlock; } } if (decode_state.literal_written_count < literals.header.regenerated_size) { const len = literals.header.regenerated_size - decode_state.literal_written_count; if (len > dest[written_count + bytes_written ..].len) return error.DestTooSmall; decode_state.decodeLiteralsSlice(dest[written_count + bytes_written ..], len) catch return error.MalformedCompressedBlock; bytes_written += len; } switch (decode_state.literal_header.block_type) { .treeless, .compressed => { if (!decode_state.isLiteralStreamEmpty()) return error.MalformedCompressedBlock; }, .raw, .rle => {}, } consumed_count.* += block_size; return bytes_written; }, .reserved => return error.ReservedBlock, } }