FlatBuffers Serialization Library
repository·master·Indexed 12 days ago
https://github.com/google/flatbuffersA cross-platform memory-efficient serialization library (version 25.12.19) that enables direct access to serialized data without intermediate parsing or unpacking. It includes the flatc compiler for generating language-specific classes from .fbs schemas and provides support for various platforms including C++, Go, Dart, Swift, Python, and TypeScript, with integrated gRPC support.
What's inside FlatBuffers
- FlatBuffers is an efficient, cross-platform serialization library designed for performance-critical applications like game development. It allows for direct access to serialized data without the need for a parsing or unpacking step, which minimizes memory overhead and increases speed. It is available under the Apache license v2.0 and supports a wide range of languages including C++, C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust, and Swift.
Supported Operating Systems and Languages
masterFlatBuffers supports a wide range of environments and programming languages.
Supported Operating Systems:
- Windows
- macOS
- Linux
- Android
- Any system with a recent C++ compiler (C++ 11 and newer)
Supported Programming Languages:
- C, C++, C#
- Dart, Go, Java, JavaScript, Kotlin, Lobster, Lua, PHP, Python, Rust, Swift, TypeScript, Nim
Use FlatBuffers with Dart
masterTo use FlatBuffers in a Dart project, you must use the
flatc(FlatBuffer compiler) binary to generate Dart classes from a FlatBuffers IDL schema. These generated classes allow you to read and write binary data that is interoperable with other languages and platforms supported by FlatBuffers.Workflow:
- Define your data structure in a
.fbsschema file. - Use the
flatccompiler to generate Dart code from that schema. - Use the generated Dart classes in your application to serialize or deserialize data.
- Define your data structure in a
What is FlexBuffers and when to use it
masterFlexBuffers is a schema-less binary serialization format designed for storing data that doesn't fit a predefined schema. While regular FlatBuffers require a schema for maximum performance and strong typing, FlexBuffers allows for free-form data structures.
Key Characteristics:
- Schema-less: You can store data without knowing the structure ahead of time.
- Zero-copy access: Like regular FlatBuffers, FlexBuffers can be accessed without parsing, copying, or object allocation, making it highly efficient for
mmap-ing large amounts of data. - Compact encoding: It uses automatic pooling of strings and automatic sizing of containers (8/16/32/64 bits) to minimize binary size.
- Performance Trade-off: FlexBuffers is slower than regular schema-based FlatBuffers, so it should only be used when schema-less flexibility is required.
What is FlatBuffers and when should I use it?
masterFlatBuffers is a memory-efficient serialization library designed for high-performance applications like games. Unlike traditional serialization formats that require a parsing/unpacking step to access data, FlatBuffers represents hierarchical data in a flat binary buffer that can be accessed directly.
Key benefits for developers:
- Zero-parsing access: You can access serialized data without unpacking it, meaning the only memory required is the buffer itself. In C++, this requires 0 additional allocations.
- Memory Efficiency: It is highly suitable for
mmapor streaming, as you only need parts of the buffer in memory at once. - Performance: Data access speed is close to raw struct access, involving only a single indirection (via a vtable) to support format evolution.
- Schema Evolution: Supports optional fields, providing both forwards and backwards compatibility.
- Strong Typing: Errors are caught at compile time rather than through error-prone runtime checks.
- Low Overhead: It has a tiny code footprint and minimal dependencies.
What is Flexbuffers?
masterFlexbuffers is a schema-less binary format developed by Google. Unlike standard FlatBuffers, it does not require a predefined schema. It is designed for high efficiency, allowing data to be accessed without parsing, copying, or memory allocation. This makes it ideal for memory-friendly use cases, such as
mmap-ing large amounts of free-form data.Key features include:
- Compact Encoding: Automatically sizes containers to their smallest possible representation (8, 16, 32, or 64 bits).
- Zero-copy Access: Access data directly from the binary buffer.
- Rust Integration: Supports Serde for automatic serialization of Rust data structures.
Text parsing limitations in Go
masterThe Go implementation does not currently support parsing text formats (such as Schemas or JSON) directly. If text parsing is required, you must use the C++ parser viacgo.How FlexBuffers Vectors are encoded
masterA vector is governed by a single bit width supplied by its parent.
Untyped Vectors (
SL_VECTOR)An untyped vector consists of:
- A size field (placed before the vector; an offset to the vector points to the first element, making the size field effectively at index -1).
- The elements of the vector.
- Type bytes (one
uint8_tper element) following the elements. These type bytes always follow the vector, even if the elements are larger scalars.
Example: A vector of
uint8_tvalues1, 2, 3is encoded as:uint8_t 3, 1, 2, 3, 4, 4, 4(Where
3is size,1, 2, 3are elements, and4, 4, 4are the type bytes).Typed Vectors
Typed vectors omit the trailing type bytes because the type is determined by the parent. This is used for:
- Inline signed/unsigned integers (
TYPE_VECTOR_INT/TYPE_VECTOR_UINT) - Floats (
TYPE_VECTOR_FLOAT) - Keys (
TYPE_VECTOR_KEY)
Additionally, fixed-length vectors of sizes 2, 3, or 4 (e.g.,
TYPE_VECTOR_INT2) exist for space savings when storing common data like colors.Serialize Unions in FlatBuffers
masterUnions in FlatBuffers allow a field to hold one of several different table types. When serializing a union, you must perform two distinct steps:
- Set the Type Field: Explicitly set the auto-generated
_typefield (e.g.,EquippedType) using the generated enum that identifies which type is currently in the union. - Set the Value Field: Provide the offset of the already-serialized object that belongs to the union.
This ensures the reader knows which specific type to cast the data to when accessing the union field.
// C# example: Setting a union field Monser.AddEquippedType(builder, Equipment.Weapon); Monster.AddEquipped(builder, axe.Value);// C++ example: Setting a union field flatbuffers::Offset<Monster> orc = CreateMonster( builder, &position, mana, hp, name, inventory, Color_Red, weapons, Equipment_Weapon, // The type enum axe.Union(), // The value offset path );- Set the Type Field: Explicitly set the auto-generated
Understand FlatBuffer format components and interoperability
masterA FlatBuffer is a binary, in-memory format consisting of scalars aligned to their own size. To ensure cross-platform interoperability, FlatBuffers assumes:
- Floating-point: Uses
IEEE-754format. - Signed integers: Uses
two's complementedrepresentation. - Endianness: The endianness for floating-point numbers is the same as for integers. All scalars are represented in little-endian format. While big-endian machines can use FlatBuffers, they will be slower due to byte-swap intrinsics.
The format is defined by offsets and adjacency rather than fixed memory locations. This allows for optimization and means two different implementations might produce different binary layouts for the same input data.
- Floating-point: Uses
Access untrusted buffers safely
masterWhen reading FlatBuffers from untrusted sources (like a network), use the safe API to prevent arbitrary memory access. The safe functions verify the buffer's integrity before interpreting it.
Safe functions (with verification):
rootsize_prefixed_rootroot_with_optssize_prefixed_root_with_opts
Unsafe functions (skip verification):
root_uncheckedsize_prefixed_root_uncheckedroot_with_opts_uncheckedsize_prefixed_root_with_opts_unchecked
Use the
_uncheckedversions only when processing large amounts of data from a trusted source (e.g., your own files on disk) to avoid the performance cost of verification.Use Reflection to read/write unknown FlatBuffer formats
masterFlatBuffers provides experimental support for reflection, allowing you to traverse and manipulate data without knowing the exact schema at compile time. This is achieved using a meta-schema (found in
reflection/reflection.fbs) that describes schemas themselves.Workflow:
- Use
flatcto write out parsed schemas as binary FlatBuffers using the meta-schema. - Load these binary schemas at runtime to query fields and read/write data.
- Include
<flatbuffers/reflection.h>to access the generated meta-schema code and helper functions.
Example usage can be found in
test.cpp/ReflectionTest().- Use