mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-01 19:58:15 +00:00
Added nested FlexBuffer parsing
Change-Id: I918b66eb5646d035e3aae675f745802eb54b03ea
This commit is contained in:
@@ -128,6 +128,16 @@ A description of how FlexBuffers are encoded is in the
|
||||
[internals](Internals.md#flexbuffers) document.
|
||||
|
||||
|
||||
# Nesting inside a FlatBuffer
|
||||
|
||||
You can mark a field as containing a FlexBuffer, e.g.
|
||||
|
||||
a:[ubyte] (flexbuffer);
|
||||
|
||||
A special accessor will be generated that allows you to access the root value
|
||||
directly, e.g. `a_flexbuffer_root().AsInt64()`.
|
||||
|
||||
|
||||
# Efficiency tips
|
||||
|
||||
* Vectors generally are a lot more efficient than maps, so prefer them over maps
|
||||
|
||||
@@ -302,6 +302,9 @@ Current understood attributes:
|
||||
(which must be a vector of ubyte) contains flatbuffer data, for which the
|
||||
root type is given by `table_name`. The generated code will then produce
|
||||
a convenient accessor for the nested FlatBuffer.
|
||||
- `flexbuffer` (on a field): this indicates that the field
|
||||
(which must be a vector of ubyte) contains flexbuffer data. The generated
|
||||
code will then produce a convenient accessor for the FlexBuffer root.
|
||||
- `key` (on a field): this field is meant to be used as a key when sorting
|
||||
a vector of the type of table it sits in. Can be used for in-place
|
||||
binary search.
|
||||
|
||||
@@ -471,6 +471,7 @@ class Parser : public ParserState {
|
||||
explicit Parser(const IDLOptions &options = IDLOptions())
|
||||
: root_struct_def_(nullptr),
|
||||
opts(options),
|
||||
uses_flexbuffers_(false),
|
||||
source_(nullptr),
|
||||
anonymous_counter(0) {
|
||||
// Just in case none are declared:
|
||||
@@ -493,6 +494,7 @@ class Parser : public ParserState {
|
||||
known_attributes_["native_inline"] = true;
|
||||
known_attributes_["native_type"] = true;
|
||||
known_attributes_["native_default"] = true;
|
||||
known_attributes_["flexbuffer"] = true;
|
||||
}
|
||||
|
||||
~Parser() {
|
||||
@@ -617,6 +619,7 @@ private:
|
||||
std::map<std::string, bool> known_attributes_;
|
||||
|
||||
IDLOptions opts;
|
||||
bool uses_flexbuffers_;
|
||||
|
||||
private:
|
||||
const char *source_;
|
||||
|
||||
@@ -97,6 +97,9 @@ class CppGenerator : public BaseGenerator {
|
||||
code_ += "";
|
||||
|
||||
code_ += "#include \"flatbuffers/flatbuffers.h\"";
|
||||
if (parser_.uses_flexbuffers_) {
|
||||
code_ += "#include \"flatbuffers/flexbuffers.h\"";
|
||||
}
|
||||
code_ += "";
|
||||
|
||||
if (parser_.opts.include_dependence_headers) {
|
||||
@@ -1335,11 +1338,19 @@ class CppGenerator : public BaseGenerator {
|
||||
code_.SetValue("CPP_NAME", TranslateNameSpace(qualified_name));
|
||||
|
||||
code_ += " const {{CPP_NAME}} *{{FIELD_NAME}}_nested_root() const {";
|
||||
code_ += " const uint8_t* data = {{FIELD_NAME}}()->Data();";
|
||||
code_ += " auto data = {{FIELD_NAME}}()->Data();";
|
||||
code_ += " return flatbuffers::GetRoot<{{CPP_NAME}}>(data);";
|
||||
code_ += " }";
|
||||
}
|
||||
|
||||
if (field.attributes.Lookup("flexbuffer")) {
|
||||
code_ += " flexbuffers::Reference {{FIELD_NAME}}_flexbuffer_root()"
|
||||
" const {";
|
||||
code_ += " auto v = {{FIELD_NAME}}();";
|
||||
code_ += " return flexbuffers::GetRoot(v->Data(), v->size());";
|
||||
code_ += " }";
|
||||
}
|
||||
|
||||
// Generate a comparison function for this field if it is a key.
|
||||
if (field.key) {
|
||||
const bool is_string = (field.value.type.base_type == BASE_TYPE_STRING);
|
||||
|
||||
@@ -725,6 +725,14 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
|
||||
LookupCreateStruct(nested->constant);
|
||||
}
|
||||
|
||||
if (field->attributes.Lookup("flexbuffer")) {
|
||||
uses_flexbuffers_ = true;
|
||||
if (field->value.type.base_type != BASE_TYPE_VECTOR ||
|
||||
field->value.type.element != BASE_TYPE_UCHAR)
|
||||
return Error(
|
||||
"flexbuffer attribute may only apply to a vector of ubyte");
|
||||
}
|
||||
|
||||
if (typefield) {
|
||||
// If this field is a union, and it has a manually assigned id,
|
||||
// the automatically added type field should have an id as well (of N - 1).
|
||||
|
||||
@@ -83,8 +83,12 @@ public struct Monster : IFlatbufferObject
|
||||
public int Testarrayofstring2Length { get { int o = __p.__offset(60); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||
public Ability? Testarrayofsortedstruct(int j) { int o = __p.__offset(62); return o != 0 ? (Ability?)(new Ability()).__assign(__p.__vector(o) + j * 8, __p.bb) : null; }
|
||||
public int TestarrayofsortedstructLength { get { int o = __p.__offset(62); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||
public byte Flex(int j) { int o = __p.__offset(64); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
|
||||
public int FlexLength { get { int o = __p.__offset(64); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||
public ArraySegment<byte>? GetFlexBytes() { return __p.__vector_as_arraysegment(64); }
|
||||
public bool MutateFlex(int j, byte flex) { int o = __p.__offset(64); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, flex); return true; } else { return false; } }
|
||||
|
||||
public static void StartMonster(FlatBufferBuilder builder) { builder.StartObject(30); }
|
||||
public static void StartMonster(FlatBufferBuilder builder) { builder.StartObject(31); }
|
||||
public static void AddPos(FlatBufferBuilder builder, Offset<Vec3> posOffset) { builder.AddStruct(0, posOffset.Value, 0); }
|
||||
public static void AddMana(FlatBufferBuilder builder, short mana) { builder.AddShort(1, mana, 150); }
|
||||
public static void AddHp(FlatBufferBuilder builder, short hp) { builder.AddShort(2, hp, 100); }
|
||||
@@ -128,6 +132,9 @@ public struct Monster : IFlatbufferObject
|
||||
public static void StartTestarrayofstring2Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
|
||||
public static void AddTestarrayofsortedstruct(FlatBufferBuilder builder, VectorOffset testarrayofsortedstructOffset) { builder.AddOffset(29, testarrayofsortedstructOffset.Value, 0); }
|
||||
public static void StartTestarrayofsortedstructVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 4); }
|
||||
public static void AddFlex(FlatBufferBuilder builder, VectorOffset flexOffset) { builder.AddOffset(30, flexOffset.Value, 0); }
|
||||
public static VectorOffset CreateFlexVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
|
||||
public static void StartFlexVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
|
||||
public static Offset<Monster> EndMonster(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
builder.Required(o, 10); // name
|
||||
|
||||
@@ -438,8 +438,33 @@ func (rcv *Monster) TestarrayofsortedstructLength() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Monster) Flex(j int) byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(64))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Monster) FlexLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(64))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Monster) FlexBytes() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(64))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func MonsterStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(30)
|
||||
builder.StartObject(31)
|
||||
}
|
||||
func MonsterAddPos(builder *flatbuffers.Builder, pos flatbuffers.UOffsetT) {
|
||||
builder.PrependStructSlot(0, flatbuffers.UOffsetT(pos), 0)
|
||||
@@ -552,6 +577,12 @@ func MonsterAddTestarrayofsortedstruct(builder *flatbuffers.Builder, testarrayof
|
||||
func MonsterStartTestarrayofsortedstructVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(8, numElems, 4)
|
||||
}
|
||||
func MonsterAddFlex(builder *flatbuffers.Builder, flex flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(30, flatbuffers.UOffsetT(flex), 0)
|
||||
}
|
||||
func MonsterStartFlexVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(1, numElems, 1)
|
||||
}
|
||||
func MonsterEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
|
||||
@@ -91,8 +91,12 @@ public final class Monster extends Table {
|
||||
public Ability testarrayofsortedstruct(int j) { return testarrayofsortedstruct(new Ability(), j); }
|
||||
public Ability testarrayofsortedstruct(Ability obj, int j) { int o = __offset(62); return o != 0 ? obj.__assign(__vector(o) + j * 8, bb) : null; }
|
||||
public int testarrayofsortedstructLength() { int o = __offset(62); return o != 0 ? __vector_len(o) : 0; }
|
||||
public int flex(int j) { int o = __offset(64); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
|
||||
public int flexLength() { int o = __offset(64); return o != 0 ? __vector_len(o) : 0; }
|
||||
public ByteBuffer flexAsByteBuffer() { return __vector_as_bytebuffer(64, 1); }
|
||||
public boolean mutateFlex(int j, int flex) { int o = __offset(64); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)flex); return true; } else { return false; } }
|
||||
|
||||
public static void startMonster(FlatBufferBuilder builder) { builder.startObject(30); }
|
||||
public static void startMonster(FlatBufferBuilder builder) { builder.startObject(31); }
|
||||
public static void addPos(FlatBufferBuilder builder, int posOffset) { builder.addStruct(0, posOffset, 0); }
|
||||
public static void addMana(FlatBufferBuilder builder, short mana) { builder.addShort(1, mana, 150); }
|
||||
public static void addHp(FlatBufferBuilder builder, short hp) { builder.addShort(2, hp, 100); }
|
||||
@@ -136,6 +140,9 @@ public final class Monster extends Table {
|
||||
public static void startTestarrayofstring2Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
|
||||
public static void addTestarrayofsortedstruct(FlatBufferBuilder builder, int testarrayofsortedstructOffset) { builder.addOffset(29, testarrayofsortedstructOffset, 0); }
|
||||
public static void startTestarrayofsortedstructVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 4); }
|
||||
public static void addFlex(FlatBufferBuilder builder, int flexOffset) { builder.addOffset(30, flexOffset, 0); }
|
||||
public static int createFlexVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
|
||||
public static void startFlexVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
|
||||
public static int endMonster(FlatBufferBuilder builder) {
|
||||
int o = builder.endObject();
|
||||
builder.required(o, 10); // name
|
||||
|
||||
@@ -398,22 +398,49 @@ class Monster extends Table
|
||||
return $o != 0 ? $this->__vector_len($o) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int offset
|
||||
* @return byte
|
||||
*/
|
||||
public function getFlex($j)
|
||||
{
|
||||
$o = $this->__offset(64);
|
||||
return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getFlexLength()
|
||||
{
|
||||
$o = $this->__offset(64);
|
||||
return $o != 0 ? $this->__vector_len($o) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFlexBytes()
|
||||
{
|
||||
return $this->__vector_as_bytes(64);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @return void
|
||||
*/
|
||||
public static function startMonster(FlatBufferBuilder $builder)
|
||||
{
|
||||
$builder->StartObject(30);
|
||||
$builder->StartObject(31);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @return Monster
|
||||
*/
|
||||
public static function createMonster(FlatBufferBuilder $builder, $pos, $mana, $hp, $name, $inventory, $color, $test_type, $test, $test4, $testarrayofstring, $testarrayoftables, $enemy, $testnestedflatbuffer, $testempty, $testbool, $testhashs32_fnv1, $testhashu32_fnv1, $testhashs64_fnv1, $testhashu64_fnv1, $testhashs32_fnv1a, $testhashu32_fnv1a, $testhashs64_fnv1a, $testhashu64_fnv1a, $testarrayofbools, $testf, $testf2, $testf3, $testarrayofstring2, $testarrayofsortedstruct)
|
||||
public static function createMonster(FlatBufferBuilder $builder, $pos, $mana, $hp, $name, $inventory, $color, $test_type, $test, $test4, $testarrayofstring, $testarrayoftables, $enemy, $testnestedflatbuffer, $testempty, $testbool, $testhashs32_fnv1, $testhashu32_fnv1, $testhashs64_fnv1, $testhashu64_fnv1, $testhashs32_fnv1a, $testhashu32_fnv1a, $testhashs64_fnv1a, $testhashu64_fnv1a, $testarrayofbools, $testf, $testf2, $testf3, $testarrayofstring2, $testarrayofsortedstruct, $flex)
|
||||
{
|
||||
$builder->startObject(30);
|
||||
$builder->startObject(31);
|
||||
self::addPos($builder, $pos);
|
||||
self::addMana($builder, $mana);
|
||||
self::addHp($builder, $hp);
|
||||
@@ -443,6 +470,7 @@ class Monster extends Table
|
||||
self::addTestf3($builder, $testf3);
|
||||
self::addTestarrayofstring2($builder, $testarrayofstring2);
|
||||
self::addTestarrayofsortedstruct($builder, $testarrayofsortedstruct);
|
||||
self::addFlex($builder, $flex);
|
||||
$o = $builder->endObject();
|
||||
$builder->required($o, 10); // name
|
||||
return $o;
|
||||
@@ -925,6 +953,40 @@ class Monster extends Table
|
||||
$builder->startVector(8, $numElems, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @param VectorOffset
|
||||
* @return void
|
||||
*/
|
||||
public static function addFlex(FlatBufferBuilder $builder, $flex)
|
||||
{
|
||||
$builder->addOffsetX(30, $flex, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @param array offset array
|
||||
* @return int vector offset
|
||||
*/
|
||||
public static function createFlexVector(FlatBufferBuilder $builder, array $data)
|
||||
{
|
||||
$builder->startVector(1, count($data), 1);
|
||||
for ($i = count($data) - 1; $i >= 0; $i--) {
|
||||
$builder->addByte($data[$i]);
|
||||
}
|
||||
return $builder->endVector();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @param int $numElems
|
||||
* @return void
|
||||
*/
|
||||
public static function startFlexVector(FlatBufferBuilder $builder, $numElems)
|
||||
{
|
||||
$builder->startVector(1, $numElems, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @return int table offset
|
||||
|
||||
@@ -316,7 +316,22 @@ class Monster(object):
|
||||
return self._tab.VectorLen(o)
|
||||
return 0
|
||||
|
||||
def MonsterStart(builder): builder.StartObject(30)
|
||||
# Monster
|
||||
def Flex(self, j):
|
||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
|
||||
if o != 0:
|
||||
a = self._tab.Vector(o)
|
||||
return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
|
||||
return 0
|
||||
|
||||
# Monster
|
||||
def FlexLength(self):
|
||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
|
||||
if o != 0:
|
||||
return self._tab.VectorLen(o)
|
||||
return 0
|
||||
|
||||
def MonsterStart(builder): builder.StartObject(31)
|
||||
def MonsterAddPos(builder, pos): builder.PrependStructSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(pos), 0)
|
||||
def MonsterAddMana(builder, mana): builder.PrependInt16Slot(1, mana, 150)
|
||||
def MonsterAddHp(builder, hp): builder.PrependInt16Slot(2, hp, 100)
|
||||
@@ -354,4 +369,6 @@ def MonsterAddTestarrayofstring2(builder, testarrayofstring2): builder.PrependUO
|
||||
def MonsterStartTestarrayofstring2Vector(builder, numElems): return builder.StartVector(4, numElems, 4)
|
||||
def MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct): builder.PrependUOffsetTRelativeSlot(29, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofsortedstruct), 0)
|
||||
def MonsterStartTestarrayofsortedstructVector(builder, numElems): return builder.StartVector(8, numElems, 4)
|
||||
def MonsterAddFlex(builder, flex): builder.PrependUOffsetTRelativeSlot(30, flatbuffers.number_types.UOffsetTFlags.py_type(flex), 0)
|
||||
def MonsterStartFlexVector(builder, numElems): return builder.StartVector(1, numElems, 1)
|
||||
def MonsterEnd(builder): return builder.EndObject()
|
||||
|
||||
@@ -73,6 +73,7 @@ table Monster {
|
||||
testf:float = 3.14159 (id:25);
|
||||
testf2:float = 3 (id:26);
|
||||
testf3:float (id:27);
|
||||
flex:[ubyte] (id:30, flexbuffer);
|
||||
}
|
||||
|
||||
rpc_service MonsterStorage {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#define FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/flexbuffers.h"
|
||||
|
||||
namespace MyGame {
|
||||
namespace Example2 {
|
||||
@@ -543,6 +544,7 @@ struct MonsterT : public flatbuffers::NativeTable {
|
||||
float testf3;
|
||||
std::vector<std::string> testarrayofstring2;
|
||||
std::vector<Ability> testarrayofsortedstruct;
|
||||
std::vector<uint8_t> flex;
|
||||
MonsterT()
|
||||
: mana(150),
|
||||
hp(100),
|
||||
@@ -594,7 +596,8 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VT_TESTF2 = 56,
|
||||
VT_TESTF3 = 58,
|
||||
VT_TESTARRAYOFSTRING2 = 60,
|
||||
VT_TESTARRAYOFSORTEDSTRUCT = 62
|
||||
VT_TESTARRAYOFSORTEDSTRUCT = 62,
|
||||
VT_FLEX = 64
|
||||
};
|
||||
const Vec3 *pos() const {
|
||||
return GetStruct<const Vec3 *>(VT_POS);
|
||||
@@ -693,7 +696,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_TESTNESTEDFLATBUFFER);
|
||||
}
|
||||
const MyGame::Example::Monster *testnestedflatbuffer_nested_root() const {
|
||||
const uint8_t* data = testnestedflatbuffer()->Data();
|
||||
auto data = testnestedflatbuffer()->Data();
|
||||
return flatbuffers::GetRoot<MyGame::Example::Monster>(data);
|
||||
}
|
||||
const Stat *testempty() const {
|
||||
@@ -792,6 +795,16 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
flatbuffers::Vector<const Ability *> *mutable_testarrayofsortedstruct() {
|
||||
return GetPointer<flatbuffers::Vector<const Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
|
||||
}
|
||||
const flatbuffers::Vector<uint8_t> *flex() const {
|
||||
return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_FLEX);
|
||||
}
|
||||
flatbuffers::Vector<uint8_t> *mutable_flex() {
|
||||
return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_FLEX);
|
||||
}
|
||||
flexbuffers::Reference flex_flexbuffer_root() const {
|
||||
auto v = flex();
|
||||
return flexbuffers::GetRoot(v->Data(), v->size());
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<Vec3>(verifier, VT_POS) &&
|
||||
@@ -838,6 +851,8 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
verifier.VerifyVectorOfStrings(testarrayofstring2()) &&
|
||||
VerifyOffset(verifier, VT_TESTARRAYOFSORTEDSTRUCT) &&
|
||||
verifier.Verify(testarrayofsortedstruct()) &&
|
||||
VerifyOffset(verifier, VT_FLEX) &&
|
||||
verifier.Verify(flex()) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
|
||||
@@ -947,13 +962,16 @@ struct MonsterBuilder {
|
||||
void add_testarrayofsortedstruct(flatbuffers::Offset<flatbuffers::Vector<const Ability *>> testarrayofsortedstruct) {
|
||||
fbb_.AddOffset(Monster::VT_TESTARRAYOFSORTEDSTRUCT, testarrayofsortedstruct);
|
||||
}
|
||||
void add_flex(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> flex) {
|
||||
fbb_.AddOffset(Monster::VT_FLEX, flex);
|
||||
}
|
||||
MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
MonsterBuilder &operator=(const MonsterBuilder &);
|
||||
flatbuffers::Offset<Monster> Finish() {
|
||||
const auto end = fbb_.EndTable(start_, 30);
|
||||
const auto end = fbb_.EndTable(start_, 31);
|
||||
auto o = flatbuffers::Offset<Monster>(end);
|
||||
fbb_.Required(o, Monster::VT_NAME);
|
||||
return o;
|
||||
@@ -990,12 +1008,14 @@ inline flatbuffers::Offset<Monster> CreateMonster(
|
||||
float testf2 = 3.0f,
|
||||
float testf3 = 0.0f,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2 = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<const Ability *>> testarrayofsortedstruct = 0) {
|
||||
flatbuffers::Offset<flatbuffers::Vector<const Ability *>> testarrayofsortedstruct = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> flex = 0) {
|
||||
MonsterBuilder builder_(_fbb);
|
||||
builder_.add_testhashu64_fnv1a(testhashu64_fnv1a);
|
||||
builder_.add_testhashs64_fnv1a(testhashs64_fnv1a);
|
||||
builder_.add_testhashu64_fnv1(testhashu64_fnv1);
|
||||
builder_.add_testhashs64_fnv1(testhashs64_fnv1);
|
||||
builder_.add_flex(flex);
|
||||
builder_.add_testarrayofsortedstruct(testarrayofsortedstruct);
|
||||
builder_.add_testarrayofstring2(testarrayofstring2);
|
||||
builder_.add_testf3(testf3);
|
||||
@@ -1054,7 +1074,8 @@ inline flatbuffers::Offset<Monster> CreateMonsterDirect(
|
||||
float testf2 = 3.0f,
|
||||
float testf3 = 0.0f,
|
||||
const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring2 = nullptr,
|
||||
const std::vector<const Ability *> *testarrayofsortedstruct = nullptr) {
|
||||
const std::vector<const Ability *> *testarrayofsortedstruct = nullptr,
|
||||
const std::vector<uint8_t> *flex = nullptr) {
|
||||
return MyGame::Example::CreateMonster(
|
||||
_fbb,
|
||||
pos,
|
||||
@@ -1085,7 +1106,8 @@ inline flatbuffers::Offset<Monster> CreateMonsterDirect(
|
||||
testf2,
|
||||
testf3,
|
||||
testarrayofstring2 ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring2) : 0,
|
||||
testarrayofsortedstruct ? _fbb.CreateVector<const Ability *>(*testarrayofsortedstruct) : 0);
|
||||
testarrayofsortedstruct ? _fbb.CreateVector<const Ability *>(*testarrayofsortedstruct) : 0,
|
||||
flex ? _fbb.CreateVector<uint8_t>(*flex) : 0);
|
||||
}
|
||||
|
||||
flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
@@ -1214,6 +1236,7 @@ inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function
|
||||
{ auto _e = testf3(); _o->testf3 = _e; };
|
||||
{ auto _e = testarrayofstring2(); if (_e) { _o->testarrayofstring2.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring2[_i] = _e->Get(_i)->str(); } } };
|
||||
{ auto _e = testarrayofsortedstruct(); if (_e) { _o->testarrayofsortedstruct.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofsortedstruct[_i] = *_e->Get(_i); } } };
|
||||
{ auto _e = flex(); if (_e) { _o->flex.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->flex[_i] = _e->Get(_i); } } };
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||
@@ -1252,6 +1275,7 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
|
||||
auto _testf3 = _o->testf3;
|
||||
auto _testarrayofstring2 = _o->testarrayofstring2.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring2) : 0;
|
||||
auto _testarrayofsortedstruct = _o->testarrayofsortedstruct.size() ? _fbb.CreateVectorOfStructs(_o->testarrayofsortedstruct) : 0;
|
||||
auto _flex = _o->flex.size() ? _fbb.CreateVector(_o->flex) : 0;
|
||||
return MyGame::Example::CreateMonster(
|
||||
_fbb,
|
||||
_pos,
|
||||
@@ -1282,7 +1306,8 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
|
||||
_testf2,
|
||||
_testf3,
|
||||
_testarrayofstring2,
|
||||
_testarrayofsortedstruct);
|
||||
_testarrayofsortedstruct,
|
||||
_flex);
|
||||
}
|
||||
|
||||
inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type) {
|
||||
|
||||
@@ -1271,11 +1271,36 @@ MyGame.Example.Monster.prototype.testarrayofsortedstructLength = function() {
|
||||
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} index
|
||||
* @returns {number}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.flex = function(index) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 64);
|
||||
return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.flexLength = function() {
|
||||
var offset = this.bb.__offset(this.bb_pos, 64);
|
||||
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.flexArray = function() {
|
||||
var offset = this.bb.__offset(this.bb_pos, 64);
|
||||
return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
*/
|
||||
MyGame.Example.Monster.startMonster = function(builder) {
|
||||
builder.startObject(30);
|
||||
builder.startObject(31);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1652,6 +1677,35 @@ MyGame.Example.Monster.startTestarrayofsortedstructVector = function(builder, nu
|
||||
builder.startVector(8, numElems, 4);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
* @param {flatbuffers.Offset} flexOffset
|
||||
*/
|
||||
MyGame.Example.Monster.addFlex = function(builder, flexOffset) {
|
||||
builder.addFieldOffset(30, flexOffset, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
* @param {Array.<number>} data
|
||||
* @returns {flatbuffers.Offset}
|
||||
*/
|
||||
MyGame.Example.Monster.createFlexVector = function(builder, data) {
|
||||
builder.startVector(1, data.length, 1);
|
||||
for (var i = data.length - 1; i >= 0; i--) {
|
||||
builder.addInt8(data[i]);
|
||||
}
|
||||
return builder.endVector();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
* @param {number} numElems
|
||||
*/
|
||||
MyGame.Example.Monster.startFlexVector = function(builder, numElems) {
|
||||
builder.startVector(1, numElems, 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
* @returns {flatbuffers.Offset}
|
||||
|
||||
@@ -1262,11 +1262,36 @@ testarrayofsortedstructLength():number {
|
||||
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} index
|
||||
* @returns {number}
|
||||
*/
|
||||
flex(index: number):number|null {
|
||||
var offset = this.bb.__offset(this.bb_pos, 64);
|
||||
return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
flexLength():number {
|
||||
var offset = this.bb.__offset(this.bb_pos, 64);
|
||||
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
flexArray():Uint8Array|null {
|
||||
var offset = this.bb.__offset(this.bb_pos, 64);
|
||||
return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
*/
|
||||
static startMonster(builder:flatbuffers.Builder) {
|
||||
builder.startObject(30);
|
||||
builder.startObject(31);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1643,6 +1668,35 @@ static startTestarrayofsortedstructVector(builder:flatbuffers.Builder, numElems:
|
||||
builder.startVector(8, numElems, 4);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
* @param {flatbuffers.Offset} flexOffset
|
||||
*/
|
||||
static addFlex(builder:flatbuffers.Builder, flexOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(30, flexOffset, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
* @param {Array.<number>} data
|
||||
* @returns {flatbuffers.Offset}
|
||||
*/
|
||||
static createFlexVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
|
||||
builder.startVector(1, data.length, 1);
|
||||
for (var i = data.length - 1; i >= 0; i--) {
|
||||
builder.addInt8(data[i]);
|
||||
}
|
||||
return builder.endVector();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
* @param {number} numElems
|
||||
*/
|
||||
static startFlexVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(1, numElems, 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
* @returns {flatbuffers.Offset}
|
||||
|
||||
Binary file not shown.
@@ -167,13 +167,19 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
|
||||
builder.CreateVector(nested_builder.GetBufferPointer(),
|
||||
nested_builder.GetSize());
|
||||
|
||||
// Test a nested FlexBuffer:
|
||||
flexbuffers::Builder flexbuild;
|
||||
flexbuild.Int(1234);
|
||||
flexbuild.Finish();
|
||||
auto flex = builder.CreateVector(flexbuild.GetBuffer());
|
||||
|
||||
// shortcut for creating monster with all fields set:
|
||||
auto mloc = CreateMonster(builder, &vec, 150, 80, name, inventory, Color_Blue,
|
||||
Any_Monster, mlocs[1].Union(), // Store a union.
|
||||
testv, vecofstrings, vecoftables, 0,
|
||||
nested_flatbuffer_vector, 0, false,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 3.14159f, 3.0f, 0.0f,
|
||||
vecofstrings2, vecofstructs);
|
||||
vecofstrings2, vecofstructs, flex);
|
||||
|
||||
FinishMonsterBuffer(builder, mloc);
|
||||
|
||||
@@ -205,10 +211,6 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length,
|
||||
std::memcpy(&test_buff[0], flatbuf , length);
|
||||
std::memcpy(&test_buff[length], flatbuf , length);
|
||||
|
||||
flatbuffers::Verifier verifierl(&test_buff[0], length - 1);
|
||||
TEST_EQ(VerifyMonsterBuffer(verifierl), false);
|
||||
TEST_EQ(verifierl.GetComputedSize(), 0);
|
||||
|
||||
flatbuffers::Verifier verifier1(&test_buff[0], length);
|
||||
TEST_EQ(VerifyMonsterBuffer(verifier1), true);
|
||||
TEST_EQ(verifier1.GetComputedSize(), length);
|
||||
@@ -305,6 +307,15 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length,
|
||||
TEST_EQ_STR(nested_monster->name()->c_str(), "NestedMonster");
|
||||
}
|
||||
|
||||
// Test flexbuffer if available:
|
||||
auto flex = monster->flex();
|
||||
if (flex) {
|
||||
// flex is a vector of bytes you can memcpy. However, if you
|
||||
// actually want to access the nested data, this is a convenient
|
||||
// accessor that directly gives you the root value:
|
||||
TEST_EQ(monster->flex_flexbuffer_root().AsInt16(), 1234);
|
||||
}
|
||||
|
||||
// Since Flatbuffers uses explicit mechanisms to override the default
|
||||
// compiler alignment, double check that the compiler indeed obeys them:
|
||||
// (Test consists of a short and byte):
|
||||
|
||||
Reference in New Issue
Block a user