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