ddn.encoding.varint
ddn.encoding.varint — checked unsigned base-128 varints (LEB128).
Canonical little-endian base-128 encoding over caller-provided buffers: each byte carries 7 value bits, the high bit marks continuation. 32-bit values take 1–5 bytes (5th byte ≤ 0x0F), 64-bit values 1–10 (10th byte ≤ 0x01).
Contract highlights (design record doc/DDN-ENCODING.md):
- Encode checks capacity first and is non-committing:
on
INSUFFICIENT_CAPACITYthe output buffer is untouched. - Decode is strict-canonical: overlong encodings (trailing
zero final byte where a shorter form exists) and payloads beyond the width are rejected, not silently accepted.
- Errors are
VarintErrorvalues in addn.result.Result:bounded context (the byte count examined when the failure was detected), no allocation, no throwing —
@nogc nothrowthroughout.TRUNCATEDandINSUFFICIENT_CAPACITYare retryable;OVERLONGandOVERFLOWmean the data is wrong.
Signed integers: compose ZigZag with these functions (ddn.encoding.zigzag), the sint32/sint64 family — see the N009 notes in the design record.
Example:
import ddn.encoding.varint;
ubyte[10] buf;
auto r = varint.encodeUint64(300, buf[]);
assert(r.ok && r.value == 2 && buf[0 .. 2] == [0xAC, 0x02]);
auto d = varint.decodeUint64(buf[0 .. 2]);
assert(d.ok && d.value.value == 300 && d.value.length == 2);Types 3
Recoverable varint failure with bounded context.
examined is the number of input bytes the decoder had consumed (encode: always 0 — the buffer is untouched) when the failure was detected. No strings, no pointers: the struct is returnable in @nogc nothrow contexts everywhere.
Code codeWhich failure happened.size_t examinedBytes examined when the failure was detected.CodeFailure classification.A decoded 64-bit varint: value plus bytes consumed.
ulong valueThe decoded value.ubyte lengthBytes consumed from the input (1–10).A decoded 32-bit varint: value plus bytes consumed.
uint valueThe decoded value.ubyte lengthBytes consumed from the input (1–5).Functions 6
Result!(size_t, VarintError) encodeUint64(ulong v,
return scope ubyte[] dst) @safe pure nothrow @nogcEncodes `v` as a canonical varint into `dst` (non-committing).Result!(size_t, VarintError) encodeUint32(uint v,
return scope ubyte[] dst) @safe pure nothrow @nogcEncodes `v` as a canonical varint into `dst` (non-committing).Result!(Varint64, VarintError) decodeUint64(scope const(ubyte)[] src) @safe pure nothrow @nogcDecodes one canonical 64-bit varint from `src`.Result!(Varint32, VarintError) decodeUint32(scope const(ubyte)[] src) @safe pure nothrow @nogcDecodes one canonical 32-bit varint from `src`.