Skip to content
FutureBlitz

    Install

    Import std.data.protobuf

    std.data.protobuf

    Protocol Buffers' wire format and text format, for the types made from .proto files.

    Protocol Buffers' wire format, which the types fb makes from a .proto file read and write: ProtoWriter and ProtoReader, with varints, zigzag, fixed32 and fixed64 values, and length-delimited fields, ProtoText for a message's ToString, in protobuf's text format, and ProtoBox, which holds a message a message of its own type has. A program uses them through its .proto's types; code that reads or writes the wire format itself can use them too.

    A reader keeps protobuf's own limits: a message nests at most 100 deep, and a length is at most what an array holds, 2147483647 bytes. What doesn't read is a ParseError at its byte: of UNEXPECTED_END when the bytes stop inside a field, SYNTAX when they aren't the wire format, and OUT_OF_RANGE past a limit.

    Examples

    Expect(ProtoTag(1, WIRE_VARINT) == 8 && ProtoTag(2, WIRE_LENGTH) == 18)
    Expect(ProtoIsZero(0.0 As Float64) && !ProtoIsZero(-0.0 As Float64))
    Local box = ProtoBox<Int>(7)
    Expect(box.Value == 7 && box == ProtoBox<Int>(7))

    std/data/protobuf.fb

    Types

    ProtoWriter class

    Public Class ProtoWriter

    Writes protobuf's wire format: each field's tag, then its value. A message inside another goes between BeginLength and EndLength, which put its length before it.

    Examples

    Local writer = ProtoWriter()
    writer.WriteTag(ProtoTag(1, WIRE_VARINT))
    writer.WriteInt32(150)
    writer.WriteTag(ProtoTag(2, WIRE_LENGTH))
    writer.WriteString("hi")
    Local bytes = writer.Finish()
    Expect(bytes == [0x08, 0x96, 0x01, 0x12, 0x02, 0x68, 0x69] As UInt8[])

    std/data/protobuf.fb, line 101

    • Public New() constructor #

      A new ProtoWriter, with nothing written.

    • Public Property Count: Int property #

      How many bytes it has written.

    • Public Method WriteTag(tag: UInt32) method #

      Writes a field's tag, its number and its wire type, as a varint.

    • Public Method WriteVarint(value: UInt64) method #

      An unsigned varint: 7 bits a byte, the lowest first, with the top bit set on every byte but the last.

    • Public Method WriteInt32(value: Int32) method #

      An int32 as protobuf writes one: a negative value as an Int64's 64 bits, in 10 bytes.

    • Public Method WriteInt64(value: Int64) method #

      Writes an int64, as a varint.

    • Public Method WriteUInt32(value: UInt32) method #

      Writes a uint32, as a varint.

    • Public Method WriteUInt64(value: UInt64) method #

      Writes a uint64, as a varint.

    • Public Method WriteSInt32(value: Int32) method #

      A sint32, zigzagged, so a small negative number takes as few bytes as a small positive one: 0, -1, 1, -2 are 0, 1, 2, 3.

    • Public Method WriteSInt64(value: Int64) method #

      Writes a sint64, zigzagged, so a small negative number takes as few bytes as a small positive one.

    • Public Method WriteBool(value: Bool) method #

      Writes a bool, as a varint of 1 or 0.

    • Public Method WriteFixed32(value: UInt32) method #

      4 bytes, the lowest first.

    • Public Method WriteFixed64(value: UInt64) method #

      8 bytes, the lowest first.

    • Public Method WriteSFixed32(value: Int32) method #

      Writes an sfixed32, as its 4 bytes, the lowest first.

    • Public Method WriteSFixed64(value: Int64) method #

      Writes an sfixed64, as its 8 bytes, the lowest first.

    • Public Method WriteFloat(value: Float32) method #

      A float's IEEE 754 bits, in 4 bytes.

    • Public Method WriteDouble(value: Float64) method #

      A double's IEEE 754 bits, in 8 bytes.

    • Public Method WriteBytes(value: UInt8[]) method #

      Its length, then its bytes.

    • Public Method WriteString(value: String) method #

      Its UTF-8's length, then its UTF-8.

    • Public Method WriteRaw(value: UInt8[]) method #

      Bytes as they are, like the fields a message didn't know, which it keeps.

    • Public Method BeginLength(): Int method #

      Starts what a length goes before, like a message inside another or a packed field's values, and gives where, for EndLength.

    • @PanicsAtCaller Public Method EndLength(start: Int) method #

      Puts the length of what was written since BeginLength gave start before it. Panics when start isn't where a BeginLength left room for a length.

    • Public Method Finish(): UInt8[] method #

      What it has written, after which it starts again, empty.

    ProtoReader class

    Public Class ProtoReader

    Reads protobuf's wire format from bytes, a field at a time: ReadTag, then the value its field has. A message inside another is read between BeginMessage and EndMessage, and a packed field's values between BeginPacked and EndPacked, which keep the reader inside them.

    Examples

    Local reader = ProtoReader([0x08, 0x96, 0x01, 0x12, 0x02, 0x68, 0x69] As UInt8[])
    Expect((Try reader.ReadTag()) == ProtoTag(1, WIRE_VARINT))
    Expect((Try reader.ReadInt32()) == 150)
    Expect((Try reader.ReadTag()) == ProtoTag(2, WIRE_LENGTH))
    Expect((Try reader.ReadString()) == "hi")
    Expect(reader.AtEnd)

    std/data/protobuf.fb, line 272

    • Public New(bytes: UInt8[]) constructor #

      A ProtoReader of bytes, the wire format of a message.

    • Public Property AtEnd: Bool property #

      Whether what's being read has no more bytes: the bytes, or the message or packed field it's inside.

    • Public Property Position: Int property #

      Where it's reading, from the first byte, 0.

    • Public Property TagStart: Int property #

      Where the last tag read starts, for KeepFrom.

    • Public Method More(ending: UInt32): Bool Throws ParseError method #

      Whether there's another field to read before the end of what's being read, or in a group, whose end tag ending is, before that tag, which has to come first. ending is 0 outside a group.

    • Public Method ReadTag(): UInt32 Throws ParseError method #

      A field's tag: its number and wire type, in up to 5 bytes, as protobuf's readers take one. Throws a ParseError for field 0, a number past PROTO_FIELD_LIMIT, or wire type 6 or 7, which aren't protobuf's.

    • Public Method ReadVarint(): UInt64 Throws ParseError method #

      An unsigned varint, of up to 10 bytes. Bits past 64 are dropped, as protobuf's readers drop them.

    • Public Method ReadInt32(): Int32 Throws ParseError method #

      An int32, from a varint's low 32 bits.

    • Public Method ReadInt64(): Int64 Throws ParseError method #

      An int64, from a varint.

    • Public Method ReadUInt32(): UInt32 Throws ParseError method #

      A uint32, from a varint's low 32 bits.

    • Public Method ReadUInt64(): UInt64 Throws ParseError method #

      A uint64, from a varint.

    • Public Method ReadSInt32(): Int32 Throws ParseError method #

      A zigzagged sint32, from a varint's low 32 bits.

    • Public Method ReadSInt64(): Int64 Throws ParseError method #

      A zigzagged sint64, from a varint.

    • Public Method ReadBool(): Bool Throws ParseError method #

      A bool: any varint but 0 is True.

    • Public Method ReadFixed32(): UInt32 Throws ParseError method #

      A fixed32's 4 bytes, the lowest first.

    • Public Method ReadFixed64(): UInt64 Throws ParseError method #

      A fixed64's 8 bytes, the lowest first.

    • Public Method ReadSFixed32(): Int32 Throws ParseError method #

      An sfixed32's 4 bytes, the lowest first.

    • Public Method ReadSFixed64(): Int64 Throws ParseError method #

      An sfixed64's 8 bytes, the lowest first.

    • Public Method ReadFloat(): Float32 Throws ParseError method #

      A float's 4 bytes, the lowest first.

    • Public Method ReadDouble(): Float64 Throws ParseError method #

      A double's 8 bytes, the lowest first.

    • Public Method ReadLength(): Int Throws ParseError method #

      A length-delimited field's length, in up to 5 bytes, which its bytes have to fit in.

    • Public Method ReadBytes(): UInt8[] Throws ParseError method #

      A length and the bytes after it, in a new array.

    • Public Method ReadString(): String Throws ParseError method #

      A length and the UTF-8 after it. Throws a ParseError when it isn't UTF-8, which every String is.

    • Public Method BeginMessage(): Int Throws ParseError method #

      Starts reading a message inside another, after its tag, and gives where the one around it ends, for EndMessage. Throws a ParseError when it's nested more than PROTO_DEPTH_LIMIT deep, or doesn't fit.

    • Public Method EndMessage(outer: Int) method #

      Goes on with the message around one BeginMessage started, which gave outer.

    • Public Method BeginGroup() Throws ParseError method #

      Starts reading a group, after its start tag, which it ends at its own end tag. Throws a ParseError when it's nested more than PROTO_DEPTH_LIMIT deep.

    • Public Method EndGroup() method #

      Goes on with the message around a group BeginGroup started.

    • Public Method BeginPacked(size: Int): Int Throws ParseError method #

      Starts reading a packed field's values, after its tag, and gives where what's around it ends, for EndPacked. size is each value's, 4 or 8, or 0 for varints, whose bytes vary.

    • Public Method EndPacked(outer: Int) method #

      Goes on with the message around a packed field BeginPacked started, which gave outer.

    • Public Method Skip(tag: UInt32, unknown: UInt8[]) Throws ParseError method #

      Reads past the value of a field the message doesn't know, whose tag was just read, and keeps the field, its tag too, in unknown, as it was written. A group's fields go along with it. Throws a ParseError for an end tag without its group.

    • Public Method Keep(unknown: UInt8[]) method #

      Keeps the field just read, its tag too, in unknown, as it was written: one whose value the message has no place for, like a number that isn't one of a closed enum's values.

    • @PanicsAtCaller Public Method KeepFrom(start: Int, unknown: UInt8[]) method #

      Keeps the bytes from start, where TagStart said a field's tag was, up to where it's reading, in unknown: a map's entry whose value is a closed enum's number it doesn't name. Panics when start is past where it's reading, or before the bytes.

    ProtoText class

    Public Class ProtoText

    Writes a message as protobuf's text format, on one line, as a message's ToString gives it: name: "Ada" id: 7 phone { number: "555" }. Each field goes in with its name, a message's between BeginMessage and EndMessage.

    Examples

    Local text = ProtoText()
    text.WriteString("name", "Ada")
    text.Write("id", "7")
    text.BeginMessage("phone")
    text.WriteString("number", "555")
    text.EndMessage()
    Expect(text.Finish() == "name: \"Ada\" id: 7 phone {{ number: \"555\" }}")

    std/data/protobuf.fb, line 630

    • Public New() constructor #

      A new ProtoText, with nothing written.

    • Public Method Write(name: String, value: String) method #

      name: value, for a value that's text already, like a number or an enum's name.

    • Public Method WriteBool(name: String, value: Bool) method #

      name: true or name: false.

    • Public Method WriteFloat(name: String, value: Float32) method #

      A float as text format has it: its shortest form, or inf, -inf, or nan.

    • Public Method WriteDouble(name: String, value: Float64) method #

      A double as text format has it: its shortest form, or inf, -inf, or nan.

    • Public Method WriteString(name: String, value: String) method #

      A string in quotes, with C's escapes for quotes, backslashes, and control characters; the rest of its UTF-8 stays as it is.

    • Public Method WriteBytes(name: String, value: UInt8[]) method #

      Bytes in quotes, with C's escapes, and each byte that isn't printable ASCII in octal.

    • Public Method BeginMessage(name: String) method #

      Starts a message's fields: name {.

    • Public Method EndMessage() method #

      Ends the message BeginMessage started: }.

    • @PanicsAtCaller Public Method WriteUnknown(unknown: UInt8[]) method #

      The fields a message didn't know, by their numbers, as text format shows them: a varint as its number, a 4-byte or 8-byte value in hex, a length-delimited one as bytes in quotes, and a group between braces. Panics when unknown isn't fields, as a reader's Skip keeps them.

    • Public Method Finish(): String method #

      What was written, after which it starts again, empty.

    ProtoBox class

    Public Class ProtoBox<T>

    A message held inside another of its own type, which a Struct can't hold itself: it's a reference, made once and never changed, so copies of the message that share it still don't share changes.

    std/data/protobuf.fb, line 795

    • Public ReadOnly Field Value: T field #

      The message it holds.

    • Public New(value: T) constructor #

      A ProtoBox that holds value.

    • Operator ==(a: ProtoBox<T>, b: ProtoBox<T>): Bool operator #

      Whether a and b hold equal messages.

    Functions

    ProtoTag function

    @PanicsAtCaller Public Function ProtoTag(number: Int, wire: UInt32): UInt32

    The tag of field number with wire type, for code that writes the wire format itself. Panics when number isn't from 1 to PROTO_FIELD_LIMIT, or wire isn't one of the WIRE_ types.

    std/data/protobuf.fb, line 55

    ProtoIsZero function

    Public Function ProtoIsZero(value: Float32): Bool

    Whether a float is 0 as proto3 leaves out a field's zero: by its bits, so -0.0 isn't.

    std/data/protobuf.fb, line 66

    ProtoIsZero function

    Public Function ProtoIsZero(value: Float64): Bool

    Whether a double is 0 as proto3 leaves out a field's zero: by its bits, so -0.0 isn't.

    std/data/protobuf.fb, line 69

    ProtoKeepEnum function

    Public Function ProtoKeepEnum(unknown: UInt8[], tag: UInt32, number: Int32)

    Keeps a closed enum's number that isn't one of its values in unknown, as field tag's, as protobuf's readers keep one: a packed field's go one at a time.

    std/data/protobuf.fb, line 73

    ProtoPanic function

    @PanicsAtCaller Public Function ProtoPanic(message: String)

    Panics with message where the program calls what the module of a .proto gives, like a New given two of a oneof's fields.

    std/data/protobuf.fb, line 82

    Constants and globals

    WIRE_VARINT const

    Public Const WIRE_VARINT: UInt32 = 0

    A field's wire type, the low 3 bits of its tag: a varint, 8 bytes, a length and its bytes, a group's start and end, and 4 bytes.

    std/data/protobuf.fb, line 33

    WIRE_FIXED64 const

    Public Const WIRE_FIXED64: UInt32 = 1

    The wire type of a field of 8 bytes: a fixed64, sfixed64, or double.

    std/data/protobuf.fb, line 35

    WIRE_LENGTH const

    Public Const WIRE_LENGTH: UInt32 = 2

    The wire type of a field of a length and its bytes: a string, bytes, a message, or packed values.

    std/data/protobuf.fb, line 38

    WIRE_GROUP_START const

    Public Const WIRE_GROUP_START: UInt32 = 3

    The wire type that starts a group.

    std/data/protobuf.fb, line 40

    WIRE_GROUP_END const

    Public Const WIRE_GROUP_END: UInt32 = 4

    The wire type that ends a group.

    std/data/protobuf.fb, line 42

    WIRE_FIXED32 const

    Public Const WIRE_FIXED32: UInt32 = 5

    The wire type of a field of 4 bytes: a fixed32, sfixed32, or float.

    std/data/protobuf.fb, line 44

    PROTO_DEPTH_LIMIT const

    Public Const PROTO_DEPTH_LIMIT = 100

    How deep messages and groups nest inside each other before a reader stops, as protobuf's own readers do.

    std/data/protobuf.fb, line 48

    PROTO_FIELD_LIMIT const

    Public Const PROTO_FIELD_LIMIT = 536870911

    The highest field number: a tag keeps 3 bits for the wire type.

    std/data/protobuf.fb, line 51

    Report an issue with this page or with FutureBlitz on GitHub.