Function decodeBlockRingBuffer [src]

Decode a single block from src into dest; see decodeBlock(). Returns the size of the decompressed block, which can be used with dest.sliceLast() to get the decompressed bytes. error.BlockSizeOverMaximum is returned if the block's compressed or decompressed size is larger than block_size_max.

Prototype

pub fn decodeBlockRingBuffer( dest: *RingBuffer, src: []const u8, block_header: frame.Zstandard.Block.Header, decode_state: *DecodeState, consumed_count: *usize, block_size_max: usize, ) Error!usize

Parameters

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

Possible Errors

BlockSizeOverMaximum
MalformedBlockSize
MalformedCompressedBlock
MalformedRleBlock
ReservedBlock

Source

pub fn decodeBlockRingBuffer( dest: *RingBuffer, src: []const u8, block_header: frame.Zstandard.Block.Header, decode_state: *DecodeState, consumed_count: *usize, block_size_max: usize, ) 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; // dest may have length zero if block_size == 0, causing division by zero in // writeSliceAssumeCapacity() if (block_size > 0) { const data = src[0..block_size]; dest.writeSliceAssumeCapacity(data); consumed_count.* += block_size; decode_state.written_count += block_size; } return block_size; }, .rle => { if (src.len < 1) return error.MalformedRleBlock; for (0..block_size) |_| { dest.writeAssumeCapacity(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 decompressed_size = decode_state.decodeSequenceRingBuffer( dest, &bit_stream, sequence_size_limit, i == sequences_header.sequence_count - 1, ) catch 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; decode_state.decodeLiteralsRingBuffer(dest, 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; if (bytes_written > block_size_max) return error.BlockSizeOverMaximum; return bytes_written; }, .reserved => return error.ReservedBlock, } }