ddn.encoding.bitpack
ddn.encoding.bitpack — plain LSB-first bit-packing.
Packs count unsigned values of width bits each into the smallest byte count (ceil(count·width/8)), LSB-first: value i occupies stream bits [i·W, (i+1)·W), stream bit b living in byte b/8 at bit b%8 — the Parquet BIT-PACKED convention (design record doc/DDN-ENCODING.md D10–D16). Signed values compose via ZigZag first; ORC's MSB-first byte-aligned dialect is a different layout.
Contract highlights:
- Whole-operation semantics: exactly
countvalues or failurewith the output buffer untouched — pack pre-validates every value against
2^width(never silently masked) and pre-checks capacity; unpack pre-checks the exact byte need. - Strict canonical padding: unpack rejects nonzero tail bits of
the final byte.
BitpackErrorin addn.result.Result: bounded context, noallocation, no throwing;
@nogc nothrow @safe pureand CTFE throughout.
Example:
import ddn.encoding.bitpack;
ubyte[2] buf;
auto r = bitpack.packUint32([1, 2, 3, 4], 3, buf[]);
assert(r.ok && r.value == 2 && buf[0] == 0xD1 && buf[1] == 0x08);
uint[4] out_;
auto d = bitpack.unpackUint32(buf[0 .. 2], 4, 3, out_);
assert(d.ok && d.value == 2 && out_[0] == 1 && out_[3] == 4);Types 1
Recoverable bit-packing failure with bounded context.
context is the value index for INVALID_VALUE and the byte count examined otherwise (encode: always 0 — the buffer is untouched).
Code codeWhich failure happened.size_t contextValue index (`INVALID_VALUE`) or bytes examined.CodeFailure classification.Functions 7
size_t packedSize(size_t count, ubyte width) @safe pure nothrow @nogcBytes `pack*` needs for `count` values at `width` bits (`ceil(count·width/8)`; zero for `count == 0`).Result!(size_t, BitpackError) packUint32(scope const(uint)[] values,
ubyte width, return scope ubyte[] dst) @safe pure nothrow @nogcPacks unsigned 32-bit values at `width` bits each (LSB-first).Result!(size_t, BitpackError) packUint64(scope const(ulong)[] values,
ubyte width, return scope ubyte[] dst) @safe pure nothrow @nogcPacks unsigned 64-bit values at `width` bits each (LSB-first).Result!(size_t, BitpackError) unpackUint32(scope const(ubyte)[] src,
size_t count, ubyte width, return scope uint[] dst) @safe pure nothrow @nogcUnpacks `count` 32-bit values packed at `width` bits (LSB-first).Result!(size_t, BitpackError) unpackUint64(scope const(ubyte)[] src,
size_t count, ubyte width, return scope ulong[] dst) @safe pure nothrow @nogcUnpacks `count` 64-bit values packed at `width` bits (LSB-first).size_t _pack(V)(scope const(V)[] values, ubyte width,
scope ubyte[] dst) @safe pure nothrow @nogcsize_t _unpack(V)(scope const(ubyte)[] run, size_t count,
ubyte width, scope V[] dst, out ulong tailBits) @safe pure nothrow @nogc