ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
protobuf.h File Reference

The Protocol Buffers wire format (PROTOCORE_ENABLE_PROTOBUF): a streaming encoder and a cursor decoder over caller buffers, zero heap. More...

#include "protocore_config.h"

Go to the source code of this file.

Detailed Description

The Protocol Buffers wire format (PROTOCORE_ENABLE_PROTOBUF): a streaming encoder and a cursor decoder over caller buffers, zero heap.

The governing specification is Google's Protocol Buffers "Encoding" document (https://protobuf.dev/programming-guides/encoding/). It is not an IETF document and no RFC number applies to it. Every normative term below is that document's.

"Message Structure": a message is a sequence of records, and each record is "the field number, a wire type and a payload". The tag "is encoded as a varint formed from the field number and the wire type via the formula `(field_number << 3) | wire_type`".

"Base 128 Varints": "Each byte in the varint has a continuation bit that indicates if the byte that follows it is part of the varint. This is the most significant bit (MSB) of the byte." The lower seven bits are payload, appended in little-endian order, and an unsigned 64-bit value takes "anywhere between one and ten bytes".

The wire types, from the same document's table:

ID  Name    Used For
0   VARINT  int32, int64, uint32, uint64, sint32, sint64, bool, enum
1   I64     fixed64, sfixed64, double
2   LEN     string, bytes, embedded messages, packed repeated fields
3   SGROUP  group start (deprecated)
4   EGROUP  group end (deprecated)
5   I32     fixed32, sfixed32, float

"Length-Delimited Records": "The LEN wire type has a dynamic length, specified by a varint immediately after the tag, which is followed by the payload as usual."

"Groups": "Groups are a deprecated feature that should not be used." SGROUP and EGROUP records are rejected by the decoder here, as are the two IDs the table does not name.

sint32 and sint64 carry ZigZag: (n << 1) ^ (n >> 31) and (n << 1) ^ (n >> 63).

An encoder row appends one record at a time into a caller buffer and fails closed on overflow; an embedded message is encoded into a second row's buffer and added with ProtobufNs::write_bytes. A decoder row is a cursor: it decodes the record at its own offset and reports where that offset landed. Rows nest, which is what an embedded message needs, so ProtobufNs::slot names one.

The module exports one symbol, Protobuf. Everything in protobuf.c has internal linkage.

Author
Douglas Quigg (dstroy0)
Date
2026

Definition in file protobuf.h.