The first-party codecs are ordinary BASIL modules under stdlib/compress . Import only the format needed; unused code is removed by the ordinary linker. There is no zlib/libbz2/Go dependency in the production implementation. Go and Python are independent acceptance oracles.
The algorithm scope follows Go’s compress packages :
| Module | Encoding | Decoding | Format |
|---|---|---|---|
| flate.bas | Yes | Yes | RFC 1951 DEFLATE |
| zlib.bas | Yes | Yes | RFC 1950, including Adler-32 |
| gzip.bas | Yes | Yes | RFC 1952, header/body checksums and sizes |
| lzw.bas | Yes | Yes | Late-change LZW; 2–8 literal bits, 12-bit dictionary, LSB/MSB |
| bzip2.bas | No | Yes | Nonrandomized bzip2 blocks and concatenated streams |
These are buffer APIs, not a claim of Go’s complete streaming Reader/Writer API. Preset DEFLATE/zlib dictionaries and reusable streaming state are not yet exposed. TIFF early-change LZW and deprecated randomized bzip2 are rejected; Go also rejects the latter. No bzip2 encoder is implied.
API
IMPORT "../stdlib/compress/gzip.bas" AS gzip
IMPORT "../stdlib/compress/common.bas" AS compression
original=EncodeUtf8("Hello, BASIC!")
packed=gzip.Compress(original)
restored=gzip.Decompress(packed,MaxOutput=1024)
PRINT DecodeUtf8(restored)Paths above are relative to an example source in examples/. All data arguments
and results are LIST OF BYTE, preserving arbitrary bytes without UTF-8 coercion.
Inputs are borrowed for the call. Results are independent owners; failures leave
inputs unchanged and clean temporary/partial owners normally.
Compress(data, Level=1) applies to flate/zlib/gzip. Levels: 0 stored blocks,
1 fast bounded matching, 2–9 progressively longer bounded hash-chain search,
-1 default search, -2 literal-only Huffman encoding. Compression levels are
effort choices, not a promise of identical Go output or compression ratio.
The encoder currently emits fixed Huffman codes or stored blocks; the decoder
accepts fixed, dynamic and stored blocks. Level 1 uses four-byte hashing,
sparse match-position updates, and checked word comparisons. Higher levels retain
bounded chains. Incompressible output falls back to stored blocks.
Decompress(data, MaxOutput=67108864) applies to flate/zlib/gzip/bzip2. The
limit counts actual output bytes, including all concatenated members. Zero permits
empty output. Negative limits and limits above 1 GiB fail. Size checks precede
growth; advertised sizes do not grant unbounded allocation. Malformed headers,
invalid Huffman trees/history references, truncation, checksum/size mismatches
and trailing garbage fail through compression.CompressionError with Format,
Offset, Message. Some shared failures name bits or huffman; no native
pointer or unchecked success escapes. gzip metadata decoding also declares
StringError for its Latin-1-to-UTF-8 conversion operations.
lzw.Compress(data, Order=lzw.BitOrder.LSB, LiteralWidth=8) and
lzw.Decompress(data, Order=..., LiteralWidth=..., MaxOutput=...) select the
packing convention. The decoder requires the terminal code and rejects trailing
bytes. Encoder input bytes must fit the specified literal width. Dictionary
resets, width transitions and the special repeated-prefix code are checked.
gzip.Compress additionally accepts Metadata=SOME(gzip.Header {...}).
Header fields are Name, Comment, Extra (byte list), Modified (unsigned seconds
in an INTEGER), OS (0–255). Name/comment use Latin-1 without NUL; extra <=65535
bytes. Default output is deterministic: no timestamp, name or comment, OS 255.
gzip.ReadMember(data, start=0, MaxOutput=..., MaxHeader=65536) returns
Member {Header, Bytes, EndOffset} for explicitly processing one member. Normal
Decompress concatenates all members. Optional extra/name/comment/header-CRC
fields are validated and header bytes are bounded separately from output.
For a valid header exceeding the default bound, use ReadMember with a larger
explicit MaxHeader; the normal multi-member convenience keeps its 64 KiB bound.
flate.Decode(data, start=0, MaxOutput=...) returns
compression.Decoded {Bytes, EndOffset} for implementing enclosing formats.
flate.Decompress requires the entire input to contain exactly one raw stream.
Offsets are byte positions at or just after the failing input operation, not
bit-precise locations.
Runnable buffer showcase exercises all four encoders with UTF-8 and arbitrary binary bytes, gzip metadata and both LZW orders. Bzip2 decoder interoperability is covered by the acceptance corpus.