Programming Language

Nocter

A self-contained systems language built around simplicity, encapsulation, and foolproof design.

index.nct

//! Allocation-free progress contracts for compressed byte representations.
//!
//! This module owns compressed representation and decoder progress. External transport remains in
//! std/io, archive structure remains in std/archive, and integrity checks remain in std/checksum.

see ./decoder.nct
see ./async_reader.nct
see ./blocking_reader.nct
see ./gzip_decoder.nct
see ./gzip_storage.nct
see ./reader_cursor.nct
see ./reader_storage.nct
see ./storage.nct
see ./tests.nct

use /io.{BlockingReader, Reader}

/// Allocation-free incremental state for one raw DEFLATE stream.
///
/// The decoder retains a 32 KiB history window and format state, but never retains caller input or
/// output slices. One value decodes exactly one stream and remains terminal after completion or
/// invalidity.
pub struct InflateDecoder

/// One terminal reason that makes the inspected DEFLATE stream invalid.
pub enum InflateFailure {
    reserved_block_type
    stored_length_mismatch
    oversubscribed_tree
    incomplete_tree
    missing_end_of_block
    invalid_code_length_repeat
    invalid_literal_length_symbol
    invalid_distance_symbol
    distance_too_far
}

/// The exact outcome of one bounded inflate operation.
///
/// Every variant reports bytes consumed from the supplied input and bytes initialized in the
/// supplied output. `needs_input` and `needs_output` are resumable. `finished` and `invalid` are
/// terminal and later operations must reproduce the same terminal state without consuming input
/// or writing output.
pub enum InflateStep {
    needs_input(input_consumed: usize, output_written: usize)
    needs_output(input_consumed: usize, output_written: usize)
    finished(input_consumed: usize, output_written: usize)
    invalid(input_consumed: usize, output_written: usize, failure: InflateFailure)
}

/// Allocation-free incremental state for one concatenated gzip stream.
///
/// The decoder owns gzip framing, integrity state, and one raw DEFLATE decoder. It retains no
/// caller input or output slice. End of input is declared explicitly with `finish` so an absent
/// next member remains distinct from a truncated member.
pub struct GzipDecoder

/// An owning synchronous reader that exposes the uncompressed bytes of one gzip sequence.
///
/// Compressed input and DEFLATE history use fixed reusable storage. The wrapper never buffers the
/// complete compressed or uncompressed representation.
pub struct BlockingGzipReader<R>

/// An owning executor-safe reader that exposes the uncompressed bytes of one gzip sequence.
///
/// Cancellation may interrupt an underlying refill, but decoder progress is committed only after
/// that refill returns. Deadlines remain an outer transport concern and compose through `Reader`.
pub struct GzipReader<R>

/// One terminal reason that makes the inspected gzip stream invalid.
pub enum GzipFailure {
    invalid_magic
    unsupported_method
    reserved_flags
    header_checksum_mismatch
    invalid_payload
    checksum_mismatch
    size_mismatch
    truncated_header
    truncated_payload
    truncated_trailer
}

/// The exact outcome of one bounded gzip operation.
///
/// `member_finished` is resumable and creates an explicit boundary between concatenated members.
/// `finished` and `invalid` are terminal. Every count applies only to the current call.
pub enum GzipStep {
    needs_input(input_consumed: usize, output_written: usize)
    needs_output(input_consumed: usize, output_written: usize)
    member_finished(input_consumed: usize, output_written: usize)
    finished(input_consumed: usize, output_written: usize)
    invalid(input_consumed: usize, output_written: usize, failure: GzipFailure)
}

construct InflateDecoder {
    /// Constructs a decoder at the beginning of one raw DEFLATE stream.
    pub noalloc func new(): Self
}

instance InflateDecoder {
    /// Advances the stream with caller-owned input and output storage.
    ///
    /// Reported counts apply only to this call. Resume with the unconsumed input suffix and fresh
    /// output capacity. Empty input or output is valid, and terminal calls consume and write zero.
    pub noalloc method &+self.decode(input: &[u8], output: &+[u8]): InflateStep
}

construct GzipDecoder {
    /// Constructs a decoder before the first gzip member.
    pub noalloc func new(): Self
}

construct BlockingGzipReader<R> {
    /// Wraps a blocking compressed-byte source with the default bounded input capacity.
    pub func new(source: R): Self where R impl BlockingReader

    /// Wraps a source and normalizes a zero requested input capacity to one byte.
    pub func with_capacity(source: R, requested_capacity: usize): Self where R impl BlockingReader
}

instance BlockingGzipReader<R> where R impl BlockingReader {
    impl BlockingReader
}

construct GzipReader<R> {
    /// Wraps an executor-safe compressed-byte source with the default bounded input capacity.
    pub func new(source: R): Self where R impl Reader

    /// Wraps a source and normalizes a zero requested input capacity to one byte.
    pub func with_capacity(source: R, requested_capacity: usize): Self where R impl Reader
}

instance GzipReader<R> where R impl Reader {
    impl Reader
}

instance GzipDecoder {
    /// Advances gzip members with caller-owned input and output storage.
    ///
    /// A completed member returns `member_finished`; resume with the unconsumed input suffix. When
    /// the underlying input reaches EOF, call `finish` instead of submitting another input slice.
    pub noalloc method &+self.decode(input: &[u8], output: &+[u8]): GzipStep

    /// Declares permanent end of input and drains output already represented by decoder state.
    ///
    /// Repeat with fresh output after `needs_output`. A complete sequence ends with `finished`;
    /// every partial header, payload, or trailer ends with the corresponding truncation failure.
    pub noalloc method &+self.finish(output: &+[u8]): GzipStep
}