Crdt.Model_codec_cbor
crdt · API reference
CBOR (RFC 7049) encoding/decoding primitives
CBOR and binary encoding/decoding primitives.
This module provides low-level encoding and decoding functions for:
- CBOR (RFC 7049) value encoding/decoding
- Variable-length integers (vu57, b1vu56)
- Compact ID encoding for CRDT timestamps The implementation is optimized for performance with:
- Inline annotations on hot paths
- Unsafe byte operations where safe
- Pre-allocated buffers with growth strategy
- Batched capacity checks
Encoder
type encoder = {
mutable buf : bytes;
mutable pos : int;
mutable cap : int;
}Mutable encoder with auto-growing buffer
val create_encoder : ?capacity:int -> unit -> encoderCreate a new encoder with optional initial capacity (default 4096)
val reset_encoder : encoder -> unitReset encoder position to reuse buffer
val grow : encoder -> int -> unitGrow the encoder buffer to accommodate at least min_additional more bytes
val ensure_capacity : encoder -> int -> unitEnsure capacity for n more bytes
val encoder_contents : encoder -> bytesGet the encoded contents as bytes
val encoder_contents_string : encoder -> stringGet the encoded contents as string
Primitive Writers
val write_u8 : encoder -> int -> unitWrite a single byte
val write_u32 : encoder -> int -> unitWrite a 32-bit unsigned integer in big-endian
val set_u32 : encoder -> int -> int -> unitSet a 32-bit value at a specific offset (for backpatching)
val write_bytes : encoder -> bytes -> unitWrite raw bytes
val write_string : encoder -> string -> unitWrite a string as raw bytes
Variable-Length Integer Encoding
val write_vu57 : encoder -> int -> unitEncode variable-length unsigned integer up to 57 bits (8 bytes max).
Format: each byte uses 7 bits for value, high bit indicates continuation.
byte 1 byte 2 ... byte 8
?zzzzzzz ?zzzzzzz zzzzzzzzwhere ? = 1 means more bytes follow, ? = 0 means last byte
val write_b1vu56 : encoder -> bool -> int -> unitEncode 1-bit flag + up to 56-bit value.
Format: first byte uses 6 bits for value, then continuation like vu57.
byte 1 byte 2 ...
f?zzzzzz ?zzzzzzzwhere f = flag bit, ? = continuation bit
val write_id : encoder -> int -> int -> unitWrite CRDT ID in compact form.
If session_index <= 7 and time_diff <= 15: single byte (0xxxyyyy) Otherwise: b1vu56(1, session_index) + vu57(time_diff)
CBOR Encoding
val write_cbor_uint : encoder -> int -> unitWrite CBOR unsigned integer (major type 0)
val write_cbor_negint : encoder -> int -> unitWrite CBOR negative integer (major type 1)
val write_cbor_int : encoder -> int -> unitWrite CBOR integer (chooses unsigned or negative encoding)
val write_cbor_string : encoder -> string -> unitWrite CBOR text string (major type 3)
val write_cbor_bytes : encoder -> bytes -> unitWrite CBOR byte string (major type 2)
val write_cbor_float : encoder -> float -> unitWrite CBOR float64 (major type 7, additional 27)
val write_cbor_null : encoder -> unitWrite CBOR null
val write_cbor_undefined : encoder -> unitWrite CBOR undefined
val write_cbor_bool : encoder -> bool -> unitWrite CBOR boolean
val write_cbor_array_header : encoder -> int -> unitWrite CBOR array header (major type 4)
val write_cbor_map_header : encoder -> int -> unitWrite CBOR map header (major type 5)
val write_cbor_value : encoder -> Value.t -> unitWrite a complete Value.t as CBOR via Cbor_simd
Decoder
type decoder = {
data : bytes;
mutable pos : int;
len : int;
}Mutable decoder state
val create_decoder : bytes -> decoderCreate a decoder from bytes
val create_decoder_string : string -> decoderCreate a decoder from string
val decoder_remaining : decoder -> intGet remaining bytes in decoder
val decoder_has_more : decoder -> boolCheck if decoder has more data
val decoder_pos : decoder -> intGet current decoder position
val set_decoder_pos : decoder -> int -> unitSet decoder position (for seeking)
Primitive Readers
val read_u8 : decoder -> intRead a single byte
val peek_u8 : decoder -> intPeek at next byte without consuming
val read_u32 : decoder -> intRead 32-bit unsigned integer in big-endian
val read_bytes : decoder -> int -> bytesRead n bytes
val read_string : decoder -> int -> stringRead n bytes as string
Variable-Length Integer Decoding
val read_vu57 : decoder -> intRead variable-length unsigned integer (up to 57 bits)
val read_b1vu56 : decoder -> bool * intRead 1-bit flag + variable-length unsigned integer (up to 56 bits)
val read_id : decoder -> int * intRead CRDT ID in compact form. Returns (session_index, time_diff)
CBOR Decoding
val read_cbor_length : decoder -> int -> intRead CBOR length/value based on additional info byte
val read_cbor_float : decoder -> floatRead CBOR float64
val read_cbor_value : decoder -> Value.tRead a complete CBOR value as Value.t via Cbor_simd.
Note: We need to read the CBOR value starting at the current decoder position, then advance the decoder past the consumed bytes. Since Cbor_simd's decoder tracks its own position, we create a sub-decoder and sync positions after.
val read_cbor_string_only : decoder -> stringRead a CBOR string (expects major type 3)
Convenience Functions
val encode_cbor : Value.t -> bytesEncode a Value.t to CBOR bytes
val encode_cbor_string : Value.t -> stringEncode a Value.t to CBOR string
val decode_cbor : bytes -> Value.tDecode CBOR bytes to Value.t
val decode_cbor_string : string -> Value.tDecode CBOR string to Value.t