Inflate
Raw DEFLATE (RFC 1951) decompressor. This is a faithful pure-Kotlin port of Mark Adler's puff() as bundled in libtorrent (src/puff.cpp, "puff" v2.3). puff is the canonical, deliberately-simple reference implementation of inflate; it trades speed for being an unambiguous specification of the format. libtorrent ships it (instead of pulling in zlib) precisely so it can decode gzip'd HTTP tracker and scrape responses with no external dependency. That is also our situation in commonMain.
Differences from the C++, all behaviour-preserving:
puff writes into a caller-supplied fixed-size buffer and returns
1("output space exhausted") when it's too small; libtorrent'sinflate_gzipthen doubles the buffer and re-runs the whole thing from scratch. That resize dance is an allocation strategy, not part of DEFLATE, so we drop it and grow the output array on demand. The error code1therefore never occurs here, which is correct. The algorithm itself never fails for lack of output; only the bounded-buffer wrapper did.puff signals "ran past the end of input" via
setjmp/longjmpfrom deep insidebits()/decode(), which the top-levelpuff()catches and turns into return code2. We model that non-local exit with a private OutOfInput throwable caught at the top of inflate, mapping to the samedata did not terminateerror.puff's "scan only" mode (
dest == NULL) is omitted; we always materialise the output. libtorrent never uses scan mode for gzip.
Bit/byte ordering follows the format exactly: bits are consumed LSB-first within each input byte; Huffman codes are read MSB-first and accumulated in reversed order so canonical codes compare as plain integers (see decode).
This object is stateless and thread-safe; all mutable inflate state lives in the private State created per call.