thrift_runtime_binary (thrift_runtime v0.7.0)
View SourceThrift binary protocol: value and message codecs as pure functions.
Encoding takes a type descriptor — the same shape the generated
struct_info/1, enum_info/1 and function_info/2 introspection
functions return — and produces iodata. Decoding consumes a binary and
returns the remaining bytes, so callers can stream.
Structs travel as maps keyed by binary field names. On decode, unknown field ids are skipped by wire type, so newer writers stay readable.
Decoding distinguishes more (the binary is a truncated but otherwise
valid encoding — read more bytes and retry) from {error, _} (the bytes
cannot be a valid encoding). That is what lets the buffered transport
parse incrementally off a socket.
Before encoding or decoding, a descriptor is compiled: wire type bytes
are precomputed, struct fields are indexed by id in a map, and the
required fields are separated out. {ref, Module, Name} schemas are
compiled once and cached in persistent_term under their names, so
resolving a nested struct is a constant-time lookup. Inline
{Kind, Fields} descriptors (such as the function_info/2 params
structs) are memoized per process under exact equality — generated
descriptors are literals, so the memo hit is a pointer comparison.
Generated types modules ship specialized wire codecs (the
encode_<name>_wire/1 / decode_<name>_wire/1 pair plus the
binary_codec/1 lookup, emitted by the generator): ref descriptors of
named structs dispatch there, so the hot path runs direct binary
patterns instead of this engine's compiled-scheme interpreter. The
interpreter stays for inline descriptors (RPC param/result structs),
hand-written descriptors, and as the fallback when the probe finds no
binary_codec/1. Compact and JSON are unaffected — they never consult
the probe.
The caches assume generated types modules are never hot-swapped between incompatible versions.
Summary
Functions
Decodes a value of Type from the front of Binary.
Decodes TApplicationException from an EXCEPTION message payload.
Decodes a message envelope.
Encodes Value as Type, or fails with a tagged error.
Encodes TApplicationException as an EXCEPTION message payload.
Encodes a message envelope around Payload (already encoded as a
struct).
Skips a value of a raw wire type, used for struct fields with ids the descriptor does not know — and by the generated specialized codecs for the same purpose.
Returns the field descriptors of a struct type descriptor
({struct, {Kind, Fields}}), resolving {struct, {ref, M, N}}
through M:struct_info/1.
Types
-type application_exception() :: thrift_runtime_protocol:application_exception().
-type base_type() :: thrift_runtime_protocol:base_type().
-type decode_result(Value) :: thrift_runtime_protocol:decode_result(Value).
-type enum_desc() :: thrift_runtime_protocol:enum_desc().
-type field_desc() :: thrift_runtime_protocol:field_desc().
-type message_type() :: thrift_runtime_protocol:message_type().
-type struct_desc() :: thrift_runtime_protocol:struct_desc().
-type struct_value() :: thrift_runtime_protocol:struct_value().
-type type_desc() :: thrift_runtime_protocol:type_desc().
Functions
-spec decode(type_desc(), binary()) -> decode_result(term()).
Decodes a value of Type from the front of Binary.
Returns {ok, Value, Rest}, more when Binary is a truncated valid
encoding, or a tagged error.
-spec decode_application_exception(binary()) -> decode_result(application_exception()).
Decodes TApplicationException from an EXCEPTION message payload.
Unknown fields are skipped per the usual struct rules.
-spec decode_message(binary()) -> {ok, message_type(), binary(), non_neg_integer(), binary()} | more | {error, term()}.
Decodes a message envelope.
Returns {ok, Type, Name, SeqId, Tail} where Tail is every byte
after the seqid (the struct payload plus anything that follows it),
more, or a tagged error. The payload length is not part of the
envelope, so the struct payload must be decoded from Tail and any
trailing bytes ignored.
Encodes Value as Type, or fails with a tagged error.
-spec encode_application_exception(binary(), non_neg_integer()) -> {ok, iodata()} | {error, term()}.
Encodes TApplicationException as an EXCEPTION message payload.
Codes follow the Thrift specification: 0 unknown, 1 unknown method, 2 invalid message type, 3 wrong method name, 4 bad sequence id, 5 missing result, 6 internal error, 7 protocol error.
-spec encode_message(message_type(), binary(), non_neg_integer(), iodata()) -> iodata().
Encodes a message envelope around Payload (already encoded as a
struct).
Always writes the strict format (version 1); decode_message/1 also
reads the legacy headerless format.
-spec skip_by_wire(non_neg_integer(), binary()) -> {ok, binary()} | more | {error, term()}.
Skips a value of a raw wire type, used for struct fields with ids the descriptor does not know — and by the generated specialized codecs for the same purpose.
-spec struct_fields(type_desc()) -> [field_desc()].
Returns the field descriptors of a struct type descriptor
({struct, {Kind, Fields}}), resolving {struct, {ref, M, N}}
through M:struct_info/1.