std/compress

Deflate (RFC 1951), zlib (RFC 1950), and gzip (RFC 1952), in one call and as streams that take and give a part at a time. The work is the system's zlib, which a program that imports std/compress links with (-lz).

import "std/compress"

bytes packed = gzip(read_bytes("log.txt"))
bytes back = gunzip(packed, 100_000_000)?

Compressor c = compressor("gzip")?
for part in parts do
    file_write(out, c.push(part))?
end
file_write(out, c.finish())?
Function Result
compress(format, data, level) data in one of COMPRESSION_FORMATS: "deflate" (raw, as ZIP and HTTP hold it), "zlib", or "gzip"; level 0 (none) to 9 (smallest), -1 for zlib's 6
decompress(format, data, limit) what data decompresses to; "auto" takes zlib or gzip, whichever it is
gzip(data, level), gunzip(data, limit) gzip; every member of data that has several, as cat a.gz b.gz makes, as gzip -d reads it
zlib_compress, zlib_decompress, deflate, inflate the same for zlib and raw deflate
compressor(format, level) a Compressor: push(data) gives what is ready, finish() the rest
decompressor(format, limit) a Decompressor: push(data) and finish() give Results, finish failing for data cut short
gzip_file(path, target, level), gunzip_file(path, target, limit) a file compressed into another a part at a time, and back

Data that is not of its format, is cut short, has other data after its end, or would decompress to more than limit bytes is an ERROR of kind "invalid_data". A limit of 0 takes any size; a program that decompresses what others send should give one, since a few kilobytes can decompress to gigabytes. Call finish once on every stream: it frees zlib's state.