Module: encoding.varint
Source: ./encoding/varint.reef
Overview
encoding/varint - Variable-length integer encoding
Implements Protocol Buffer style variable-length integer encoding (LEB128). Small values use fewer bytes, making this efficient for data that is typically small but occasionally large.
Encoding scheme (unsigned):
- Each byte uses 7 bits for data, 1 bit as continuation flag
- MSB = 1 means more bytes follow, MSB = 0 means last byte
- Values 0-127 use 1 byte, 128-16383 use 2 bytes, etc.
Signed integers use ZigZag encoding: 0 -> 0, -1 -> 1, 1 -> 2, -2 -> 3, 2 -> 4, ...
Usage: import encoding.varint let buf: [int] = varint_alloc_buffer() let len: int = varint_encode(300, buf) // Returns bytes written let val: int = varint_decode(buf, 0) // Decode from offset 0
Types
Varint
Decode unsigned varint from buffer at offset, returns value One decoded varint: the value, and how many bytes it consumed. Returning both is what callers actually need -- the old API made you decode twice (varint_decode then varint_decode_size) or pass an out-param.
Fields:
| Name | Type |
|---|---|
value |
int |
size |
int |
Functions
fn varint_alloc_buffer(): [int]
fn zigzag_encode(n: int): int
ZigZag encode: maps signed integers to unsigned 0 -> 0, -1 -> 1, 1 -> 2, -2 -> 3, 2 -> 4, ...
fn zigzag_decode(n: int): int
ZigZag decode: maps unsigned back to signed
fn varint_size(value: int): int
Calculate bytes needed to encode an unsigned value
fn varint_size_signed(value: int): int
Calculate bytes needed for signed value (using ZigZag)
fn varint_encode(value: int, buf: [int]): int
Encode unsigned varint to buffer, returns number of bytes written
fn varint_decode_at(buf: [int], offset: int): result.Result[Varint, error.Error]
Decode the varint starting at offset.
Bounds are checked EXPLICITLY rather than left to the array bounds check. The old decoders read buf[pos] with no test, so a varint whose continuation bit was set on the final byte of the buffer ran off the end and Reef's bounds check ABORTED THE PROCESS:
Runtime error: array index 3 out of bounds (length 3)
For a decoder handed untrusted bytes that is the wrong failure: truncation is an ordinary, expected input condition, not a program error.
The 10-byte cap is also an error now instead of a silent break. Breaking
returned a value assembled from a prefix of a malformed varint -- a wrong
answer indistinguishable from a right one.
fn varint_decode(buf: [int], offset: int): result.Result[int, error.Error]
fn varint_decode_size(buf: [int], offset: int): result.Result[int, error.Error]
fn varint_encode_signed(value: int, buf: [int]): int
Encode signed integer using ZigZag encoding
fn varint_decode_signed(buf: [int], offset: int): result.Result[int, error.Error]
Decode signed integer using ZigZag encoding
fn varint_encode_bytes(value: int, buf: [int], offset: int): int
Encode to buffer at offset, returns bytes written
Generated by reefc doc