diff --git a/src/idl_gen_kotlin.cpp b/src/idl_gen_kotlin.cpp index 2ed89d419..9101a91ad 100644 --- a/src/idl_gen_kotlin.cpp +++ b/src/idl_gen_kotlin.cpp @@ -1201,11 +1201,12 @@ class KotlinGenerator : public BaseGenerator { : InlineSize(field.value.type.VectorType())); // Generate a ByteBuffer accessor for strings & vectors of scalars. // e.g. - // val inventoryByteBuffer: ByteBuffer + // val inventoryByteBuffer: ByteBuffer? // get = __vector_as_bytebuffer(14, 1) + auto buffer_type = field.IsRequired() ? "ByteBuffer" : "ByteBuffer?"; GenerateGetterOneLine( - writer, field_name + "AsByteBuffer", "ByteBuffer", [&]() { + writer, field_name + "AsByteBuffer", buffer_type, [&]() { writer.SetValue("end", end_idx); writer += "__vector_as_bytebuffer({{offset}}, {{end}})"; }); @@ -1213,10 +1214,10 @@ class KotlinGenerator : public BaseGenerator { // Generate a ByteBuffer accessor for strings & vectors of scalars. // e.g. // fun inventoryInByteBuffer(_bb: Bytebuffer): - // ByteBuffer = __vector_as_bytebuffer(_bb, 14, 1) + // ByteBuffer? = __vector_as_bytebuffer(_bb, 14, 1) GenerateFunOneLine( writer, field_name + "InByteBuffer", "_bb: ByteBuffer", - "ByteBuffer", [&]() { + buffer_type, [&]() { writer.SetValue("end", end_idx); writer += "__vector_in_bytebuffer(_bb, {{offset}}, {{end}})"; }); diff --git a/tests/KotlinTest.kt b/tests/KotlinTest.kt index b9ee39331..94e74965c 100644 --- a/tests/KotlinTest.kt +++ b/tests/KotlinTest.kt @@ -80,6 +80,7 @@ class KotlinTest { TestSharedStringPool() TestScalarOptional() TestDictionaryLookup() + TestNullFields() println("FlatBuffers test: completed successfully") } @@ -142,7 +143,7 @@ class KotlinTest { assert(invsum == 10u) // Alternative way of accessing a vector: - val ibb = monster.inventoryAsByteBuffer + val ibb = monster.inventoryAsByteBuffer!! invsum = 0u while (ibb.position() < ibb.limit()) invsum += ibb.get().toUInt() assert(invsum == 10u) @@ -615,5 +616,37 @@ class KotlinTest { assert(scalarStuff.maybeEnum == OptionalByte.Two) assert(scalarStuff.defaultEnum == OptionalByte.Two) } + + fun TestNullFields() { + val fbb = FlatBufferBuilder(1) + val nameOffset = fbb.createString("name") + Monster.startMonster(fbb) + Monster.addName(fbb, nameOffset) + Monster.finishMonsterBuffer(fbb, Monster.endMonster(fbb)) + + val monsterBb = fbb.dataBuffer() + val monster = Monster.getRootAsMonster(monsterBb.duplicate()) + assert(monster.pos == null) // struct + assert(monster.enemy == null) // table + assert(monster.test(Monster()) == null) // union + assert(monster.testType == Any_.NONE) + assert(monster.inventoryLength == 0) // vector of scalars + assert(monster.inventoryAsByteBuffer == null) + assert(monster.inventoryInByteBuffer(monsterBb) == null) + assert(monster.testarrayofsortedstructLength == 0) // vector of structs + assert(monster.testarrayofstringLength == 0) // vector of strings + assert(monster.testarrayoftablesLength == 0) // vector of tables + + + val fbb2 = FlatBufferBuilder(1) + val offset = Stat.createStat(fbb2, 0, 10, 10.toUShort()) + fbb2.finish(offset) + + val statBb = fbb2.dataBuffer() + val stat = Stat.getRootAsStat(statBb.duplicate()) + assert(stat.id == null) // string + assert(stat.idAsByteBuffer == null) + assert(stat.idInByteBuffer(statBb) == null) + } } } diff --git a/tests/MyGame/Example/Monster.kt b/tests/MyGame/Example/Monster.kt index 9dfdc3000..4e10a8ab7 100644 --- a/tests/MyGame/Example/Monster.kt +++ b/tests/MyGame/Example/Monster.kt @@ -91,8 +91,8 @@ class Monster : Table() { get() { val o = __offset(14); return if (o != 0) __vector_len(o) else 0 } - val inventoryAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(14, 1) - fun inventoryInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 14, 1) + val inventoryAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(14, 1) + fun inventoryInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 14, 1) fun mutateInventory(j: Int, inventory: UByte) : Boolean { val o = __offset(14) return if (o != 0) { @@ -212,8 +212,8 @@ class Monster : Table() { get() { val o = __offset(30); return if (o != 0) __vector_len(o) else 0 } - val testnestedflatbufferAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(30, 1) - fun testnestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 30, 1) + val testnestedflatbufferAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(30, 1) + fun testnestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 30, 1) val testnestedflatbufferAsMonster : MyGame.Example.Monster? get() = testnestedflatbufferAsMonster(MyGame.Example.Monster()) fun testnestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? { val o = __offset(30) @@ -379,8 +379,8 @@ class Monster : Table() { get() { val o = __offset(52); return if (o != 0) __vector_len(o) else 0 } - val testarrayofboolsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(52, 1) - fun testarrayofboolsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 52, 1) + val testarrayofboolsAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(52, 1) + fun testarrayofboolsInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 52, 1) fun mutateTestarrayofbools(j: Int, testarrayofbools: Boolean) : Boolean { val o = __offset(52) return if (o != 0) { @@ -469,8 +469,8 @@ class Monster : Table() { get() { val o = __offset(64); return if (o != 0) __vector_len(o) else 0 } - val flexAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(64, 1) - fun flexInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 64, 1) + val flexAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(64, 1) + fun flexInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 64, 1) fun mutateFlex(j: Int, flex: UByte) : Boolean { val o = __offset(64) return if (o != 0) { @@ -505,8 +505,8 @@ class Monster : Table() { get() { val o = __offset(68); return if (o != 0) __vector_len(o) else 0 } - val vectorOfLongsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(68, 8) - fun vectorOfLongsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 68, 8) + val vectorOfLongsAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(68, 8) + fun vectorOfLongsInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 68, 8) fun mutateVectorOfLongs(j: Int, vectorOfLongs: Long) : Boolean { val o = __offset(68) return if (o != 0) { @@ -528,8 +528,8 @@ class Monster : Table() { get() { val o = __offset(70); return if (o != 0) __vector_len(o) else 0 } - val vectorOfDoublesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(70, 8) - fun vectorOfDoublesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 70, 8) + val vectorOfDoublesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(70, 8) + fun vectorOfDoublesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 70, 8) fun mutateVectorOfDoubles(j: Int, vectorOfDoubles: Double) : Boolean { val o = __offset(70) return if (o != 0) { @@ -603,8 +603,8 @@ class Monster : Table() { get() { val o = __offset(78); return if (o != 0) __vector_len(o) else 0 } - val vectorOfWeakReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(78, 8) - fun vectorOfWeakReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 78, 8) + val vectorOfWeakReferencesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(78, 8) + fun vectorOfWeakReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 78, 8) fun mutateVectorOfWeakReferences(j: Int, vectorOfWeakReferences: ULong) : Boolean { val o = __offset(78) return if (o != 0) { @@ -669,8 +669,8 @@ class Monster : Table() { get() { val o = __offset(84); return if (o != 0) __vector_len(o) else 0 } - val vectorOfCoOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(84, 8) - fun vectorOfCoOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 84, 8) + val vectorOfCoOwningReferencesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(84, 8) + fun vectorOfCoOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 84, 8) fun mutateVectorOfCoOwningReferences(j: Int, vectorOfCoOwningReferences: ULong) : Boolean { val o = __offset(84) return if (o != 0) { @@ -706,8 +706,8 @@ class Monster : Table() { get() { val o = __offset(88); return if (o != 0) __vector_len(o) else 0 } - val vectorOfNonOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(88, 8) - fun vectorOfNonOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 88, 8) + val vectorOfNonOwningReferencesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(88, 8) + fun vectorOfNonOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 88, 8) fun mutateVectorOfNonOwningReferences(j: Int, vectorOfNonOwningReferences: ULong) : Boolean { val o = __offset(88) return if (o != 0) { @@ -763,8 +763,8 @@ class Monster : Table() { get() { val o = __offset(98); return if (o != 0) __vector_len(o) else 0 } - val vectorOfEnumsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(98, 1) - fun vectorOfEnumsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 98, 1) + val vectorOfEnumsAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(98, 1) + fun vectorOfEnumsInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 98, 1) fun mutateVectorOfEnums(j: Int, vectorOfEnums: UByte) : Boolean { val o = __offset(98) return if (o != 0) { @@ -800,8 +800,8 @@ class Monster : Table() { get() { val o = __offset(102); return if (o != 0) __vector_len(o) else 0 } - val testrequirednestedflatbufferAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(102, 1) - fun testrequirednestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 102, 1) + val testrequirednestedflatbufferAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(102, 1) + fun testrequirednestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 102, 1) val testrequirednestedflatbufferAsMonster : MyGame.Example.Monster? get() = testrequirednestedflatbufferAsMonster(MyGame.Example.Monster()) fun testrequirednestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? { val o = __offset(102) diff --git a/tests/MyGame/Example/Stat.kt b/tests/MyGame/Example/Stat.kt index 26ee25371..d7bc296c2 100644 --- a/tests/MyGame/Example/Stat.kt +++ b/tests/MyGame/Example/Stat.kt @@ -37,8 +37,8 @@ class Stat : Table() { null } } - val idAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(4, 1) - fun idInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 4, 1) + val idAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(4, 1) + fun idInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 4, 1) val val_ : Long get() { val o = __offset(6) diff --git a/tests/MyGame/Example/TypeAliases.kt b/tests/MyGame/Example/TypeAliases.kt index d73f78b36..b00eb544b 100644 --- a/tests/MyGame/Example/TypeAliases.kt +++ b/tests/MyGame/Example/TypeAliases.kt @@ -180,8 +180,8 @@ class TypeAliases : Table() { get() { val o = __offset(24); return if (o != 0) __vector_len(o) else 0 } - val v8AsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(24, 1) - fun v8InByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 24, 1) + val v8AsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(24, 1) + fun v8InByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 24, 1) fun mutateV8(j: Int, v8: Byte) : Boolean { val o = __offset(24) return if (o != 0) { @@ -203,8 +203,8 @@ class TypeAliases : Table() { get() { val o = __offset(26); return if (o != 0) __vector_len(o) else 0 } - val vf64AsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(26, 8) - fun vf64InByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 26, 8) + val vf64AsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(26, 8) + fun vf64InByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 26, 8) fun mutateVf64(j: Int, vf64: Double) : Boolean { val o = __offset(26) return if (o != 0) { diff --git a/tests/MyGame/MonsterExtra.kt b/tests/MyGame/MonsterExtra.kt index d8c8d15b0..e38abc29c 100644 --- a/tests/MyGame/MonsterExtra.kt +++ b/tests/MyGame/MonsterExtra.kt @@ -152,8 +152,8 @@ class MonsterExtra : Table() { get() { val o = __offset(20); return if (o != 0) __vector_len(o) else 0 } - val dvecAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(20, 8) - fun dvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 20, 8) + val dvecAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(20, 8) + fun dvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 20, 8) fun mutateDvec(j: Int, dvec: Double) : Boolean { val o = __offset(20) return if (o != 0) { @@ -175,8 +175,8 @@ class MonsterExtra : Table() { get() { val o = __offset(22); return if (o != 0) __vector_len(o) else 0 } - val fvecAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(22, 4) - fun fvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 22, 4) + val fvecAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(22, 4) + fun fvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 22, 4) fun mutateFvec(j: Int, fvec: Float) : Boolean { val o = __offset(22) return if (o != 0) { diff --git a/tests/union_vector/Movie.kt b/tests/union_vector/Movie.kt index 0e8645d5a..aa04ad5c3 100644 --- a/tests/union_vector/Movie.kt +++ b/tests/union_vector/Movie.kt @@ -55,8 +55,8 @@ class Movie : Table() { get() { val o = __offset(8); return if (o != 0) __vector_len(o) else 0 } - val charactersTypeAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(8, 1) - fun charactersTypeInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 8, 1) + val charactersTypeAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(8, 1) + fun charactersTypeInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 8, 1) fun mutateCharactersType(j: Int, charactersType: UByte) : Boolean { val o = __offset(8) return if (o != 0) {