ZXC 0.15.0
High-performance asymmetric lossless compression library
Loading...
Searching...
No Matches
zxc_pstream.c File Reference

Push-based, single-threaded streaming driver implementation. More...

Go to the source code of this file.

Enumerations

enum  cstream_state_t {
  CS_INIT = 0 , CS_DRAIN_HEADER , CS_ACCUMULATE , CS_DRAIN_BLOCK ,
  CS_DRAIN_LAST , CS_DRAIN_EOF , CS_DRAIN_FOOTER , CS_DONE ,
  CS_ERRORED
}
 Lifecycle states of the push compression stream. More...
 
enum  dstream_state_t {
  DS_NEED_FILE_HEADER = 0 , DS_NEED_BLOCK_HEADER , DS_NEED_BLOCK_PAYLOAD , DS_DECODE_BLOCK ,
  DS_EMIT_DECODED , DS_NEED_SEK_HEADER , DS_DRAIN_SEK_PAYLOAD , DS_NEED_FOOTER ,
  DS_VALIDATE_FOOTER , DS_DONE , DS_ERRORED
}
 Lifecycle states of the push decompression stream. More...
 

Functions

static int cs_set_error (zxc_cstream *cs, const int code)
 Latches a sticky error on the compression stream.
 
static int cs_compress_block_from (zxc_cstream *cs, const uint8_t *src, const size_t len)
 Compresses one block from src into cs->pending.
 
static int cs_compress_one_block (zxc_cstream *cs)
 Compresses the accumulated (full or partial) block.
 
static size_t zxc_outbuf_push (zxc_outbuf_t *out, const uint8_t *src, size_t *pos, const size_t len)
 Copies what fits of a staged buffer into the caller's output.
 
static int cs_drain_pending (zxc_cstream *cs, zxc_outbuf_t *out)
 Flushes the pending staging buffer; 1 once fully drained.
 
zxc_cstream * zxc_cstream_create (const zxc_compress_opts_t *opts)
 Allocates and initialises a push compression stream.
 
static int cs_stage_file_header (zxc_cstream *cs)
 Stages the 16-byte file header into the pending buffer.
 
static int cs_stage_eof (zxc_cstream *cs)
 Stages the 8-byte EOF block into the pending buffer.
 
static int cs_stage_footer (zxc_cstream *cs)
 Stages the file footer into the pending buffer.
 
void zxc_cstream_free (zxc_cstream *cs)
 Releases a compression stream and all internal buffers.
 
size_t zxc_cstream_in_size (const zxc_cstream *cs)
 Returns the suggested input chunk size (configured block size).
 
size_t zxc_cstream_out_size (const zxc_cstream *cs)
 Returns the suggested output chunk size.
 
int64_t zxc_cstream_compress (zxc_cstream *cs, zxc_outbuf_t *out, zxc_inbuf_t *in)
 Push-side entry point: feeds input and drains compressed output.
 
int64_t zxc_cstream_end (zxc_cstream *cs, zxc_outbuf_t *out)
 Finalises the stream: residual block (if any), EOF, and footer.
 
static int ds_set_error (zxc_dstream *ds, const int code)
 Latches a sticky error on the decompression stream.
 
static int ds_pull (uint8_t *dst, size_t *used, const size_t need, zxc_inbuf_t *in)
 Accumulates caller input into a buffer until it holds the wanted size.
 
static void ds_free_buffers (zxc_dstream *ds)
 Releases the per-frame buffers; the next header allocates them anew.
 
static void ds_start_frame (zxc_dstream *ds)
 Puts ds at the start of a frame, its buffers kept for reuse.
 
zxc_dstream * zxc_dstream_create (const zxc_decompress_opts_t *opts)
 Allocates and initialises a push decompression stream.
 
void zxc_dstream_free (zxc_dstream *ds)
 Releases a decompression stream and all internal buffers.
 
int zxc_dstream_finished (const zxc_dstream *ds)
 Returns 1 iff the stream has reached DS_DONE.
 
size_t zxc_dstream_in_size (const zxc_dstream *ds)
 Returns the suggested input chunk size for the decompressor.
 
size_t zxc_dstream_out_size (const zxc_dstream *ds)
 Returns the suggested output chunk size for the decompressor.
 
static int ds_drain_decoded (zxc_dstream *ds, zxc_outbuf_t *out, size_t *produced)
 Flushes the decoded block; 1 once fully drained.
 
static int ds_handle_need_file_header (zxc_dstream *ds, zxc_inbuf_t *in)
 Handles the DS_NEED_FILE_HEADER state.
 
static int ds_handle_need_block_header (zxc_dstream *ds, zxc_inbuf_t *in)
 Handles the DS_NEED_BLOCK_HEADER state.
 
