Internals.md revision 66de19ace80bae3bf377e43e9698597170bc9031
126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen# FlatBuffer Internals
226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenThis section is entirely optional for the use of FlatBuffers. In normal
426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenusage, you should never need the information contained herein. If you're
526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmersseninterested however, it should give you more of an appreciation of why
626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenFlatBuffers is both efficient and convenient.
726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen### Format components
926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
1026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenA FlatBuffer is a binary file and in-memory format consisting mostly of
1126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenscalars of various sizes, all aligned to their own size. Each scalar is
1226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenalso always represented in little-endian format, as this corresponds to
1326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenall commonly used CPUs today. FlatBuffers will also work on big-endian
1426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenmachines, but will be slightly slower because of additional
1526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenbyte-swap intrinsics.
1626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
1726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenOn purpose, the format leaves a lot of details about where exactly
1826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenthings live in memory undefined, e.g. fields in a table can have any
1926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenorder, and objects to some extend can be stored in many orders. This is
2026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenbecause the format doesn't need this information to be efficient, and it
2126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenleaves room for optimization and extension (for example, fields can be
2226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenpacked in a way that is most compact). Instead, the format is defined in
2326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenterms of offsets and adjacency only.
2426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
2526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen### Format identification
2626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
2726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenThe format also doesn't contain information for format identification
2826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenand versioning, which is also by design. FlatBuffers is a statically typed
2926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssensystem, meaning the user of a buffer needs to know what kind of buffer
3026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenit is. FlatBuffers can of course be wrapped inside other containers
3126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenwhere needed, or you can use its union feature to dynamically identify
3226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenmultiple possible sub-objects stored. Additionally, it can be used
3326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssentogether with the schema parser if full reflective capabilities are
3426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssendesired.
3526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
3626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenVersioning is something that is intrinsically part of the format (the
3726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenoptionality / extensibility of fields), so the format itself does not
3826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenneed a version number (it's a meta-format, in a sense). We're hoping
3926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenthat this format can accommodate all data needed. If format breaking
4026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenchanges are ever necessary, it would become a new kind of format rather
4126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenthan just a variation.
4226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
4326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen### Offsets
4426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
4526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenThe most important and generic offset type (see `flatbuffers.h`) is
4666de19ace80bae3bf377e43e9698597170bc9031Wouter van Oortmerssen`uoffset_t`, which is currently always a `uint32_t`, and is used to
4766de19ace80bae3bf377e43e9698597170bc9031Wouter van Oortmerssenrefer to all tables/unions/strings/vectors (these are never stored
4866de19ace80bae3bf377e43e9698597170bc9031Wouter van Oortmerssenin-line). 32bit is
4926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenintentional, since we want to keep the format binary compatible between
5026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen32 and 64bit systems, and a 64bit offset would bloat the size for almost
5126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenall uses. A version of this format with 64bit (or 16bit) offsets is easy to set
5226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenwhen needed. Unsigned means they can only point in one direction, which
5326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssentypically is forward (towards a higher memory location). Any backwards
5426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenoffsets will be explicitly marked as such.
5526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
5666de19ace80bae3bf377e43e9698597170bc9031Wouter van OortmerssenThe format starts with an `uoffset_t` to the root object in the buffer.
5726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
5826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenWe have two kinds of objects, structs and tables.
5926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
6026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen### Structs
6126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
6226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenThese are the simplest, and as mentioned, intended for simple data that
6326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenbenefits from being extra efficient and doesn't need versioning /
6426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenextensibility. They are always stored inline in their parent (a struct,
6526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssentable, or vector) for maximum compactness. Structs define a consistent
6626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenmemory layout where all components are aligned to their size, and
6726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenstructs aligned to their largest scalar member. This is done independent
6826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenof the alignment rules of the underlying compiler to guarantee a cross
6926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenplatform compatible layout. This layout is then enforced in the generated
7026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssencode.
7126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
7226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen### Tables
7326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
7426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenThese start with an `soffset_t` to a vtable (signed version of
7566de19ace80bae3bf377e43e9698597170bc9031Wouter van Oortmerssen`uoffset_t`, since vtables may be stored anywhere), followed by all the
7666de19ace80bae3bf377e43e9698597170bc9031Wouter van Oortmerssenfields as aligned scalars (or offsets). Unlike structs, not all fields
7766de19ace80bae3bf377e43e9698597170bc9031Wouter van Oortmerssenneed to be present. There is no set order and layout.
7826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
7926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenTo be able to access fields regardless of these uncertainties, we go
8026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenthrough a vtable of offsets. Vtables are shared between any objects that
8126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenhappen to have the same vtable values.
8226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
8366de19ace80bae3bf377e43e9698597170bc9031Wouter van OortmerssenThe elements of a vtable are all of type `voffset_t`, which is
8426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssena `uint16_t`. The first element is the number of elements of the vtable,
8526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenincluding this one. The second one is the size of the object, in bytes
8626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen(including the vtable offset). This size is used for streaming, to know
8726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenhow many bytes to read to be able to access all fields of the object.
8866de19ace80bae3bf377e43e9698597170bc9031Wouter van OortmerssenThe remaining elements are the N offsets, where N is the amount of fields
8926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssendeclared in the schema when the code that constructed this buffer was
9026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssencompiled (thus, the size of the table is N + 2).
9126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
9226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenAll accessor functions in the generated code for tables contain the
9326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenoffset into this table as a constant. This offset is checked against the
9426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenfirst field (the number of elements), to protect against newer code
9526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenreading older data. If this offset is out of range, or the vtable entry
9626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenis 0, that means the field is not present in this object, and the
9726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssendefault value is return. Otherwise, the entry is used as offset to the
9826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenfield to be read.
9926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
10026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen### Strings and Vectors
10126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
10226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenStrings are simply a vector of bytes, and are always
10326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssennull-terminated. Vectors are stored as contiguous aligned scalar
10466de19ace80bae3bf377e43e9698597170bc9031Wouter van Oortmerssenelements prefixed by a 32bit element count (not including any
10566de19ace80bae3bf377e43e9698597170bc9031Wouter van Oortmerssennull termination).
10626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
10726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen### Construction
10826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
10966de19ace80bae3bf377e43e9698597170bc9031Wouter van OortmerssenThe current implementation constructs these buffers backwards (starting
11066de19ace80bae3bf377e43e9698597170bc9031Wouter van Oortmerssenat the highest memory address of the buffer), since
11126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenthat significantly reduces the amount of bookkeeping and simplifies the
11226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenconstruction API.
11326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
11426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen### Code example
11526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
11626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenHere's an example of the code that gets generated for the `samples/monster.fbs`.
11726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenWhat follows is the entire file, broken up by comments:
11826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
11926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    // automatically generated, do not modify
12026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
12126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    #include "flatbuffers/flatbuffers.h"
12226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
12326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    namespace MyGame {
12426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    namespace Sample {
12526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
12626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenNested namespace support.
12726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
12826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    enum {
12926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      Color_Red = 0,
13026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      Color_Green = 1,
13126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      Color_Blue = 2,
13226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    };
13326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
13426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    inline const char **EnumNamesColor() {
13526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      static const char *names[] = { "Red", "Green", "Blue", nullptr };
13626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      return names;
13726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    }
13826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
13926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    inline const char *EnumNameColor(int e) { return EnumNamesColor()[e]; }
14026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
14126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenEnums and convenient reverse lookup.
14226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
14326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    enum {
14426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      Any_NONE = 0,
14526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      Any_Monster = 1,
14626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    };
14726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
14826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    inline const char **EnumNamesAny() {
14926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      static const char *names[] = { "NONE", "Monster", nullptr };
15026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      return names;
15126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    }
15226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
15326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    inline const char *EnumNameAny(int e) { return EnumNamesAny()[e]; }
15426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
15526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenUnions share a lot with enums.
15626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
15726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    struct Vec3;
15826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    struct Monster;
15926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
16026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenPredeclare all datatypes since there may be circular references.
16126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
16226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    MANUALLY_ALIGNED_STRUCT(4) Vec3 {
16326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen     private:
16426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      float x_;
16526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      float y_;
16626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      float z_;
16726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
16826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen     public:
16926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      Vec3(float x, float y, float z)
17026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen        : x_(flatbuffers::EndianScalar(x)), y_(flatbuffers::EndianScalar(y)), z_(flatbuffers::EndianScalar(z)) {}
17126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
17226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      float x() const { return flatbuffers::EndianScalar(x_); }
17326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      float y() const { return flatbuffers::EndianScalar(y_); }
17426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      float z() const { return flatbuffers::EndianScalar(z_); }
17526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    };
17626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    STRUCT_END(Vec3, 12);
17726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
17826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenThese ugly macros do a couple of things: they turn off any padding the compiler
17926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenmight normally do, since we add padding manually (though none in this example),
18026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenand they enforce alignment chosen by FlatBuffers. This ensures the layout of
18126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenthis struct will look the same regardless of compiler and platform. Note that
18226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenthe fields are private: this is because these store little endian scalars
18326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenregardless of platform (since this is part of the serialized data).
18426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen`EndianScalar` then converts back and forth, which is a no-op on all current
18526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenmobile and desktop platforms, and a single machine instruction on the few
18626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenremaining big endian platforms.
18726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
18826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    struct Monster : private flatbuffers::Table {
18926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      const Vec3 *pos() const { return GetStruct<const Vec3 *>(4); }
19026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      int16_t mana() const { return GetField<int16_t>(6, 150); }
19126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      int16_t hp() const { return GetField<int16_t>(8, 100); }
19226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      const flatbuffers::String *name() const { return GetPointer<const flatbuffers::String *>(10); }
19326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      const flatbuffers::Vector<uint8_t> *inventory() const { return GetPointer<const flatbuffers::Vector<uint8_t> *>(14); }
19426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      int8_t color() const { return GetField<int8_t>(16, 2); }
19526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    };
19626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
19726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenTables are a bit more complicated. A table accessor struct is used to point at
19826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenthe serialized data for a table, which always starts with an offset to its
19926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenvtable. It derives from `Table`, which contains the `GetField` helper functions.
20026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenGetField takes a vtable offset, and a default value. It will look in the vtable
20126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenat that offset. If the offset is out of bounds (data from an older version) or
20226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenthe vtable entry is 0, the field is not present and the default is returned.
20326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenOtherwise, it uses the entry as an offset into the table to locate the field.
20426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
20526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    struct MonsterBuilder {
20626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      flatbuffers::FlatBufferBuilder &fbb_;
20726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      flatbuffers::uoffset_t start_;
20826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      void add_pos(const Vec3 *pos) { fbb_.AddStruct(4, pos); }
20926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      void add_mana(int16_t mana) { fbb_.AddElement<int16_t>(6, mana, 150); }
21026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      void add_hp(int16_t hp) { fbb_.AddElement<int16_t>(8, hp, 100); }
21126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      void add_name(flatbuffers::Offset<flatbuffers::String> name) { fbb_.AddOffset(10, name); }
21226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      void add_inventory(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory) { fbb_.AddOffset(14, inventory); }
21326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      void add_color(int8_t color) { fbb_.AddElement<int8_t>(16, color, 2); }
21426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
21526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      flatbuffers::Offset<Monster> Finish() { return flatbuffers::Offset<Monster>(fbb_.EndTable(start_, 7)); }
21626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    };
21726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
21826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen`MonsterBuilder` is the base helper struct to construct a table using a
21926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen`FlatBufferBuilder`. You can add the fields in any order, and the `Finish`
22026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssencall will ensure the correct vtable gets generated.
22126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
22226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const Vec3 *pos, int16_t mana, int16_t hp, flatbuffers::Offset<flatbuffers::String> name, flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory, int8_t color) {
22326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      MonsterBuilder builder_(_fbb);
22426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      builder_.add_inventory(inventory);
22526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      builder_.add_name(name);
22626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      builder_.add_pos(pos);
22726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      builder_.add_hp(hp);
22826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      builder_.add_mana(mana);
22926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      builder_.add_color(color);
23026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen      return builder_.Finish();
23126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    }
23226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
23326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen`CreateMonster` is a convenience function that calls all functions in
23426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen`MonsterBuilder` above for you. Note that if you pass values which are
23526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssendefaults as arguments, it will not actually construct that field, so
23626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenyou can probably use this function instead of the builder class in
23726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenalmost all cases.
23826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
23926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    inline const Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot<Monster>(buf); }
24026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
24126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van OortmerssenThis function is only generated for the root table type, to be able to
24226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenstart traversing a FlatBuffer from a raw buffer pointer.
24326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
24426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    }; // namespace MyGame
24526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen    }; // namespace Sample
24626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
24726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen
248