silk/inflate
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc.
Bounded streaming decoding for raw DEFLATE, zlib, and gzip bytes.
When to use
Use Decoder to decode compressed input into caller-owned output buffers.
Select Format explicitly. Use make to create state and step to decode bytes.
Use reset to reuse a decoder for another independent stream.
This module does not detect formats or encode data.
Details
Construction acquires two bounded allocations: history and table storage. Steps and reset retain no borrowed buffers and allocate nothing. Limits count consumed input, emitted output, started members, and header bytes within each independent stream. Raw and zlib stop at the first stream boundary. Gzip accepts concatenated members and requires final input.
Gotchas
Output is provisional until Finished. Discard all output after a decoding failure.
Preset dictionaries are unsupported. A failed decoder rejects steps until a successful reset.
Examples
Decode a stored block into a caller-owned buffer
import silk.allocator {Allocator, OutOfMemoryError}
import silk.effect {Effect}
import silk.inflate {Decoder, DecodeError, Format, Limits, Progress, Status}
import silk.result {Result}
effect fn decode() -> i32 ! OutOfMemoryError | DecodeError {
let mut allocator = Allocator.systemAllocatorProvider()
let limits = Limits {
maxInputBytes: 7,
maxOutputBytes: 2,
maxMembers: 1,
maxHeaderBytes: 0,
maxMemoryBytes: 65536,
}
let creating = Decoder.make(Format.Raw, move limits)
|> Effect.provideMut<Allocator>(&mut allocator)
let mut decoder = run creating
let input = b"\x01\x02\x00\xfd\xffhi"
let mut output: [u8; 2] = [0, 0]
let result = Decoder.step(&mut decoder, &input, &mut output, true)
return match move result {
Result<Progress, DecodeError>.Success {value} => inspect(move value, &output)
Result<Progress, DecodeError>.Failure {error} => 99
}
}
fn inspect(progress: Progress, output: &[u8]) -> i32 {
if progress.status != Status.Finished || progress.consumed != 7 || progress.written != 2 {
return 1
}
if output[0] != 104 || output[1] != 105 {
return 2
}
return 0
}
effect fn recover(error: OutOfMemoryError | DecodeError) -> i32 {
return 99
}
pub fn main() -> i32 {
return run Effect.catchAll(decode(), recover)
}Import as Decoder with import silk.inflate { Decoder }.
Public declarations: 8.
MEMORY_BOUND
pub const MEMORY_BOUND: u64A conservative byte bound for decoder storage, owned tables, and temporary decoding state.
Details
The bound excludes caller buffers and allocator metadata. A larger allowance does not increase storage.
Format
pub enum FormatThe explicit compressed container format.
Raw
Raw = 0One raw RFC 1951 DEFLATE stream.
Zlib
Zlib = 1One RFC 1950 zlib stream without a preset dictionary.
Gzip
Gzip = 2An RFC 1952 gzip stream with one or more concatenated members.
Status
pub enum StatusThe next action required after a successful step.
NeedInput
NeedInput = 0Supply more input after discarding exactly the consumed prefix.
NeedOutput
NeedOutput = 1Supply another output buffer and resubmit the unconsumed input suffix.
Finished
Finished = 2The selected container and its integrity checks are complete.
Limits
pub struct LimitsExplicit cumulative resource allowances. Zero permits no units of that resource.
Field maxInputBytes
pub maxInputBytes: u64The maximum total number of consumed compressed bytes.
Field maxOutputBytes
pub maxOutputBytes: u64The maximum total number of emitted uncompressed bytes.
Field maxMembers
pub maxMembers: u64The maximum number of started members. Raw and zlib each count as one member.
Field maxHeaderBytes
pub maxHeaderBytes: u64The maximum total number of wrapper header bytes, including gzip optional fields and header CRC.
Field maxMemoryBytes
pub maxMemoryBytes: u64The available decoder storage allowance. It must be at least MEMORY_BOUND.
Progress
pub struct ProgressExact progress within one call and the next required action.
Field consumed
pub consumed: usizeThe input prefix consumed by this call.
Field written
pub written: usizeThe output prefix initialized by this call.
Field status
pub status: StatusThe next action required from the caller.
ErrorKind
pub enum ErrorKindA decoding failure category or the resource allowance that was exceeded.
InvalidHeader
InvalidHeader = 0A wrapper header violates its format.
UnsupportedMethod
UnsupportedMethod = 1A wrapper requests a compression method other than DEFLATE.
UnsupportedDictionary
UnsupportedDictionary = 2A zlib header requests an unsupported preset dictionary.
InvalidBlock
InvalidBlock = 3A block type, stored length, or compressed symbol is invalid.
InvalidHuffman
InvalidHuffman = 4A Huffman alphabet or code-length repeat is invalid.
InvalidDistance
InvalidDistance = 5A match refers outside initialized history or the declared window.
TruncatedInput
TruncatedInput = 6Final input ends before a required field is complete.
ChecksumMismatch
ChecksumMismatch = 7A header or data checksum does not match.
SizeMismatch
SizeMismatch = 8A gzip member size does not match its trailer.
InvalidUse
InvalidUse = 9The decoder failed earlier or the final-input contract was violated.
InputLimit
InputLimit = 10Consuming the next byte would exceed the input allowance.
OutputLimit
OutputLimit = 11Emitting the next byte would exceed the output allowance.
MemberLimit
MemberLimit = 12Starting a member would exceed the member allowance.
HeaderLimit
HeaderLimit = 13Consuming a header byte would exceed the header allowance.
MemoryLimit
MemoryLimit = 14Construction or reset cannot fit within the decoder storage allowance.
DecodeError
pub struct DecodeErrorA typed failure with exact progress for the failing call.
Gotchas
The written prefix can contain provisional output. Discard the decoded stream after a step failure. A rejected reset leaves the original decoder and its output unchanged.
Field kind
pub kind: ErrorKindThe failure category.
Field consumed
pub consumed: usizeThe input prefix consumed before failure in this call.
Field written
pub written: usizeThe output prefix initialized before failure in this call.
Decoder
pub struct DecoderAn owned, bounded decoder with no retained input or output borrow.
Details
Drop releases its history and table allocations. A finished decoder returns Finished with zero progress on later calls.
A failed decoder rejects later steps with InvalidUse.
A successful reset starts another independent stream with the same owned storage.
Associated function Decoder.make
pub effect<'static> fn make(format: Format, limits: Limits) -> Decoder ! OutOfMemoryError | DecodeError ? &mut AllocatorCreates a decoder and acquires bounded history and table storage through the current allocator.
Details
Construction fails with MemoryLimit or MemberLimit before allocation if either allowance is insufficient.
Allocation failure is OutOfMemoryError. The first member counts at construction.
Method Decoder.reset
pub fn reset<'life0>(self: &'life0 mut Decoder, format: Format, limits: Limits) -> silk/result.Result<(), silk/inflate.DecodeError>Starts another independent stream with the existing decoder storage.
When to use
Use after completion, failure, or abandonment to reuse storage without an allocator requirement.
Details
Success replaces the format and limits and restores fresh stream behavior. Reset allocates nothing.
The first member counts immediately. Counters and final-input obligations start again for the new stream.
The memory allowance must cover MEMORY_BOUND, and the member allowance must be nonzero.
These checks occur in that order before mutation. Rejection returns MemoryLimit or MemberLimit with zero progress.
A rejected reset leaves the decoder unchanged. An in-progress stream can continue.
Gotchas
Reset does not validate, reclaim, or erase previous output. Output from failed or abandoned streams remains provisional. Reset does not securely erase the decoder storage.
Method Decoder.step
pub fn step<'life0, 'life1, 'life2>(self: &'life0 mut Decoder, input: &'life1 [u8], output: &'life2 mut [u8], finalInput: bool) -> silk/result.Result<silk/inflate.Progress, silk/inflate.DecodeError>Decodes input into the supplied output buffer and returns exact per-call progress.
Details
Resubmit only the unconsumed input suffix. Once finalInput is true, keep it true and preserve that suffix length.
The caller must preserve suffix contents. A later call can provide a new output buffer of any length.
Steps allocate nothing and retain no buffer borrow. An empty output returns NeedOutput when emission is required.
Raw and zlib leave trailing input unconsumed. Gzip waits for final exhaustion after a complete member.
Gotchas
Output remains provisional until Finished. A failure poisons the decoder; discard all output after failure.
Limits are cumulative across calls and gzip members until a successful reset.
Checks occur before the excess byte or member is accepted.