Modules

Deflate

moduleextensionSource

Available on macOS, Linux, Windows, Wasm·since 0.28.0

#import "Extensions/Deflate";

DEFLATE compression (RFC 1951) with its zlib (RFC 1950) and gzip (RFC 1952) wrappers. deflate compresses, inflate decompresses, and crc32 and adler32 are the checksums.

Example↗
#import "Extensions/Deflate";

bytes := cast([] u8) "hello hello hello hello";
packed := deflate(bytes, .GZIP);
unpacked, ok, error := inflate(packed, .GZIP);
assert(ok && cast(string) unpacked == "hello hello hello hello");

Results are allocated with context.allocator and owned by the caller. Errors are static strings.

Procedures#

inflatesince 0.28.0Source
(data: [] u8, container := Deflate_Container.ZLIB, max_output: s64 = DEFAULT_MAX_OUTPUT) -> (output: [] u8, ok: bool, error: string)

Decompresses data into a new buffer. max_output bounds the result (a compressed bomb fails instead of exhausting memory). A GZIP stream is a single member; bytes after the stream are ignored. On failure the output is empty and error says why.

#import "Extensions/Deflate";

packed := deflate(cast([] u8) "abcabcabc", .ZLIB);
output, ok, error := inflate(packed, .ZLIB);
assert(ok);
assert(cast(string) output == "abcabcabc");

_, ok = inflate(cast([] u8) "not deflate data", .ZLIB);
assert(!ok);
↗
inflate_intosince 0.28.0Source
(data: [] u8, output: [] u8, container := Deflate_Container.ZLIB) -> (written: s64, ok: bool, error: string)

Like inflate, into a buffer the caller sized. Fails with "output is too small" when the stream expands past output; nothing is written beyond it.

#import "Extensions/Deflate";

packed := deflate(cast([] u8) "abcabcabc");
buffer: [16] u8;
written, ok := inflate_into(packed, buffer);
assert(ok && written == 9);
↗
deflatesince 0.28.0Source
(data: [] u8, container := Deflate_Container.ZLIB, level: s32 = 6) -> [] u8

Compresses data. level runs from 0 (stored blocks only) to 9 (smallest); 6 is the usual balance. Out-of-range levels are clamped.

#import "Extensions/Deflate";

text := cast([] u8) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
packed := deflate(text, .GZIP, 9);
assert(packed.count < text.count);
↗
crc32since 0.28.0Source
(data: [] u8, crc: u32 = 0) -> u32

CRC-32 (the checksum of gzip and PNG). To continue over more data, pass the previous result.

#import "Extensions/Deflate";

assert(crc32(cast([] u8) "123456789") == 0xCBF43926);
↗
adler32since 0.28.0Source
(data: [] u8, adler: u32 = 1) -> u32

Adler-32 (the checksum of zlib). To continue over more data, pass the previous result.

#import "Extensions/Deflate";

assert(adler32(cast([] u8) "123456789") == 0x091E01DE);
↗

Types#

Deflate_Containerenumsince 0.28.0Source
:: enum

The framing around the compressed blocks.

RAW
bare DEFLATE blocks
ZLIB
2-byte header, Adler-32 trailer (PNG's IDAT stream)
GZIP
gzip member: header, CRC-32 and size trailer

Constants#

:: 18

A gzip member is at least this long: 10 bytes of header and 8 of trailer.

MAX_RATIOsince 0.28.0Source
:: 1032

DEFLATE cannot expand a byte past 1032 bytes of output.

:: 1 << 30

inflate refuses to produce more than this many bytes unless told otherwise.