FakeRiak.Protobuf (fake_riak v0.3.0)

Copy Markdown View Source

Minimal protobuf (proto2) wire-format codec, just enough for the Riak PBC messages FakeRiak.RiakPBC speaks.

Only the wire types Riak's KV messages use are decoded: varint (0) and length-delimited (2). Unknown fixed64 (1) and fixed32 (5) fields are skipped; the long-deprecated group types (3/4) are treated as malformed. Field types are not schema-checked — a decoded message is just a map of field number to the values seen, in order, and the caller picks out the fields it knows.

Signed sint64 fields (used by Riak's counters and CRDT counters) ride on the varint wire type but are zigzag-encoded. Decoding stays generic: last/3 hands back the raw unsigned varint and the caller applies zigzag_decode/1. Encoding has a dedicated {:zigzag, n} field form (see encode/1).

Summary

Types

A decoded field value: a varint as an integer, or raw bytes.

Field number => values in order of appearance.

Functions

Decode a message payload into its fields.

Encode fields, in the given order, into a message payload. Integers and booleans go as {:varint, n}; signed sint64 values as {:zigzag, n} (zigzag-encoded onto the varint wire type); bytes, strings and embedded messages as {:bytes, iodata}.

The value of a field, with proto2 scalar semantics: when a scalar field appears more than once, the last occurrence wins.

Map the raw unsigned varint a sint64 field decodes to back to its signed integer value (zigzag: small magnitudes, positive or negative, stay small).

Zigzag-encode a signed 64-bit integer into the non-negative varint a sint64 field is written as. Inverse of zigzag_decode/1.

Types

field_value()

@type field_value() :: non_neg_integer() | binary()

A decoded field value: a varint as an integer, or raw bytes.

fields()

@type fields() :: %{optional(pos_integer()) => [field_value()]}

Field number => values in order of appearance.

Functions

decode(payload)

@spec decode(binary()) :: {:ok, fields()} | :error

Decode a message payload into its fields.

Returns :error on malformed input: a truncated field, an over-long varint, a group wire type, or field number 0.

encode(fields)

@spec encode([
  {pos_integer(),
   {:varint, non_neg_integer()} | {:zigzag, integer()} | {:bytes, iodata()}}
]) :: iodata()

Encode fields, in the given order, into a message payload. Integers and booleans go as {:varint, n}; signed sint64 values as {:zigzag, n} (zigzag-encoded onto the varint wire type); bytes, strings and embedded messages as {:bytes, iodata}.

last(fields, field, default \\ nil)

@spec last(fields(), pos_integer(), field_value() | nil) :: field_value() | nil

The value of a field, with proto2 scalar semantics: when a scalar field appears more than once, the last occurrence wins.

zigzag_decode(n)

@spec zigzag_decode(non_neg_integer()) :: integer()

Map the raw unsigned varint a sint64 field decodes to back to its signed integer value (zigzag: small magnitudes, positive or negative, stay small).

zigzag_encode(n)

@spec zigzag_encode(integer()) :: non_neg_integer()

Zigzag-encode a signed 64-bit integer into the non-negative varint a sint64 field is written as. Inverse of zigzag_decode/1.