diff options
author | Vladimir Glavnyy <31897320+vglavnyy@users.noreply.github.com> | 2021-01-08 02:24:59 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-07 11:24:59 -0800 |
commit | 83ce29cc22cc80546b38e94e59f95f9a72fc1c6d (patch) | |
tree | 9089380f0fc76c50e65ee6564a4eb6ba56c79fb1 /tests/MyGame/Example | |
parent | 4363c1d2cb898768073128bb92db9d4c63b43300 (diff) | |
download | flatbuffers-83ce29cc22cc80546b38e94e59f95f9a72fc1c6d.tar.gz flatbuffers-83ce29cc22cc80546b38e94e59f95f9a72fc1c6d.tar.bz2 flatbuffers-83ce29cc22cc80546b38e94e59f95f9a72fc1c6d.zip |
[C++, JSON] Fix nullptr access when reading a key with a default value. (#6375)
This commit fixes handling of default and NULL `key` fields in `Parser::ParseVector` (#5928).
The JSON generator updated. It outputs `key` fields even if the `--force-defaults` option is inactive.
Additional test cases for `key` added.
Diffstat (limited to 'tests/MyGame/Example')
-rw-r--r-- | tests/MyGame/Example/Monster.cs | 29 | ||||
-rw-r--r-- | tests/MyGame/Example/Monster.go | 50 | ||||
-rw-r--r-- | tests/MyGame/Example/Monster.java | 12 | ||||
-rw-r--r-- | tests/MyGame/Example/Monster.kt | 40 | ||||
-rw-r--r-- | tests/MyGame/Example/Monster.lua | 22 | ||||
-rw-r--r-- | tests/MyGame/Example/Monster.php | 60 | ||||
-rw-r--r-- | tests/MyGame/Example/Monster.py | 48 | ||||
-rw-r--r-- | tests/MyGame/Example/Stat.cs | 25 | ||||
-rw-r--r-- | tests/MyGame/Example/Stat.java | 30 | ||||
-rw-r--r-- | tests/MyGame/Example/Stat.kt | 27 |
10 files changed, 331 insertions, 12 deletions
diff --git a/tests/MyGame/Example/Monster.cs b/tests/MyGame/Example/Monster.cs index acfb3943..12a43576 100644 --- a/tests/MyGame/Example/Monster.cs +++ b/tests/MyGame/Example/Monster.cs @@ -207,6 +207,9 @@ public struct Monster : IFlatbufferObject public byte[] GetTestrequirednestedflatbufferArray() { return __p.__vector_as_array<byte>(102); } public MyGame.Example.Monster? GetTestrequirednestedflatbufferAsMonster() { int o = __p.__offset(102); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(__p.__vector(o)), __p.bb) : null; } public bool MutateTestrequirednestedflatbuffer(int j, byte testrequirednestedflatbuffer) { int o = __p.__offset(102); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, testrequirednestedflatbuffer); return true; } else { return false; } } + public MyGame.Example.Stat? ScalarKeySortedTables(int j) { int o = __p.__offset(104); return o != 0 ? (MyGame.Example.Stat?)(new MyGame.Example.Stat()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; } + public int ScalarKeySortedTablesLength { get { int o = __p.__offset(104); return o != 0 ? __p.__vector_len(o) : 0; } } + public MyGame.Example.Stat? ScalarKeySortedTablesByKey(ushort key) { int o = __p.__offset(104); return o != 0 ? MyGame.Example.Stat.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; } public static Offset<MyGame.Example.Monster> CreateMonster(FlatBufferBuilder builder, MyGame.Example.Vec3T pos = null, @@ -257,8 +260,9 @@ public struct Monster : IFlatbufferObject int any_ambiguousOffset = 0, VectorOffset vector_of_enumsOffset = default(VectorOffset), MyGame.Example.Race signed_enum = MyGame.Example.Race.None, - VectorOffset testrequirednestedflatbufferOffset = default(VectorOffset)) { - builder.StartTable(50); + VectorOffset testrequirednestedflatbufferOffset = default(VectorOffset), + VectorOffset scalar_key_sorted_tablesOffset = default(VectorOffset)) { + builder.StartTable(51); Monster.AddNonOwningReference(builder, non_owning_reference); Monster.AddCoOwningReference(builder, co_owning_reference); Monster.AddSingleWeakReference(builder, single_weak_reference); @@ -266,6 +270,7 @@ public struct Monster : IFlatbufferObject Monster.AddTesthashs64Fnv1a(builder, testhashs64_fnv1a); Monster.AddTesthashu64Fnv1(builder, testhashu64_fnv1); Monster.AddTesthashs64Fnv1(builder, testhashs64_fnv1); + Monster.AddScalarKeySortedTables(builder, scalar_key_sorted_tablesOffset); Monster.AddTestrequirednestedflatbuffer(builder, testrequirednestedflatbufferOffset); Monster.AddVectorOfEnums(builder, vector_of_enumsOffset); Monster.AddAnyAmbiguous(builder, any_ambiguousOffset); @@ -311,7 +316,7 @@ public struct Monster : IFlatbufferObject return Monster.EndMonster(builder); } - public static void StartMonster(FlatBufferBuilder builder) { builder.StartTable(50); } + public static void StartMonster(FlatBufferBuilder builder) { builder.StartTable(51); } public static void AddPos(FlatBufferBuilder builder, Offset<MyGame.Example.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); } @@ -412,6 +417,10 @@ public struct Monster : IFlatbufferObject public static VectorOffset CreateTestrequirednestedflatbufferVector(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 VectorOffset CreateTestrequirednestedflatbufferVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); } public static void StartTestrequirednestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); } + public static void AddScalarKeySortedTables(FlatBufferBuilder builder, VectorOffset scalarKeySortedTablesOffset) { builder.AddOffset(50, scalarKeySortedTablesOffset.Value, 0); } + public static VectorOffset CreateScalarKeySortedTablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.Stat>[] 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 VectorOffset CreateScalarKeySortedTablesVectorBlock(FlatBufferBuilder builder, Offset<MyGame.Example.Stat>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); } + public static void StartScalarKeySortedTablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); } public static Offset<MyGame.Example.Monster> EndMonster(FlatBufferBuilder builder) { int o = builder.EndTable(); builder.Required(o, 10); // name @@ -555,6 +564,8 @@ public struct Monster : IFlatbufferObject _o.SignedEnum = this.SignedEnum; _o.Testrequirednestedflatbuffer = new List<byte>(); for (var _j = 0; _j < this.TestrequirednestedflatbufferLength; ++_j) {_o.Testrequirednestedflatbuffer.Add(this.Testrequirednestedflatbuffer(_j));} + _o.ScalarKeySortedTables = new List<MyGame.Example.StatT>(); + for (var _j = 0; _j < this.ScalarKeySortedTablesLength; ++_j) {_o.ScalarKeySortedTables.Add(this.ScalarKeySortedTables(_j).HasValue ? this.ScalarKeySortedTables(_j).Value.UnPack() : null);} } public static Offset<MyGame.Example.Monster> Pack(FlatBufferBuilder builder, MonsterT _o) { if (_o == null) return default(Offset<MyGame.Example.Monster>); @@ -671,6 +682,12 @@ public struct Monster : IFlatbufferObject var __testrequirednestedflatbuffer = _o.Testrequirednestedflatbuffer.ToArray(); _testrequirednestedflatbuffer = CreateTestrequirednestedflatbufferVector(builder, __testrequirednestedflatbuffer); } + var _scalar_key_sorted_tables = default(VectorOffset); + if (_o.ScalarKeySortedTables != null) { + var __scalar_key_sorted_tables = new Offset<MyGame.Example.Stat>[_o.ScalarKeySortedTables.Count]; + for (var _j = 0; _j < __scalar_key_sorted_tables.Length; ++_j) { __scalar_key_sorted_tables[_j] = MyGame.Example.Stat.Pack(builder, _o.ScalarKeySortedTables[_j]); } + _scalar_key_sorted_tables = CreateScalarKeySortedTablesVector(builder, __scalar_key_sorted_tables); + } return CreateMonster( builder, _o.Pos, @@ -721,7 +738,8 @@ public struct Monster : IFlatbufferObject _any_ambiguous, _vector_of_enums, _o.SignedEnum, - _testrequirednestedflatbuffer); + _testrequirednestedflatbuffer, + _scalar_key_sorted_tables); } }; @@ -866,6 +884,8 @@ public class MonsterT public MyGame.Example.Race SignedEnum { get; set; } [Newtonsoft.Json.JsonProperty("testrequirednestedflatbuffer")] public List<byte> Testrequirednestedflatbuffer { get; set; } + [Newtonsoft.Json.JsonProperty("scalar_key_sorted_tables")] + public List<MyGame.Example.StatT> ScalarKeySortedTables { get; set; } public MonsterT() { this.Pos = new MyGame.Example.Vec3T(); @@ -914,6 +934,7 @@ public class MonsterT this.VectorOfEnums = null; this.SignedEnum = MyGame.Example.Race.None; this.Testrequirednestedflatbuffer = null; + this.ScalarKeySortedTables = null; } public static MonsterT DeserializeFromJson(string jsonText) { diff --git a/tests/MyGame/Example/Monster.go b/tests/MyGame/Example/Monster.go index 2ffe9264..4992d595 100644 --- a/tests/MyGame/Example/Monster.go +++ b/tests/MyGame/Example/Monster.go @@ -56,6 +56,7 @@ type MonsterT struct { VectorOfEnums []Color SignedEnum Race Testrequirednestedflatbuffer []byte + ScalarKeySortedTables []*StatT } func (t *MonsterT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { @@ -241,6 +242,19 @@ func (t *MonsterT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { if t.Testrequirednestedflatbuffer != nil { testrequirednestedflatbufferOffset = builder.CreateByteString(t.Testrequirednestedflatbuffer) } + scalarKeySortedTablesOffset := flatbuffers.UOffsetT(0) + if t.ScalarKeySortedTables != nil { + scalarKeySortedTablesLength := len(t.ScalarKeySortedTables) + scalarKeySortedTablesOffsets := make([]flatbuffers.UOffsetT, scalarKeySortedTablesLength) + for j := 0; j < scalarKeySortedTablesLength; j++ { + scalarKeySortedTablesOffsets[j] = t.ScalarKeySortedTables[j].Pack(builder) + } + MonsterStartScalarKeySortedTablesVector(builder, scalarKeySortedTablesLength) + for j := scalarKeySortedTablesLength - 1; j >= 0; j-- { + builder.PrependUOffsetT(scalarKeySortedTablesOffsets[j]) + } + scalarKeySortedTablesOffset = builder.EndVector(scalarKeySortedTablesLength) + } MonsterStart(builder) posOffset := t.Pos.Pack(builder) MonsterAddPos(builder, posOffset) @@ -298,6 +312,7 @@ func (t *MonsterT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { MonsterAddVectorOfEnums(builder, vectorOfEnumsOffset) MonsterAddSignedEnum(builder, t.SignedEnum) MonsterAddTestrequirednestedflatbuffer(builder, testrequirednestedflatbufferOffset) + MonsterAddScalarKeySortedTables(builder, scalarKeySortedTablesOffset) return MonsterEnd(builder) } @@ -429,6 +444,13 @@ func (rcv *Monster) UnPackTo(t *MonsterT) { } t.SignedEnum = rcv.SignedEnum() t.Testrequirednestedflatbuffer = rcv.TestrequirednestedflatbufferBytes() + scalarKeySortedTablesLength := rcv.ScalarKeySortedTablesLength() + t.ScalarKeySortedTables = make([]*StatT, scalarKeySortedTablesLength) + for j := 0; j < scalarKeySortedTablesLength; j++ { + x := Stat{} + rcv.ScalarKeySortedTables(&x, j) + t.ScalarKeySortedTables[j] = x.UnPack() + } } func (rcv *Monster) UnPack() *MonsterT { @@ -1297,8 +1319,28 @@ func (rcv *Monster) MutateTestrequirednestedflatbuffer(j int, n byte) bool { return false } +func (rcv *Monster) ScalarKeySortedTables(obj *Stat, j int) bool { + o := flatbuffers.UOffsetT(rcv._tab.Offset(104)) + if o != 0 { + x := rcv._tab.Vector(o) + x += flatbuffers.UOffsetT(j) * 4 + x = rcv._tab.Indirect(x) + obj.Init(rcv._tab.Bytes, x) + return true + } + return false +} + +func (rcv *Monster) ScalarKeySortedTablesLength() int { + o := flatbuffers.UOffsetT(rcv._tab.Offset(104)) + if o != 0 { + return rcv._tab.VectorLen(o) + } + return 0 +} + func MonsterStart(builder *flatbuffers.Builder) { - builder.StartObject(50) + builder.StartObject(51) } func MonsterAddPos(builder *flatbuffers.Builder, pos flatbuffers.UOffsetT) { builder.PrependStructSlot(0, flatbuffers.UOffsetT(pos), 0) @@ -1504,6 +1546,12 @@ func MonsterAddTestrequirednestedflatbuffer(builder *flatbuffers.Builder, testre func MonsterStartTestrequirednestedflatbufferVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(1, numElems, 1) } +func MonsterAddScalarKeySortedTables(builder *flatbuffers.Builder, scalarKeySortedTables flatbuffers.UOffsetT) { + builder.PrependUOffsetTSlot(50, flatbuffers.UOffsetT(scalarKeySortedTables), 0) +} +func MonsterStartScalarKeySortedTablesVector(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 c3cd1ca3..41959581 100644 --- a/tests/MyGame/Example/Monster.java +++ b/tests/MyGame/Example/Monster.java @@ -203,8 +203,15 @@ public final class Monster extends Table { public MyGame.Example.Monster testrequirednestedflatbufferAsMonster() { return testrequirednestedflatbufferAsMonster(new MyGame.Example.Monster()); } public MyGame.Example.Monster testrequirednestedflatbufferAsMonster(MyGame.Example.Monster obj) { int o = __offset(102); return o != 0 ? obj.__assign(__indirect(__vector(o)), bb) : null; } public boolean mutateTestrequirednestedflatbuffer(int j, int testrequirednestedflatbuffer) { int o = __offset(102); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)testrequirednestedflatbuffer); return true; } else { return false; } } + public MyGame.Example.Stat scalarKeySortedTables(int j) { return scalarKeySortedTables(new MyGame.Example.Stat(), j); } + public MyGame.Example.Stat scalarKeySortedTables(MyGame.Example.Stat obj, int j) { int o = __offset(104); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public int scalarKeySortedTablesLength() { int o = __offset(104); return o != 0 ? __vector_len(o) : 0; } + public MyGame.Example.Stat scalarKeySortedTablesByKey(int key) { int o = __offset(104); return o != 0 ? MyGame.Example.Stat.__lookup_by_key(null, __vector(o), key, bb) : null; } + public MyGame.Example.Stat scalarKeySortedTablesByKey(MyGame.Example.Stat obj, int key) { int o = __offset(104); return o != 0 ? MyGame.Example.Stat.__lookup_by_key(obj, __vector(o), key, bb) : null; } + public MyGame.Example.Stat.Vector scalarKeySortedTablesVector() { return scalarKeySortedTablesVector(new MyGame.Example.Stat.Vector()); } + public MyGame.Example.Stat.Vector scalarKeySortedTablesVector(MyGame.Example.Stat.Vector obj) { int o = __offset(104); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; } - public static void startMonster(FlatBufferBuilder builder) { builder.startTable(50); } + public static void startMonster(FlatBufferBuilder builder) { builder.startTable(51); } 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); } @@ -294,6 +301,9 @@ public final class Monster extends Table { public static int createTestrequirednestedflatbufferVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); } public static int createTestrequirednestedflatbufferVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); } public static void startTestrequirednestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); } + public static void addScalarKeySortedTables(FlatBufferBuilder builder, int scalarKeySortedTablesOffset) { builder.addOffset(50, scalarKeySortedTablesOffset, 0); } + public static int createScalarKeySortedTablesVector(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 startScalarKeySortedTablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endMonster(FlatBufferBuilder builder) { int o = builder.endTable(); builder.required(o, 10); // name diff --git a/tests/MyGame/Example/Monster.kt b/tests/MyGame/Example/Monster.kt index 7b151386..0da3eea2 100644 --- a/tests/MyGame/Example/Monster.kt +++ b/tests/MyGame/Example/Monster.kt @@ -805,6 +805,35 @@ class Monster : Table() { false } } + fun scalarKeySortedTables(j: Int) : MyGame.Example.Stat? = scalarKeySortedTables(MyGame.Example.Stat(), j) + fun scalarKeySortedTables(obj: MyGame.Example.Stat, j: Int) : MyGame.Example.Stat? { + val o = __offset(104) + return if (o != 0) { + obj.__assign(__indirect(__vector(o) + j * 4), bb) + } else { + null + } + } + val scalarKeySortedTablesLength : Int + get() { + val o = __offset(104); return if (o != 0) __vector_len(o) else 0 + } + fun scalarKeySortedTablesByKey(key: UShort) : MyGame.Example.Stat? { + val o = __offset(104) + return if (o != 0) { + MyGame.Example.Stat.__lookup_by_key(null, __vector(o), key, bb) + } else { + null + } + } + fun scalarKeySortedTablesByKey(obj: MyGame.Example.Stat, key: UShort) : MyGame.Example.Stat? { + val o = __offset(104) + return if (o != 0) { + MyGame.Example.Stat.__lookup_by_key(obj, __vector(o), key, bb) + } else { + null + } + } override fun keysCompare(o1: Int, o2: Int, _bb: ByteBuffer) : Int { return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb) } @@ -816,7 +845,7 @@ class Monster : Table() { return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)) } fun MonsterBufferHasIdentifier(_bb: ByteBuffer) : Boolean = __has_identifier(_bb, "MONS") - fun startMonster(builder: FlatBufferBuilder) = builder.startTable(50) + fun startMonster(builder: FlatBufferBuilder) = builder.startTable(51) fun addPos(builder: FlatBufferBuilder, pos: Int) = builder.addStruct(0, pos, 0) fun addMana(builder: FlatBufferBuilder, mana: Short) = builder.addShort(1, mana, 150) fun addHp(builder: FlatBufferBuilder, hp: Short) = builder.addShort(2, hp, 100) @@ -997,6 +1026,15 @@ class Monster : Table() { return builder.endVector() } fun startTestrequirednestedflatbufferVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1) + fun addScalarKeySortedTables(builder: FlatBufferBuilder, scalarKeySortedTables: Int) = builder.addOffset(50, scalarKeySortedTables, 0) + fun createScalarKeySortedTablesVector(builder: FlatBufferBuilder, data: IntArray) : Int { + builder.startVector(4, data.size, 4) + for (i in data.size - 1 downTo 0) { + builder.addOffset(data[i]) + } + return builder.endVector() + } + fun startScalarKeySortedTablesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4) fun endMonster(builder: FlatBufferBuilder) : Int { val o = builder.endTable() builder.required(o, 10) diff --git a/tests/MyGame/Example/Monster.lua b/tests/MyGame/Example/Monster.lua index 78ae4a5d..6e520025 100644 --- a/tests/MyGame/Example/Monster.lua +++ b/tests/MyGame/Example/Monster.lua @@ -544,7 +544,25 @@ function Monster_mt:TestrequirednestedflatbufferLength() end return 0 end -function Monster.Start(builder) builder:StartObject(50) end +function Monster_mt:ScalarKeySortedTables(j) + local o = self.view:Offset(104) + if o ~= 0 then + local x = self.view:Vector(o) + x = x + ((j-1) * 4) + x = self.view:Indirect(x) + local obj = require('MyGame.Example.Stat').New() + obj:Init(self.view.bytes, x) + return obj + end +end +function Monster_mt:ScalarKeySortedTablesLength() + local o = self.view:Offset(104) + if o ~= 0 then + return self.view:VectorLen(o) + end + return 0 +end +function Monster.Start(builder) builder:StartObject(51) end function Monster.AddPos(builder, pos) builder:PrependStructSlot(0, pos, 0) end function Monster.AddMana(builder, mana) builder:PrependInt16Slot(1, mana, 150) end function Monster.AddHp(builder, hp) builder:PrependInt16Slot(2, hp, 100) end @@ -613,6 +631,8 @@ function Monster.StartVectorOfEnumsVector(builder, numElems) return builder:Star function Monster.AddSignedEnum(builder, signedEnum) builder:PrependInt8Slot(48, signedEnum, -1) end function Monster.AddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer) builder:PrependUOffsetTRelativeSlot(49, testrequirednestedflatbuffer, 0) end function Monster.StartTestrequirednestedflatbufferVector(builder, numElems) return builder:StartVector(1, numElems, 1) end +function Monster.AddScalarKeySortedTables(builder, scalarKeySortedTables) builder:PrependUOffsetTRelativeSlot(50, scalarKeySortedTables, 0) end +function Monster.StartScalarKeySortedTablesVector(builder, numElems) return builder:StartVector(4, numElems, 4) end function Monster.End(builder) return builder:EndObject() end return Monster -- return the module
\ No newline at end of file diff --git a/tests/MyGame/Example/Monster.php b/tests/MyGame/Example/Monster.php index 21e27dcf..17e2a678 100644 --- a/tests/MyGame/Example/Monster.php +++ b/tests/MyGame/Example/Monster.php @@ -711,21 +711,40 @@ class Monster extends Table } /** + * @returnVectorOffset + */ + public function getScalarKeySortedTables($j) + { + $o = $this->__offset(104); + $obj = new Stat(); + return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null; + } + + /** + * @return int + */ + public function getScalarKeySortedTablesLength() + { + $o = $this->__offset(104); + return $o != 0 ? $this->__vector_len($o) : 0; + } + + /** * @param FlatBufferBuilder $builder * @return void */ public static function startMonster(FlatBufferBuilder $builder) { - $builder->StartObject(50); + $builder->StartObject(51); } /** * @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, $flex, $test5, $vector_of_longs, $vector_of_doubles, $parent_namespace_test, $vector_of_referrables, $single_weak_reference, $vector_of_weak_references, $vector_of_strong_referrables, $co_owning_reference, $vector_of_co_owning_references, $non_owning_reference, $vector_of_non_owning_references, $any_unique_type, $any_unique, $any_ambiguous_type, $any_ambiguous, $vector_of_enums, $signed_enum, $testrequirednestedflatbuffer) + 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, $test5, $vector_of_longs, $vector_of_doubles, $parent_namespace_test, $vector_of_referrables, $single_weak_reference, $vector_of_weak_references, $vector_of_strong_referrables, $co_owning_reference, $vector_of_co_owning_references, $non_owning_reference, $vector_of_non_owning_references, $any_unique_type, $any_unique, $any_ambiguous_type, $any_ambiguous, $vector_of_enums, $signed_enum, $testrequirednestedflatbuffer, $scalar_key_sorted_tables) { - $builder->startObject(50); + $builder->startObject(51); self::addPos($builder, $pos); self::addMana($builder, $mana); self::addHp($builder, $hp); @@ -775,6 +794,7 @@ class Monster extends Table self::addVectorOfEnums($builder, $vector_of_enums); self::addSignedEnum($builder, $signed_enum); self::addTestrequirednestedflatbuffer($builder, $testrequirednestedflatbuffer); + self::addScalarKeySortedTables($builder, $scalar_key_sorted_tables); $o = $builder->endObject(); $builder->required($o, 10); // name return $o; @@ -1713,6 +1733,40 @@ class Monster extends Table /** * @param FlatBufferBuilder $builder + * @param VectorOffset + * @return void + */ + public static function addScalarKeySortedTables(FlatBufferBuilder $builder, $scalarKeySortedTables) + { + $builder->addOffsetX(50, $scalarKeySortedTables, 0); + } + + /** + * @param FlatBufferBuilder $builder + * @param array offset array + * @return int vector offset + */ + public static function createScalarKeySortedTablesVector(FlatBufferBuilder $builder, array $data) + { + $builder->startVector(4, count($data), 4); + for ($i = count($data) - 1; $i >= 0; $i--) { + $builder->putOffset($data[$i]); + } + return $builder->endVector(); + } + + /** + * @param FlatBufferBuilder $builder + * @param int $numElems + * @return void + */ + public static function startScalarKeySortedTablesVector(FlatBufferBuilder $builder, $numElems) + { + $builder->startVector(4, $numElems, 4); + } + + /** + * @param FlatBufferBuilder $builder * @return int table offset */ public static function endMonster(FlatBufferBuilder $builder) diff --git a/tests/MyGame/Example/Monster.py b/tests/MyGame/Example/Monster.py index 80840af2..7ebf6974 100644 --- a/tests/MyGame/Example/Monster.py +++ b/tests/MyGame/Example/Monster.py @@ -762,7 +762,32 @@ class Monster(object): o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102)) return o == 0 -def MonsterStart(builder): builder.StartObject(50) + # Monster + def ScalarKeySortedTables(self, j): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(104)) + if o != 0: + x = self._tab.Vector(o) + x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4 + x = self._tab.Indirect(x) + from MyGame.Example.Stat import Stat + obj = Stat() + obj.Init(self._tab.Bytes, x) + return obj + return None + + # Monster + def ScalarKeySortedTablesLength(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(104)) + if o != 0: + return self._tab.VectorLen(o) + return 0 + + # Monster + def ScalarKeySortedTablesIsNone(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(104)) + return o == 0 + +def MonsterStart(builder): builder.StartObject(51) 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) @@ -841,6 +866,8 @@ def MonsterMakeTestrequirednestedflatbufferVectorFromBytes(builder, bytes): builder.head = builder.head - len(bytes) builder.Bytes[builder.head : builder.head + len(bytes)] = bytes return builder.EndVector() +def MonsterAddScalarKeySortedTables(builder, scalarKeySortedTables): builder.PrependUOffsetTRelativeSlot(50, flatbuffers.number_types.UOffsetTFlags.py_type(scalarKeySortedTables), 0) +def MonsterStartScalarKeySortedTablesVector(builder, numElems): return builder.StartVector(4, numElems, 4) def MonsterEnd(builder): return builder.EndObject() import MyGame.Example.Ability @@ -912,6 +939,7 @@ class MonsterT(object): self.vectorOfEnums = None # type: List[int] self.signedEnum = -1 # type: int self.testrequirednestedflatbuffer = None # type: List[int] + self.scalarKeySortedTables = None # type: List[MyGame.Example.Stat.StatT] @classmethod def InitFromBuf(cls, buf, pos): @@ -1096,6 +1124,14 @@ class MonsterT(object): self.testrequirednestedflatbuffer.append(monster.Testrequirednestedflatbuffer(i)) else: self.testrequirednestedflatbuffer = monster.TestrequirednestedflatbufferAsNumpy() + if not monster.ScalarKeySortedTablesIsNone(): + self.scalarKeySortedTables = [] + for i in range(monster.ScalarKeySortedTablesLength()): + if monster.ScalarKeySortedTables(i) is None: + self.scalarKeySortedTables.append(None) + else: + stat_ = MyGame.Example.Stat.StatT.InitFromObj(monster.ScalarKeySortedTables(i)) + self.scalarKeySortedTables.append(stat_) # MonsterT def Pack(self, builder): @@ -1256,6 +1292,14 @@ class MonsterT(object): for i in reversed(range(len(self.testrequirednestedflatbuffer))): builder.PrependUint8(self.testrequirednestedflatbuffer[i]) testrequirednestedflatbuffer = builder.EndVector() + if self.scalarKeySortedTables is not None: + scalarKeySortedTableslist = [] + for i in range(len(self.scalarKeySortedTables)): + scalarKeySortedTableslist.append(self.scalarKeySortedTables[i].Pack(builder)) + MonsterStartScalarKeySortedTablesVector(builder, len(self.scalarKeySortedTables)) + for i in reversed(range(len(self.scalarKeySortedTables))): + builder.PrependUOffsetTRelative(scalarKeySortedTableslist[i]) + scalarKeySortedTables = builder.EndVector() MonsterStart(builder) if self.pos is not None: pos = self.pos.Pack(builder) @@ -1334,5 +1378,7 @@ class MonsterT(object): MonsterAddSignedEnum(builder, self.signedEnum) if self.testrequirednestedflatbuffer is not None: MonsterAddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer) + if self.scalarKeySortedTables is not None: + MonsterAddScalarKeySortedTables(builder, scalarKeySortedTables) monster = MonsterEnd(builder) return monster diff --git a/tests/MyGame/Example/Stat.cs b/tests/MyGame/Example/Stat.cs index 6f19ed40..07c22da7 100644 --- a/tests/MyGame/Example/Stat.cs +++ b/tests/MyGame/Example/Stat.cs @@ -50,6 +50,31 @@ public struct Stat : IFlatbufferObject int o = builder.EndTable(); return new Offset<MyGame.Example.Stat>(o); } + + public static VectorOffset CreateSortedVectorOfStat(FlatBufferBuilder builder, Offset<Stat>[] offsets) { + Array.Sort(offsets, (Offset<Stat> o1, Offset<Stat> o2) => builder.DataBuffer.GetUshort(Table.__offset(8, o1.Value, builder.DataBuffer)).CompareTo(builder.DataBuffer.GetUshort(Table.__offset(8, o2.Value, builder.DataBuffer)))); + return builder.CreateVectorOfTables(offsets); + } + + public static Stat? __lookup_by_key(int vectorLocation, ushort key, ByteBuffer bb) { + int span = bb.GetInt(vectorLocation - 4); + int start = 0; + while (span != 0) { + int middle = span / 2; + int tableOffset = Table.__indirect(vectorLocation + 4 * (start + middle), bb); + int comp = bb.GetUshort(Table.__offset(8, bb.Length - tableOffset, bb)).CompareTo(key); + if (comp > 0) { + span = middle; + } else if (comp < 0) { + middle++; + start += middle; + span -= middle; + } else { + return new Stat().__assign(tableOffset, bb); + } + } + return null; + } public StatT UnPack() { var _o = new StatT(); this.UnPackTo(_o); diff --git a/tests/MyGame/Example/Stat.java b/tests/MyGame/Example/Stat.java index 116c2111..75d74b9a 100644 --- a/tests/MyGame/Example/Stat.java +++ b/tests/MyGame/Example/Stat.java @@ -43,11 +43,41 @@ public final class Stat extends Table { return o; } + @Override + protected int keysCompare(Integer o1, Integer o2, ByteBuffer _bb) { + int val_1 = _bb.getShort(__offset(8, o1, _bb)) & 0xFFFF; + int val_2 = _bb.getShort(__offset(8, o2, _bb)) & 0xFFFF; + return val_1 > val_2 ? 1 : val_1 < val_2 ? -1 : 0; + } + + public static Stat __lookup_by_key(Stat obj, int vectorLocation, int key, ByteBuffer bb) { + int span = bb.getInt(vectorLocation - 4); + int start = 0; + while (span != 0) { + int middle = span / 2; + int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb); + int val = bb.getShort(__offset(8, bb.capacity() - tableOffset, bb)) & 0xFFFF; + int comp = val > key ? 1 : val < key ? -1 : 0; + if (comp > 0) { + span = middle; + } else if (comp < 0) { + middle++; + start += middle; + span -= middle; + } else { + return (obj == null ? new Stat() : obj).__assign(tableOffset, bb); + } + } + return null; + } + public static final class Vector extends BaseVector { public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } public Stat get(int j) { return get(new Stat(), j); } public Stat get(Stat obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + public Stat getByKey(int key) { return __lookup_by_key(null, __vector(), key, bb); } + public Stat getByKey(Stat obj, int key) { return __lookup_by_key(obj, __vector(), key, bb); } } } diff --git a/tests/MyGame/Example/Stat.kt b/tests/MyGame/Example/Stat.kt index e72f5533..3d658b4d 100644 --- a/tests/MyGame/Example/Stat.kt +++ b/tests/MyGame/Example/Stat.kt @@ -52,6 +52,11 @@ class Stat : Table() { false } } + override fun keysCompare(o1: Int, o2: Int, _bb: ByteBuffer) : Int { + val val_1 = _bb.getShort(__offset(8, o1, _bb)) + val val_2 = _bb.getShort(__offset(8, o2, _bb)) + return (val_1 - val_2).sign + } companion object { fun validateVersion() = Constants.FLATBUFFERS_1_12_0() fun getRootAsStat(_bb: ByteBuffer): Stat = getRootAsStat(_bb, Stat()) @@ -74,5 +79,27 @@ class Stat : Table() { val o = builder.endTable() return o } + fun __lookup_by_key(obj: Stat?, vectorLocation: Int, key: UShort, bb: ByteBuffer) : Stat? { + var span = bb.getInt(vectorLocation - 4) + var start = 0 + while (span != 0) { + var middle = span / 2 + val tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb) + val value = bb.getShort(__offset(8, bb.capacity() - tableOffset, bb)).toUShort() + val comp = value.compareTo(key) + when { + comp > 0 -> span = middle + comp < 0 -> { + middle++ + start += middle + span -= middle + } + else -> { + return (obj ?: Stat()).__assign(tableOffset, bb) + } + } + } + return null + } } } |