Pure-MoonBit, runtime-agnostic DEFLATE (RFC 1951) engine with gzip/zlib wrappers — suspendable and io-free.
moon add moonbit-community/flate///|
test "README raw DEFLATE round-trip" {
let source = b"runtime-agnostic streaming compression"
let compressed = @flate.deflate_all(source)
assert_eq(@flate.inflate_all(compressed), source)
}///|
test "README streaming Deflater" {
let source = b"small buffers exercise suspension and resume"
let encoder = @flate.Deflater::new()
let chunk = FixedArray::make(3, b'\x00')
let compressed = Buffer()
let mut first = true
for ;; {
let input = if first { source[:] } else { b""[:] }
let status = encoder.step(
input,
chunk.mut_view(),
action=if first { Finish } else { Continue },
)
let consumed = encoder.last_consumed()
let produced = encoder.last_produced()
assert_eq(consumed, if first { source.length() } else { 0 })
first = false
for i in 0..<produced {
compressed.write_byte(chunk[i])
}
if status is Done {
break
}
}
assert_eq(@flate.inflate_all(compressed.to_bytes()), source)
}///|
test "README exact and limited inflate" {
let source = b"bounded convenience API"
let compressed = @flate.deflate_all(source)
assert_eq(@flate.inflate_exact(compressed), source)
assert_eq(
@flate.inflate_all_limited(compressed, max_output=source.length()),
source,
)
}ENCODE: bytes → raw DEFLATE
═══════════════════════════
deflate_all Deflater::step deflate_all_optimal(input)
one-shot streaming, suspendable; one-shot, offline (zopfli-style)
greedy sync flush, preset dict
│ │ │
└──────┬───────┘ │
▼ ▼
┌─ parser ─────────────────┐ ┌─ parser ───────────────────┐
│ lz77.mbt │ │ optimal_parse.mbt │
│ greedy/lazy hash chains │ │ squeeze: iterated │
│ (levels 1-9; 0 = stored) │ │ cost-optimal shortest path │
├─ block driver ───────────┤ ├─ planner ──────────────────┤
│ block_planner.mbt (strm) │ │ optimal_plan.mbt │
│ or deflate_all.mbt inline│ │ content-driven splitting │
│ both: 16 KB blocks │ │ (FindMinimum + resplit) │
└────────────┬─────────────┘ └─────────────┬──────────────┘
└────────────┬───────────────────┘
▼
packed tokens + caller-owned frequencies
│ ← the seam: any parser/planner
│ pair feeds the same writer
▼
block_writer.mbt ◄── huffman_build.mbt
one block: stored / (package-merge length-limited
fixed / dynamic, canonical codes)
whichever is smallest
│
▼
bitwriter.mbt (LSB-first) → raw DEFLATE bit stream
DECODE: raw DEFLATE → bytes
═══════════════════════════
raw DEFLATE bit stream
│
huffman_table.mbt — code lengths → zlib-style chunked tables
│
┌───────────┴─────────────┐
▼ ▼
Inflater::step inflate_all
(inflate.mbt) (inflate_all.mbt)
streaming, suspendable one-shot, growable output —
(internal atomic staging); trusted input only
32 KB window, 1-byte
output progress,
preset dictionary
CONTAINERS: thin framing over the engine
════════════════════════════════════════
gzip/ Encoder/Decoder, gzip_compress/gunzip (RFC 1952)
10 B header (optional fields skipped in O(1)) + CRC-32 + ISIZE;
decodes concatenated multi-member streams (§2.2)
zlib/ Encoder/Decoder, zlib_compress/zlib_decompress (RFC 1950)
2 B header (+ FDICT dictionary id) + Adler-32
checksum/ incremental CRC-32 / Adler-32 digests
shared by both pipelines:
tables.mbt RFC 1951 symbol tables, fixed codes, window size
decode_rules.mbt pure distance/count/stored-block/history validation shared
by the one-shot and streaming decoders
status.mbt Done / NeedMoreInput / NeedMoreOutputpub struct Deflater {
// private fields
}fn Deflater::step(self : Deflater, input : BytesView, output : MutArrayView[Byte], action? : DeflateAction) -> Statuspub struct Inflater {
// private fields
}fn Inflater::step(self : Inflater, input : BytesView, output : MutArrayView[Byte], end? : Bool) -> Status raise InflateErrorfn deflate_all(input : Bytes, level? : Int) -> Bytesfn deflate_all_optimal(input : Bytes, iterations? : Int) -> BytesPure-MoonBit, runtime-agnostic DEFLATE (RFC 1951) engine with gzip/zlib wrappers — suspendable and io-free.