int64_t zxc_dstream_decompress (zxc_dstream *ds, zxc_outbuf_t *out, zxc_inbuf_t *in)
 Push-side entry point: feeds compressed input and drains decoded output.
 

Detailed Description

Push-based, single-threaded streaming driver implementation.

See zxc_pstream.h for the public contract. The implementation drives the internal block codec (zxc_compress_block_at, zxc_decompress_chunk_wrapper and their context) with the sans-IO layout helpers of zxc_internal.h: the header, footer and block-header readers and writers, the seek-table and footer sizes, the digest fold.

Both compression and decompression are structured as resumable state machines driven by caller-provided input/output buffers (zxc_inbuf_t / zxc_outbuf_t). Each call advances as much as possible without blocking and returns a status indicating whether the caller should drain out, supply more in, or finalise the stream.

Definition in file zxc_pstream.c.

Enumeration Type Documentation

◆ cstream_state_t

Lifecycle states of the push compression stream.

The compression state machine alternates between staging a chunk of output bytes into the pending buffer and draining those bytes into the caller's zxc_outbuf_t. Forward progress is therefore always either consuming from in or producing into out.

Enumerator
CS_INIT 

Initial state; nothing has been emitted yet.

CS_DRAIN_HEADER 

File header staged in pending; draining to out, then transitions to CS_ACCUMULATE.

CS_ACCUMULATE 

Copying input bytes into the internal block accumulator until it is full (or the stream is finalised).

CS_DRAIN_BLOCK 

A full data block was just compressed; draining it to out, then back to CS_ACCUMULATE.

CS_DRAIN_LAST 

Draining the final partial block produced inside zxc_cstream_end; transitions to CS_DRAIN_EOF.

CS_DRAIN_EOF 

Draining the EOF block; transitions to CS_DRAIN_FOOTER.

CS_DRAIN_FOOTER 

Draining the file footer; transitions to CS_DONE.

CS_DONE 

Finalisation complete; further _compress / _end calls are rejected.

CS_ERRORED 

Sticky error state; subsequent calls return the latched error code.

Definition at line 69 of file zxc_pstream.c.

◆ dstream_state_t

Lifecycle states of the push decompression stream.

The decompressor implements a frame-aware parser: file header -> N (data block header + payload [+ optional checksum]) -> EOF block -> optional SEK index block -> file footer. The states alternate between pulling fixed- or variable-sized chunks from the caller's input, and emitting the corresponding decoded output.

Enumerator
DS_NEED_FILE_HEADER 

Pulling the 16-byte file header into scratch.

DS_NEED_BLOCK_HEADER 

Pulling an 8-byte block header into scratch.

DS_NEED_BLOCK_PAYLOAD 

Pulling a data block payload (and optional checksum) into payload.

DS_DECODE_BLOCK 

Calling the underlying block decoder on the accumulated payload.

DS_EMIT_DECODED 

Draining decoded bytes from decoded into out.

DS_NEED_SEK_HEADER 

Just past the EOF block of an archive whose header announced a seek table: pulling and validating its SEK block header.

DS_DRAIN_SEK_PAYLOAD 

Skipping the SEK payload bytes.

DS_NEED_FOOTER 

Pulling the file footer.

DS_VALIDATE_FOOTER 

Validating total_out.

DS_DONE 

A frame fully consumed and validated; a call with more input starts the next one.

DS_ERRORED 

Sticky error state; subsequent calls return the latched code.

Definition at line 604 of file zxc_pstream.c.

Function Documentation

◆ cs_compress_block_from()

static int cs_compress_block_from ( zxc_cstream *  cs,
const uint8_t *  src,
const size_t  len 
)
static

Compresses one block from src into cs->pending.

Grows pending to zxc_compress_block_bound if needed and updates bookkeeping (block_index, total_in). src is either the in_block accumulator (via cs_compress_one_block) or the caller's input buffer directly (the full-block fast path in zxc_cstream_compress, which skips the staging memcpy).

Precondition
len > 0.
Parameters
[in,out]csCompression stream.
[in]srcBlock bytes to compress (only [src, src+len) is read).
[in]lenBlock length in bytes.
Returns
ZXC_OK on success, negative zxc_error_t on failure.

Definition at line 181 of file zxc_pstream.c.

References ZXC_BLOCK_CHECKSUM_SIZE, zxc_compress_block_at(), zxc_compress_block_bound(), zxc_digest_combine(), ZXC_ERROR_MEMORY, ZXC_ERROR_OVERFLOW, zxc_le32(), ZXC_OK, and ZXC_REALLOC.

Referenced by cs_compress_one_block(), and zxc_cstream_compress().

◆ cs_compress_one_block()

