2.6. FlatBuffers

FlatBuffers is a framework that generates accessor code for serialized messages described in platform independent message description language. Individual language bindings are provided for multiple languages including C++, Java, Python, JavaScript.

2.6.1. Schema Language

The schema language defines the root type of a buffer, and any user defined types. Basic types are integer and floating point numbers of common sizes and booleans. Constructed types include vectors of basic types (also strings), enums with given backing types, structures and tables.

Structures and tables are the basic object representations with named and typed fields. All fields in a structure are mandatory, a structure cannot be estended later. All fields in a table are optional unless explicitly declared as required, a table can be extended later by adding fields at the end.

FlatBuffers Schema Example

namespace SomeNamespace;

enum SomeEnum: int { One = 1, Two, Three }

struct SomeStructure {

    // Basic integer types.
    a_byte: byte;
    a_short: short;
    an_int: int;
    a_long: long;
    an_unsigned_short: ushort;
    an_unsigned_int: uint;
    an_unsigned_long: ulong;

    // Basic float types.
    a_float: float;
    a_double: double;

    // Array field only supported in structures.
    an_int_array: [int: 123];
}

table SomeTable {

    // Optional fields.
    a_byte: byte;
    an_int: int;
    a_string: string;

    // Required field of non basic types.
    a_required_string: string (required);
    a_required_enum_array: [SomeEnum] (required);
}

table AnotherTable {

    // Explicitly specified field identifiers.
    // Must form continuous range from 0.
    // Must be specified everywhere.
    an_int: int (id: 2);
    a_long: long (id: 0);
    a_string: string (id: 1);

    // Fields with default values.
    a_float: float = 0.0 (id: 3);
}

// Union types only for tables.
union SomeUnion { SomeTable, AnotherTable }

table RootTable {
    content: SomeUnion;
}

// Root type must be table.
root_type RootTable;
  • A spectrum of basic types

  • Structures with mandatory fields

  • Extensible tables with optional fields

2.6.2. C++ Generated Code Basics

Buffer content is created using builder pattern. Child content must be serialized before parent content.

C++ Buffer Creation

Direct Creation. 

FlatBufferBuilder builder;
auto another_table = CreateAnotherTableDirect (builder, 0x1234, "Hello FlatBuffers !", 0x12345678);
builder.Finish (another_table);

Incremental Creation. 

FlatBufferBuilder builder;
auto some_string = builder.CreateString ("Hello FlatBuffers !");
auto another_table = CreateAnotherTable (builder, 0x1234, some_string, 0x12345678);
builder.Finish (another_table);

Accessor code is geared towards non copying access. Explicit verification functions are available to detect corrupted buffers.

C++ Buffer Access

Buffer Verification. 

uint8_t buffer [];
int size;
auto verifier = flatbuffers::Verifier (buffer, size);
if (VerifyAnotherTableBuffer (verifier)) {
    auto another_table = GetAnotherTable (buffer);
}

Buffer Access. 

cout << another_table->an_int ();
cout << another_table->a_long ();
cout << another_table->a_string ()->str ();

An alternative object based interface that resembles other serialization frameworks is also available.

2.6.3. References

  1. The FlatBuffers Project Home Page. https://google.github.io/flatbuffers