-- SPDX-FileCopyrightText: © 2022—2026 Vladimir Zorin -- SPDX-License-Identifier: LicenseRef-OWL-1.0-or-later -- Licensed under OWL v1.0+. See LICENSE. --[==[ Zlib compression and decompression built on miniz. Provides raw deflate/inflate, zlib-wrapped compress/decompress, gzip/gunzip, and CRC-32/Adler-32 checksum functions. ]==] local core = require("zlib.core") ---! Compress data using raw deflate (no header/trailer) ---@ deflate(`data`{.str}, `level`{.num .opt}) -> `compressed`{.str .or_nil}, `err`{.str .err} --[===[ Level ranges from 0 (no compression) to 10 (maximum), default 6. ]===] local deflate = function(data, level) if type(data) ~= "string" then return nil, "data must be a string" end return core.deflate(data, level) end ---! Compress data with zlib wrapping (header + adler32 footer) ---@ compress(`data`{.str}, `level`{.num .opt}) -> `compressed`{.str .or_nil}, `err`{.str .err} --[===[ Level ranges from 0 (no compression) to 10 (maximum), default 6. ]===] local compress = function(data, level) if type(data) ~= "string" then return nil, "data must be a string" end return core.compress(data, level) end ---! Compress data in gzip format (RFC 1952) ---@ gzip(`data`{.str}, `level`{.num .opt}) -> `compressed`{.str .or_nil}, `err`{.str .err} --[===[ Level ranges from 0 (no compression) to 10 (maximum), default 6. Output is compatible with the `gzip` command-line tool. ]===] local gzip = function(data, level) if type(data) ~= "string" then return nil, "data must be a string" end return core.gzip(data, level) end ---! Decompress raw deflate data ---@ inflate(`data`{.str}, `max_size`{.num .opt}) -> `decompressed`{.str .or_nil}, `bytes_consumed`{.num}, `err`{.str .err} --[===[ Returns the decompressed data and the number of compressed bytes consumed from the input. `max_size` caps the output buffer to guard against decompression bombs (default 64 MB). ]===] local inflate = function(data, max_size) if type(data) ~= "string" then return nil, "data must be a string" end return core.inflate(data, max_size) end ---! Decompress zlib-wrapped data ---@ decompress(`data`{.str}, `max_size`{.num .opt}) -> `decompressed`{.str .or_nil}, `bytes_consumed`{.num}, `err`{.str .err} --[===[ Input must include the zlib header and adler32 footer. Returns the decompressed data and the number of bytes consumed from the input. `max_size` caps the output buffer (default 64 MB). ]===] local decompress = function(data, max_size) if type(data) ~= "string" then return nil, "data must be a string" end return core.decompress(data, max_size) end ---! Decompress gzip data (RFC 1952) ---@ gunzip(`data`{.str}, `max_size`{.num .opt}) -> `decompressed`{.str .or_nil}, `bytes_consumed`{.num}, `err`{.str .err} --[===[ Parses the gzip header, inflates the payload, and validates the CRC32 trailer. Compatible with output from the `gzip` command. Returns the decompressed data and total bytes consumed. `max_size` caps the output buffer (default 64 MB). ]===] local gunzip = function(data, max_size) if type(data) ~= "string" then return nil, "data must be a string" end return core.gunzip(data, max_size) end ---! Compute CRC-32 checksum ---@ crc32(`data`{.str}, `initial`{.num .opt}) -> `checksum`{.num} --[===[ Returns the CRC-32 value as a number. Pass a previous result as `initial` to compute a running checksum over multiple chunks. ]===] local crc32 = function(data, initial) if type(data) ~= "string" then return nil, "data must be a string" end return core.crc32(data, initial) end ---! Compute Adler-32 checksum ---@ adler32(`data`{.str}, `initial`{.num .opt}) -> `checksum`{.num} --[===[ Returns the Adler-32 value as a number. Pass a previous result as `initial` to compute a running checksum over multiple chunks. ]===] local adler32 = function(data, initial) if type(data) ~= "string" then return nil, "data must be a string" end return core.adler32(data, initial) end return { deflate = deflate, compress = compress, gzip = gzip, inflate = inflate, decompress = decompress, gunzip = gunzip, crc32 = crc32, adler32 = adler32, }