static int cs_compress_one_block ( zxc_cstream *  cs)
static

Compresses the accumulated (full or partial) block.

Convenience wrapper around cs_compress_block_from for the staging path: compresses cs->in_block[0..in_used) into cs->pending and, on success, resets in_used to 0 so the accumulator is ready for the next block. On failure the accumulator is left untouched.

Precondition
cs->in_used > 0.
Parameters
[in,out]csCompression stream.
Returns
ZXC_OK on success, negative zxc_error_t on failure.

Definition at line 220 of file zxc_pstream.c.

References cs_compress_block_from(), and ZXC_OK.

Referenced by zxc_cstream_compress(), and zxc_cstream_end().

◆ cs_drain_pending()

static int cs_drain_pending ( zxc_cstream *  cs,
zxc_outbuf_t *  out 
)
static

Flushes the pending staging buffer; 1 once fully drained.

Definition at line 246 of file zxc_pstream.c.

References zxc_outbuf_push().

Referenced by zxc_cstream_compress(), and zxc_cstream_end().

◆ cs_set_error()

static int cs_set_error ( zxc_cstream *  cs,
const int  code 
)
static

Latches a sticky error on the compression stream.

Stores code in cs->error_code, transitions cs->state to CS_ERRORED, and returns code. Once errored, subsequent zxc_cstream_compress / zxc_cstream_end calls return the same code without performing further work.

Parameters
[in,out]csCompression stream.
[in]codeNegative zxc_error_t value to latch.
Returns
code (always negative).

Definition at line 158 of file zxc_pstream.c.

References CS_ERRORED.

Referenced by zxc_cstream_compress(), and zxc_cstream_end().

◆ cs_stage_eof()

static int cs_stage_eof ( zxc_cstream *  cs)
static

Stages the 8-byte EOF block into the pending buffer.

The EOF block is a regular block header with block_type set to ZXC_BLOCK_EOF and comp_size = 0; it carries no payload.

Parameters
[in,out]csCompression stream.
Returns
ZXC_OK on success, negative zxc_error_t on failure.

Definition at line 344 of file zxc_pstream.c.

References zxc_block_header_t::block_type, ZXC_BLOCK_HEADER_SIZE, ZXC_ERROR_MEMORY, ZXC_OK, ZXC_REALLOC, and zxc_write_block_header().

Referenced by zxc_cstream_end().

◆ cs_stage_file_header()

static int cs_stage_file_header ( zxc_cstream *  cs)
static

Stages the 16-byte file header into the pending buffer.

Parameters
[in,out]csCompression stream.
Returns
ZXC_OK on success, negative zxc_error_t on failure.

Definition at line 325 of file zxc_pstream.c.

References ZXC_OK, and zxc_write_file_header().

Referenced by zxc_cstream_compress(), and zxc_cstream_end().

◆ cs_stage_footer()

static int cs_stage_footer ( zxc_cstream *  cs)
static

Stages the file footer into the pending buffer.

The footer carries the input size and the compressed size; pending holds the largest one from creation.

Parameters
[in,out]csCompression stream.
Returns
ZXC_OK on success, negative zxc_error_t on failure.

Definition at line 377 of file zxc_pstream.c.

References ZXC_OK, and zxc_write_file_footer().

Referenced by zxc_cstream_end().

◆ ds_drain_decoded()

static int ds_drain_decoded ( zxc_dstream *  ds,
zxc_outbuf_t *  out,
size_t *  produced 
)
static

Flushes the decoded block; 1 once fully drained.

produced is optional.

Definition at line 855 of file zxc_pstream.c.

References zxc_outbuf_push().

Referenced by zxc_dstream_decompress().

◆ ds_free_buffers()

static void ds_free_buffers ( zxc_dstream *  ds)
static

Releases the per-frame buffers; the next header allocates them anew.

Definition at line 764 of file zxc_pstream.c.

References zxc_cctx_free(), and ZXC_FREE.

Referenced by ds_handle_need_file_header(), and zxc_dstream_free().

◆ ds_handle_need_block_header()

static int ds_handle_need_block_header ( zxc_dstream *  ds,
zxc_inbuf_t *  in 
)
static

Handles the DS_NEED_BLOCK_HEADER state.

Pulls 8 bytes into scratch and parses them as a block header. If the block is an EOF block, transitions to DS_NEED_SEK_HEADER or DS_NEED_FOOTER, as the file header's seek-table flag says. Otherwise, validates the announced comp_size against the payload buffer capacity, copies the parsed header into payload (the underlying decoder expects header

  • body + optional checksum as a single contiguous frame), and transitions to DS_NEED_BLOCK_PAYLOAD.
