From afa276288c8db9a983aa8ae134328b1b447bec70 Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Wed, 15 Jun 2016 12:10:01 -0700 Subject: [PATCH] Added additional convenience overloads to CreateVector(). Bug: 29337887, 29336299 Change-Id: Iad8b3b2263f6cea7ee7e45994369194960df293b Tested: on Linux. --- docs/source/Tutorial.md | 10 ++++- include/flatbuffers/flatbuffers.h | 55 +++++++++++++++++++++------ tests/MyGame/Example/Monster.cs | 7 +++- tests/MyGame/Example/Monster.go | 22 ++++++++++- tests/MyGame/Example/Monster.java | 7 +++- tests/MyGame/Example/Monster.php | 60 ++++++++++++++++++++++++++++-- tests/MyGame/Example/Monster.py | 19 +++++++++- tests/monster_test.fbs | 1 + tests/monster_test_generated.h | 19 +++++++--- tests/monster_test_generated.js | 49 +++++++++++++++++++++++- tests/monsterdata_test.mon | Bin 384 -> 384 bytes tests/test.cpp | 29 +++++++++++---- 12 files changed, 244 insertions(+), 34 deletions(-) diff --git a/docs/source/Tutorial.md b/docs/source/Tutorial.md index 1e48796d9..6f6ac9a51 100644 --- a/docs/source/Tutorial.md +++ b/docs/source/Tutorial.md @@ -790,6 +790,14 @@ offsets. ~~~ +
+
+Note there's additional convenience overloads of `CreateVector`, allowing you +to work with data that's not in a `std::vector`, or allowing you to generate +elements by calling a lambda. For the common case of `std::vector` +there's also `CreateVectorOfStrings`. +
+ To create a `struct`, use the `Vec3` class/struct that was generated by the schema compiler: @@ -1075,7 +1083,7 @@ Here is a repetition these lines, to help highlight them more clearly:
~~~{.c} // Add union type and data simultanously. - ns(Monster_equipped_Weapon_add(B, axe)); + ns(Monster_equipped_Weapon_add(B, axe)); ~~~
diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index ff83da6d2..ae50d57d6 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -36,16 +36,17 @@ (!defined(_MSC_VER) || _MSC_VER < 1600) && \ (!defined(__GNUC__) || \ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400)) - #error A C++11 compatible compiler with support for the auto typing is required for FlatBuffers. + #error A C++11 compatible compiler with support for the auto typing is \ + required for FlatBuffers. #error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ #endif #if !defined(__clang__) && \ defined(__GNUC__) && \ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600) - // Backwards compatability for g++ 4.4, and 4.5 which don't have the nullptr and constexpr - // keywords. Note the __clang__ check is needed, because clang presents itself as an older GNUC - // compiler. + // Backwards compatability for g++ 4.4, and 4.5 which don't have the nullptr + // and constexpr keywords. Note the __clang__ check is needed, because clang + // presents itself as an older GNUC compiler. #ifndef nullptr_t const class nullptr_t { public: @@ -983,6 +984,33 @@ FLATBUFFERS_FINAL_CLASS return CreateVector(v.data(), v.size()); } + /// @brief Serialize values returned by a function into a FlatBuffer `vector`. + /// This is a convenience function that takes care of iteration for you. + /// @tparam T The data type of the `std::vector` elements. + /// @param f A function that takes the current iteration 0..vector_size-1 and + /// returns any type that you can construct a FlatBuffers vector out of. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template Offset> CreateVector(size_t vector_size, + const std::function &f) { + std::vector elems(vector_size); + for (size_t i = 0; i < vector_size; i++) elems[i] = f(i); + return CreateVector(elems.data(), elems.size()); + } + + /// @brief Serialize a `std::vector` into a FlatBuffer `vector`. + /// This is a convenience function for a common case. + /// @param v A const reference to the `std::vector` to serialize into the + /// buffer as a `vector`. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + Offset>> CreateVectorOfStrings( + const std::vector &v) { + std::vector> offsets(v.size()); + for (size_t i = 0; i < v.size(); i++) offsets[i] = CreateString(v[i]); + return CreateVector(offsets.data(), offsets.size()); + } + /// @brief Serialize an array of structs into a FlatBuffer `vector`. /// @tparam T The data type of the struct array elements. /// @param[in] v A pointer to the array of type `T` to serialize into the @@ -991,7 +1019,7 @@ FLATBUFFERS_FINAL_CLASS /// @return Returns a typed `Offset` into the serialized data indicating /// where the vector is stored. template Offset> CreateVectorOfStructs( - const T *v, size_t len) { + const T *v, size_t len) { StartVector(len * sizeof(T) / AlignOf(), AlignOf()); PushBytes(reinterpret_cast(v), sizeof(T) * len); return Offset>(EndVector(len)); @@ -1004,7 +1032,7 @@ FLATBUFFERS_FINAL_CLASS /// @return Returns a typed `Offset` into the serialized data indicating /// where the vector is stored. template Offset> CreateVectorOfStructs( - const std::vector &v) { + const std::vector &v) { return CreateVectorOfStructs(v.data(), v.size()); } @@ -1033,7 +1061,7 @@ FLATBUFFERS_FINAL_CLASS /// @return Returns a typed `Offset` into the serialized data indicating /// where the vector is stored. template Offset>> CreateVectorOfSortedTables( - Offset *v, size_t len) { + Offset *v, size_t len) { std::sort(v, v + len, TableKeyComparator(buf_)); return CreateVector(v, len); } @@ -1046,7 +1074,7 @@ FLATBUFFERS_FINAL_CLASS /// @return Returns a typed `Offset` into the serialized data indicating /// where the vector is stored. template Offset>> CreateVectorOfSortedTables( - std::vector> *v) { + std::vector> *v) { return CreateVectorOfSortedTables(v->data(), v->size()); } @@ -1077,7 +1105,7 @@ FLATBUFFERS_FINAL_CLASS /// written to at a later time to serialize the data into a `vector` /// in the buffer. template Offset> CreateUninitializedVector( - size_t len, T **buf) { + size_t len, T **buf) { return CreateUninitializedVector(len, sizeof(T), reinterpret_cast(buf)); } @@ -1162,13 +1190,16 @@ template const T *GetRoot(const void *buf) { } /// Helpers to get a typed pointer to objects that are currently beeing built. -/// @warning Creating new objects will lead to reallocations and invalidates the pointer! -template T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset offset) { +/// @warning Creating new objects will lead to reallocations and invalidates +/// the pointer! +template T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, + Offset offset) { return reinterpret_cast(fbb.GetCurrentBufferPointer() + fbb.GetSize() - offset.o); } -template const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset offset) { +template const T *GetTemporaryPointer(FlatBufferBuilder &fbb, + Offset offset) { return GetMutableTemporaryPointer(fbb, offset); } diff --git a/tests/MyGame/Example/Monster.cs b/tests/MyGame/Example/Monster.cs index 6101f464c..fdfd2b0a3 100644 --- a/tests/MyGame/Example/Monster.cs +++ b/tests/MyGame/Example/Monster.cs @@ -78,8 +78,10 @@ public sealed class Monster : Table { public bool MutateTestf2(float testf2) { int o = __offset(56); if (o != 0) { bb.PutFloat(o + bb_pos, testf2); return true; } else { return false; } } public float Testf3 { get { int o = __offset(58); return o != 0 ? bb.GetFloat(o + bb_pos) : (float)0.0f; } } public bool MutateTestf3(float testf3) { int o = __offset(58); if (o != 0) { bb.PutFloat(o + bb_pos, testf3); return true; } else { return false; } } + public string GetTestarrayofstring2(int j) { int o = __offset(60); return o != 0 ? __string(__vector(o) + j * 4) : null; } + public int Testarrayofstring2Length { get { int o = __offset(60); return o != 0 ? __vector_len(o) : 0; } } - public static void StartMonster(FlatBufferBuilder builder) { builder.StartObject(28); } + public static void StartMonster(FlatBufferBuilder builder) { builder.StartObject(29); } public static void AddPos(FlatBufferBuilder builder, Offset 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); } @@ -118,6 +120,9 @@ public sealed class Monster : Table { public static void AddTestf(FlatBufferBuilder builder, float testf) { builder.AddFloat(25, testf, 3.14159f); } public static void AddTestf2(FlatBufferBuilder builder, float testf2) { builder.AddFloat(26, testf2, 3.0f); } public static void AddTestf3(FlatBufferBuilder builder, float testf3) { builder.AddFloat(27, testf3, 0.0f); } + public static void AddTestarrayofstring2(FlatBufferBuilder builder, VectorOffset testarrayofstring2Offset) { builder.AddOffset(28, testarrayofstring2Offset.Value, 0); } + public static VectorOffset CreateTestarrayofstring2Vector(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); } + public static void StartTestarrayofstring2Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); } public static Offset EndMonster(FlatBufferBuilder builder) { int o = builder.EndObject(); builder.Required(o, 10); // name diff --git a/tests/MyGame/Example/Monster.go b/tests/MyGame/Example/Monster.go index fbd849e81..0c42f45a5 100644 --- a/tests/MyGame/Example/Monster.go +++ b/tests/MyGame/Example/Monster.go @@ -337,7 +337,24 @@ func (rcv *Monster) Testf3() float32 { return 0.0 } -func MonsterStart(builder *flatbuffers.Builder) { builder.StartObject(28) } +func (rcv *Monster) Testarrayofstring2(j int) []byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(60)) + if o != 0 { + a := rcv._tab.Vector(o) + return rcv._tab.ByteVector(a + flatbuffers.UOffsetT(j * 4)) + } + return nil +} + +func (rcv *Monster) Testarrayofstring2Length() int { + o := flatbuffers.UOffsetT(rcv._tab.Offset(60)) + if o != 0 { + return rcv._tab.VectorLen(o) + } + return 0 +} + +func MonsterStart(builder *flatbuffers.Builder) { builder.StartObject(29) } func MonsterAddPos(builder *flatbuffers.Builder, pos flatbuffers.UOffsetT) { builder.PrependStructSlot(0, flatbuffers.UOffsetT(pos), 0) } func MonsterAddMana(builder *flatbuffers.Builder, mana int16) { builder.PrependInt16Slot(1, mana, 150) } func MonsterAddHp(builder *flatbuffers.Builder, hp int16) { builder.PrependInt16Slot(2, hp, 100) } @@ -377,4 +394,7 @@ func MonsterStartTestarrayofboolsVector(builder *flatbuffers.Builder, numElems i func MonsterAddTestf(builder *flatbuffers.Builder, testf float32) { builder.PrependFloat32Slot(25, testf, 3.14159) } func MonsterAddTestf2(builder *flatbuffers.Builder, testf2 float32) { builder.PrependFloat32Slot(26, testf2, 3.0) } func MonsterAddTestf3(builder *flatbuffers.Builder, testf3 float32) { builder.PrependFloat32Slot(27, testf3, 0.0) } +func MonsterAddTestarrayofstring2(builder *flatbuffers.Builder, testarrayofstring2 flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(28, flatbuffers.UOffsetT(testarrayofstring2), 0) } +func MonsterStartTestarrayofstring2Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems, 4) +} func MonsterEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() } diff --git a/tests/MyGame/Example/Monster.java b/tests/MyGame/Example/Monster.java index d85e4baac..bfd4be1c9 100644 --- a/tests/MyGame/Example/Monster.java +++ b/tests/MyGame/Example/Monster.java @@ -84,8 +84,10 @@ public final class Monster extends Table { public boolean mutateTestf2(float testf2) { int o = __offset(56); if (o != 0) { bb.putFloat(o + bb_pos, testf2); return true; } else { return false; } } public float testf3() { int o = __offset(58); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } public boolean mutateTestf3(float testf3) { int o = __offset(58); if (o != 0) { bb.putFloat(o + bb_pos, testf3); return true; } else { return false; } } + public String testarrayofstring2(int j) { int o = __offset(60); return o != 0 ? __string(__vector(o) + j * 4) : null; } + public int testarrayofstring2Length() { int o = __offset(60); return o != 0 ? __vector_len(o) : 0; } - public static void startMonster(FlatBufferBuilder builder) { builder.startObject(28); } + public static void startMonster(FlatBufferBuilder builder) { builder.startObject(29); } 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); } @@ -124,6 +126,9 @@ public final class Monster extends Table { public static void addTestf(FlatBufferBuilder builder, float testf) { builder.addFloat(25, testf, 3.14159f); } public static void addTestf2(FlatBufferBuilder builder, float testf2) { builder.addFloat(26, testf2, 3.0f); } public static void addTestf3(FlatBufferBuilder builder, float testf3) { builder.addFloat(27, testf3, 0.0f); } + public static void addTestarrayofstring2(FlatBufferBuilder builder, int testarrayofstring2Offset) { builder.addOffset(28, testarrayofstring2Offset, 0); } + public static int createTestarrayofstring2Vector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } + public static void startTestarrayofstring2Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endMonster(FlatBufferBuilder builder) { int o = builder.endObject(); builder.required(o, 10); // name diff --git a/tests/MyGame/Example/Monster.php b/tests/MyGame/Example/Monster.php index 9f82d5a9c..c06cffbc6 100644 --- a/tests/MyGame/Example/Monster.php +++ b/tests/MyGame/Example/Monster.php @@ -360,22 +360,41 @@ class Monster extends Table return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : 0.0; } + /** + * @param int offset + * @return string + */ + public function getTestarrayofstring2($j) + { + $o = $this->__offset(60); + return $o != 0 ? $this->__string($this->__vector($o) + $j * 4) : 0; + } + + /** + * @return int + */ + public function getTestarrayofstring2Length() + { + $o = $this->__offset(60); + return $o != 0 ? $this->__vector_len($o) : 0; + } + /** * @param FlatBufferBuilder $builder * @return void */ public static function startMonster(FlatBufferBuilder $builder) { - $builder->StartObject(28); + $builder->StartObject(29); } /** * @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) + 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) { - $builder->startObject(28); + $builder->startObject(29); self::addPos($builder, $pos); self::addMana($builder, $mana); self::addHp($builder, $hp); @@ -403,6 +422,7 @@ class Monster extends Table self::addTestf($builder, $testf); self::addTestf2($builder, $testf2); self::addTestf3($builder, $testf3); + self::addTestarrayofstring2($builder, $testarrayofstring2); $o = $builder->endObject(); $builder->required($o, 10); // name return $o; @@ -817,6 +837,40 @@ class Monster extends Table $builder->addFloatX(27, $testf3, 0.0); } + /** + * @param FlatBufferBuilder $builder + * @param VectorOffset + * @return void + */ + public static function addTestarrayofstring2(FlatBufferBuilder $builder, $testarrayofstring2) + { + $builder->addOffsetX(28, $testarrayofstring2, 0); + } + + /** + * @param FlatBufferBuilder $builder + * @param array offset array + * @return int vector offset + */ + public static function createTestarrayofstring2Vector(FlatBufferBuilder $builder, array $data) + { + $builder->startVector(4, count($data), 4); + for ($i = count($data) - 1; $i >= 0; $i--) { + $builder->addOffset($data[$i]); + } + return $builder->endVector(); + } + + /** + * @param FlatBufferBuilder $builder + * @param int $numElems + * @return void + */ + public static function startTestarrayofstring2Vector(FlatBufferBuilder $builder, $numElems) + { + $builder->startVector(4, $numElems, 4); + } + /** * @param FlatBufferBuilder $builder * @return int table offset diff --git a/tests/MyGame/Example/Monster.py b/tests/MyGame/Example/Monster.py index 4f1ca2dfa..9d2909e89 100644 --- a/tests/MyGame/Example/Monster.py +++ b/tests/MyGame/Example/Monster.py @@ -283,7 +283,22 @@ class Monster(object): return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos) return 0.0 -def MonsterStart(builder): builder.StartObject(28) + # Monster + def Testarrayofstring2(self, j): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60)) + if o != 0: + a = self._tab.Vector(o) + return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4)) + return "" + + # Monster + def Testarrayofstring2Length(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60)) + if o != 0: + return self._tab.VectorLen(o) + return 0 + +def MonsterStart(builder): builder.StartObject(29) 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) @@ -317,4 +332,6 @@ def MonsterStartTestarrayofboolsVector(builder, numElems): return builder.StartV def MonsterAddTestf(builder, testf): builder.PrependFloat32Slot(25, testf, 3.14159) def MonsterAddTestf2(builder, testf2): builder.PrependFloat32Slot(26, testf2, 3.0) def MonsterAddTestf3(builder, testf3): builder.PrependFloat32Slot(27, testf3, 0.0) +def MonsterAddTestarrayofstring2(builder, testarrayofstring2): builder.PrependUOffsetTRelativeSlot(28, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofstring2), 0) +def MonsterStartTestarrayofstring2Vector(builder, numElems): return builder.StartVector(4, numElems, 4) def MonsterEnd(builder): return builder.EndObject() diff --git a/tests/monster_test.fbs b/tests/monster_test.fbs index f302ce444..08e72d4a5 100755 --- a/tests/monster_test.fbs +++ b/tests/monster_test.fbs @@ -44,6 +44,7 @@ table Monster { /// multiline too testarrayoftables:[Monster] (id: 11); testarrayofstring:[string] (id: 10); + testarrayofstring2:[string] (id: 28); testarrayofbools:[bool] (id: 24); enemy:MyGame.Example.Monster (id:12); // Test referring by full namespace. test:Any (id: 8); diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h index 594c6f7c8..60abbdecd 100644 --- a/tests/monster_test_generated.h +++ b/tests/monster_test_generated.h @@ -22,8 +22,8 @@ enum Color { Color_Red = 1, Color_Green = 2, Color_Blue = 8, - Color_MIN = Color_Red, - Color_MAX = Color_Blue + Color_NONE = 0, + Color_ANY = 11 }; inline const char **EnumNamesColor() { @@ -206,7 +206,8 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_TESTARRAYOFBOOLS = 52, VT_TESTF = 54, VT_TESTF2 = 56, - VT_TESTF3 = 58 + VT_TESTF3 = 58, + VT_TESTARRAYOFSTRING2 = 60 }; const Vec3 *pos() const { return GetStruct(VT_POS); } Vec3 *mutable_pos() { return GetStruct(VT_POS); } @@ -267,6 +268,8 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { bool mutate_testf2(float _testf2) { return SetField(VT_TESTF2, _testf2); } float testf3() const { return GetField(VT_TESTF3, 0.0f); } bool mutate_testf3(float _testf3) { return SetField(VT_TESTF3, _testf3); } + const flatbuffers::Vector> *testarrayofstring2() const { return GetPointer> *>(VT_TESTARRAYOFSTRING2); } + flatbuffers::Vector> *mutable_testarrayofstring2() { return GetPointer> *>(VT_TESTARRAYOFSTRING2); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_POS) && @@ -308,6 +311,9 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField(verifier, VT_TESTF) && VerifyField(verifier, VT_TESTF2) && VerifyField(verifier, VT_TESTF3) && + VerifyField(verifier, VT_TESTARRAYOFSTRING2) && + verifier.Verify(testarrayofstring2()) && + verifier.VerifyVectorOfStrings(testarrayofstring2()) && verifier.EndTable(); } }; @@ -342,10 +348,11 @@ struct MonsterBuilder { void add_testf(float testf) { fbb_.AddElement(Monster::VT_TESTF, testf, 3.14159f); } void add_testf2(float testf2) { fbb_.AddElement(Monster::VT_TESTF2, testf2, 3.0f); } void add_testf3(float testf3) { fbb_.AddElement(Monster::VT_TESTF3, testf3, 0.0f); } + void add_testarrayofstring2(flatbuffers::Offset>> testarrayofstring2) { fbb_.AddOffset(Monster::VT_TESTARRAYOFSTRING2, testarrayofstring2); } MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } MonsterBuilder &operator=(const MonsterBuilder &); flatbuffers::Offset Finish() { - auto o = flatbuffers::Offset(fbb_.EndTable(start_, 28)); + auto o = flatbuffers::Offset(fbb_.EndTable(start_, 29)); fbb_.Required(o, Monster::VT_NAME); // name return o; } @@ -378,12 +385,14 @@ inline flatbuffers::Offset CreateMonster(flatbuffers::FlatBufferBuilder flatbuffers::Offset> testarrayofbools = 0, float testf = 3.14159f, float testf2 = 3.0f, - float testf3 = 0.0f) { + float testf3 = 0.0f, + flatbuffers::Offset>> testarrayofstring2 = 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_testarrayofstring2(testarrayofstring2); builder_.add_testf3(testf3); builder_.add_testf2(testf2); builder_.add_testf(testf); diff --git a/tests/monster_test_generated.js b/tests/monster_test_generated.js index 8316fbc69..f967b9d83 100644 --- a/tests/monster_test_generated.js +++ b/tests/monster_test_generated.js @@ -701,11 +701,29 @@ MyGame.Example.Monster.prototype.testf3 = function() { return offset ? this.bb.readFloat32(this.bb_pos + offset) : 0.0; }; +/** + * @param {number} index + * @param {flatbuffers.Encoding=} optionalEncoding + * @returns {string|Uint8Array} + */ +MyGame.Example.Monster.prototype.testarrayofstring2 = function(index, optionalEncoding) { + var offset = this.bb.__offset(this.bb_pos, 60); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; +}; + +/** + * @returns {number} + */ +MyGame.Example.Monster.prototype.testarrayofstring2Length = function() { + var offset = this.bb.__offset(this.bb_pos, 60); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; +}; + /** * @param {flatbuffers.Builder} builder */ MyGame.Example.Monster.startMonster = function(builder) { - builder.startObject(28); + builder.startObject(29); }; /** @@ -1037,6 +1055,35 @@ MyGame.Example.Monster.addTestf3 = function(builder, testf3) { builder.addFieldFloat32(27, testf3, 0.0); }; +/** + * @param {flatbuffers.Builder} builder + * @param {flatbuffers.Offset} testarrayofstring2Offset + */ +MyGame.Example.Monster.addTestarrayofstring2 = function(builder, testarrayofstring2Offset) { + builder.addFieldOffset(28, testarrayofstring2Offset, 0); +}; + +/** + * @param {flatbuffers.Builder} builder + * @param {Array.} data + * @returns {flatbuffers.Offset} + */ +MyGame.Example.Monster.createTestarrayofstring2Vector = function(builder, data) { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); +}; + +/** + * @param {flatbuffers.Builder} builder + * @param {number} numElems + */ +MyGame.Example.Monster.startTestarrayofstring2Vector = function(builder, numElems) { + builder.startVector(4, numElems, 4); +}; + /** * @param {flatbuffers.Builder} builder * @returns {flatbuffers.Offset} diff --git a/tests/monsterdata_test.mon b/tests/monsterdata_test.mon index 7a7fbf707f84e8b7ef957001da0ce8b3d9a89324..01bd5279453ac6fd4e290c1d5a3b8537275d9619 100644 GIT binary patch delta 156 zcmZo*ZeaHGU|?YI_4f;AV6bDTVc-Dr*cfzxqyZ4KGMF$}FxUWD4nPb7E({(F5ex|o zJ`4d284LvsArN68X*bbRTl5c*@dk*m0C5Wt#{jX*#EHU;8WWc)^8z^x%s|Wtgu5nQ cbOs98fo%jyuuN8D)Sqm?$iiqhIgn8w05${_r~m)} delta 171 zcmZo*ZeaHGU|?YI_4f+~QVcc>4GbJWnvKB(NLm0fD^SdV!3D?ysRIEYh5&{Hh75)f zh6siNh6;ulh%kfAL{Du)D4XF6knseF&j4`)5Jv#90}wl&th@`tg-aUyKv-qsTxCvX gpadfj?wNSjncD{J0H6p1%Vb4HeW0Ap strings[4]; - strings[0] = builder.CreateSharedString("bob"); - strings[1] = builder.CreateSharedString("fred"); - strings[2] = builder.CreateSharedString("bob"); - strings[3] = builder.CreateSharedString("fred"); - auto vecofstrings = builder.CreateVector(strings, 4); + // Create an array of strings. Also test string pooling, and lambdas. + const char *names[] = { "bob", "fred", "bob", "fred" }; + auto vecofstrings = + builder.CreateVector>(4, + [&](size_t i) { + return builder.CreateSharedString(names[i]); + }); + + // Creating vectors of strings in one convenient call. + std::vector names2 = { "jane", "mary" }; + auto vecofstrings2 = builder.CreateVectorOfStrings(names2); // Create an array of sorted tables, can be used with binary search when read: auto vecoftables = builder.CreateVectorOfSortedTables(mlocs, 3); @@ -128,7 +132,9 @@ flatbuffers::unique_ptr_t CreateFlatBufferTest(std::string &buffer) { // 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); + testv, vecofstrings, vecoftables, 0, 0, 0, false, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.14159f, 3.0f, 0.0f, + vecofstrings2); FinishMonsterBuffer(builder, mloc); @@ -198,6 +204,13 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length) { TEST_EQ(vecofstrings->Get(0)->c_str(), vecofstrings->Get(2)->c_str()); TEST_EQ(vecofstrings->Get(1)->c_str(), vecofstrings->Get(3)->c_str()); + auto vecofstrings2 = monster->testarrayofstring2(); + if (vecofstrings2) { + TEST_EQ(vecofstrings2->Length(), 2U); + TEST_EQ_STR(vecofstrings2->Get(0)->c_str(), "jane"); + TEST_EQ_STR(vecofstrings2->Get(1)->c_str(), "mary"); + } + // Example of accessing a vector of tables: auto vecoftables = monster->testarrayoftables(); TEST_EQ(vecoftables->Length(), 3U);