Parameters
[in,out]dsDecompression stream.
[in,out]inCaller input buffer.
Returns
1 if more input is needed, 0 to continue the outer loop, negative zxc_error_t on validation/allocation failure.

Definition at line 944 of file zxc_pstream.c.

References DS_NEED_BLOCK_PAYLOAD, DS_NEED_FOOTER, DS_NEED_SEK_HEADER, ds_pull(), ds_set_error(), zxc_footer_layout_t::len, ZXC_BLOCK_CHECKSUM_SIZE, ZXC_BLOCK_HEADER_SIZE, zxc_check_eof_header(), ZXC_ERROR_BAD_BLOCK_SIZE, ZXC_ERROR_BAD_HEADER, ZXC_ERROR_MEMORY, zxc_footer_layout(), ZXC_OK, zxc_read_block_header(), and ZXC_REALLOC.

Referenced by zxc_dstream_decompress().

◆ ds_handle_need_file_header()

static int ds_handle_need_file_header ( zxc_dstream *  ds,
zxc_inbuf_t *  in 
)
static

Handles the DS_NEED_FILE_HEADER state.

Pulls the 16-byte file header into scratch, parses it via zxc_read_file_header, and lazily allocates the payload and decoded buffers (sized from the negotiated block_size). The decoded buffer is over-allocated by ZXC_DECOMPRESS_TAIL_PAD bytes to absorb wild-copy overflow and give the decoder's 4x ML bounds checks their required tail headroom. Initialises the underlying decompression context and transitions to DS_NEED_BLOCK_HEADER.

Parameters
[in,out]dsDecompression stream.
[in,out]inCaller input buffer.
Returns
1 if more input is needed, 0 to continue the outer loop, negative zxc_error_t on validation/allocation failure.

Definition at line 878 of file zxc_pstream.c.

References ds_free_buffers(), DS_NEED_BLOCK_HEADER, ds_pull(), ds_set_error(), ZXC_BLOCK_HEADER_SIZE, zxc_cctx_init(), zxc_compress_block_bound(), ZXC_DECOMPRESS_TAIL_PAD, ZXC_ERROR_CORRUPT_DATA, ZXC_ERROR_DICT_REQUIRED, ZXC_ERROR_MEMORY, ZXC_ERROR_OVERFLOW, ZXC_FILE_HEADER_SIZE, zxc_magic_prefix_ok(), ZXC_MALLOC, ZXC_OK, and zxc_read_file_header().

Referenced by zxc_dstream_decompress().

◆ ds_pull()

static int ds_pull ( uint8_t *  dst,
size_t *  used,
const size_t  need,
zxc_inbuf_t *  in 
)
static

Accumulates caller input into a buffer until it holds the wanted size.

The single input pump: the fixed-size frame accumulator (headers, footer, EOF peek) and the variable-size block payload differ only in the buffer they fill. Returns 1 once the target size is reached, 0 if more input is needed.

Definition at line 750 of file zxc_pstream.c.

References zxc_inbuf_t::pos, zxc_inbuf_t::size, and zxc_inbuf_t::src.

Referenced by ds_handle_need_block_header(), ds_handle_need_file_header(), and zxc_dstream_decompress().

◆ ds_set_error()

static int ds_set_error ( zxc_dstream *  ds,
const int  code 
)
static

Latches a sticky error on the decompression stream.

Stores code in ds->error_code, transitions ds->state to DS_ERRORED, and returns code. Once errored, subsequent zxc_dstream_decompress calls return the same code without performing further work.

Parameters
[in,out]dsDecompression stream.
[in]codeNegative zxc_error_t value to latch.
Returns
code (always negative).

Definition at line 737 of file zxc_pstream.c.

References DS_ERRORED.

Referenced by ds_handle_need_block_header(), ds_handle_need_file_header(), and zxc_dstream_decompress().

◆ ds_start_frame()

static void ds_start_frame ( zxc_dstream *  ds)
static

Puts ds at the start of a frame, its buffers kept for reuse.

Definition at line 776 of file zxc_pstream.c.

References DS_NEED_FILE_HEADER, and ZXC_FILE_HEADER_SIZE.

Referenced by zxc_dstream_create(), and zxc_dstream_decompress().

◆ zxc_outbuf_push()

static size_t zxc_outbuf_push ( zxc_outbuf_t *  out,
const uint8_t *  src,
size_t *  pos,
const size_t  len 
)
static

Copies what fits of a staged buffer into the caller's output.

The single output pump: the compressor's pending buffer and the decompressor's decoded block both drain through it. Returns the byte count.

Definition at line 232 of file zxc_pstream.c.

References zxc_outbuf_t::dst, zxc_outbuf_t::pos, and zxc_outbuf_t::size.

Referenced by cs_drain_pending(), and ds_drain_decoded().