Squashed 'third_party/flatbuffers/' content from commit acc9990ab
Change-Id: I48550d40d78fea996ebe74e9723a5d1f910de491
git-subtree-dir: third_party/flatbuffers
git-subtree-split: acc9990abd2206491480291b0f85f925110102ea
diff --git a/tests/KotlinTest.kt b/tests/KotlinTest.kt
new file mode 100644
index 0000000..07f0465
--- /dev/null
+++ b/tests/KotlinTest.kt
@@ -0,0 +1,460 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import MyGame.Example.*
+import com.google.flatbuffers.ByteBufferUtil
+import com.google.flatbuffers.FlatBufferBuilder
+import NamespaceA.*
+import NamespaceA.NamespaceB.*
+import NamespaceA.NamespaceB.TableInNestedNS
+import java.io.File
+import java.io.FileOutputStream
+import java.io.InputStream
+import java.io.RandomAccessFile
+import java.nio.ByteBuffer
+import java.nio.ByteOrder
+import java.nio.channels.FileChannel
+
+import com.google.flatbuffers.Constants.SIZE_PREFIX_LENGTH
+
+@kotlin.ExperimentalUnsignedTypes
+class KotlinTest {
+
+ companion object {
+ @JvmStatic
+ fun main(args: Array<String>) {
+
+ // First, let's test reading a FlatBuffer generated by C++ code:
+ // This file was generated from monsterdata_test.json
+
+ val data = RandomAccessFile(File("monsterdata_test.mon"), "r").use {
+ val temp = ByteArray(it.length().toInt())
+ it.readFully(temp)
+ temp
+ }
+
+ // Now test it:
+
+ val bb = ByteBuffer.wrap(data)
+ TestBuffer(bb)
+
+ // Second, let's create a FlatBuffer from scratch in Java, and test it also.
+ // We use an initial size of 1 to exercise the reallocation algorithm,
+ // normally a size larger than the typical FlatBuffer you generate would be
+ // better for performance.
+ val fbb = FlatBufferBuilder(1)
+
+ TestBuilderBasics(fbb, true)
+ TestBuilderBasics(fbb, false)
+
+ TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer())
+
+ TestNamespaceNesting()
+
+ TestNestedFlatBuffer()
+
+ TestCreateByteVector()
+
+ TestCreateUninitializedVector()
+
+ TestByteBufferFactory()
+
+ TestSizedInputStream()
+
+ TestVectorOfUnions()
+
+ println("FlatBuffers test: completed successfully")
+ }
+
+ fun TestEnums() {
+ assert(Color.name(Color.Red.toInt()) == "Red")
+ assert(Color.name(Color.Blue.toInt()) == "Blue")
+ assert(Any_.name(Any_.NONE.toInt()) == "NONE")
+ assert(Any_.name(Any_.Monster.toInt()) == "Monster")
+ }
+
+ fun TestBuffer(bb: ByteBuffer) {
+ assert(Monster.MonsterBufferHasIdentifier(bb) == true)
+
+ val monster = Monster.getRootAsMonster(bb)
+
+ assert(monster.hp == 80.toShort())
+ assert(monster.mana == 150.toShort()) // default
+
+ assert(monster.name == "MyMonster")
+ // monster.friendly() // can't access, deprecated
+
+ val pos = monster.pos!!
+ assert(pos.x == 1.0f)
+ assert(pos.y == 2.0f)
+ assert(pos.z == 3.0f)
+ assert(pos.test1 == 3.0)
+ // issue: int != byte
+ assert(pos.test2 == Color.Green)
+ val t = pos.test3!!
+ assert(t.a == 5.toShort())
+ assert(t.b == 6.toByte())
+
+ assert(monster.testType == Any_.Monster)
+ val monster2 = Monster()
+ assert(monster.test(monster2) != null == true)
+ assert(monster2.name == "Fred")
+
+ assert(monster.inventoryLength == 5)
+ var invsum = 0u
+ for (i in 0 until monster.inventoryLength)
+ invsum += monster.inventory(i)
+ assert(invsum == 10u)
+
+ // Alternative way of accessing a vector:
+ val ibb = monster.inventoryAsByteBuffer
+ invsum = 0u
+ while (ibb.position() < ibb.limit())
+ invsum += ibb.get().toUInt()
+ assert(invsum == 10u)
+
+
+ val test_0 = monster.test4(0)!!
+ val test_1 = monster.test4(1)!!
+ assert(monster.test4Length == 2)
+ assert(test_0.a + test_0.b + test_1.a + test_1.b == 100)
+
+ assert(monster.testarrayofstringLength == 2)
+ assert(monster.testarrayofstring(0) == "test1")
+ assert(monster.testarrayofstring(1) == "test2")
+
+ assert(monster.testbool == true)
+ }
+
+ // this method checks additional fields not present in the binary buffer read from file
+ // these new tests are performed on top of the regular tests
+ fun TestExtendedBuffer(bb: ByteBuffer) {
+ TestBuffer(bb)
+
+ val monster = Monster.getRootAsMonster(bb)
+
+ assert(monster.testhashu32Fnv1 == (1u + Integer.MAX_VALUE.toUInt()))
+ }
+
+ fun TestNamespaceNesting() {
+ // reference / manipulate these to verify compilation
+ val fbb = FlatBufferBuilder(1)
+
+ TableInNestedNS.startTableInNestedNS(fbb)
+ TableInNestedNS.addFoo(fbb, 1234)
+ val nestedTableOff = TableInNestedNS.endTableInNestedNS(fbb)
+
+ TableInFirstNS.startTableInFirstNS(fbb)
+ TableInFirstNS.addFooTable(fbb, nestedTableOff)
+ }
+
+ fun TestNestedFlatBuffer() {
+ val nestedMonsterName = "NestedMonsterName"
+ val nestedMonsterHp: Short = 600
+ val nestedMonsterMana: Short = 1024
+
+ var fbb1: FlatBufferBuilder? = FlatBufferBuilder(16)
+ val str1 = fbb1!!.createString(nestedMonsterName)
+ Monster.startMonster(fbb1)
+ Monster.addName(fbb1, str1)
+ Monster.addHp(fbb1, nestedMonsterHp)
+ Monster.addMana(fbb1, nestedMonsterMana)
+ val monster1 = Monster.endMonster(fbb1)
+ Monster.finishMonsterBuffer(fbb1, monster1)
+ val fbb1Bytes = fbb1.sizedByteArray()
+
+ val fbb2 = FlatBufferBuilder(16)
+ val str2 = fbb2.createString("My Monster")
+ val nestedBuffer = Monster.createTestnestedflatbufferVector(fbb2, fbb1Bytes.asUByteArray())
+ Monster.startMonster(fbb2)
+ Monster.addName(fbb2, str2)
+ Monster.addHp(fbb2, 50.toShort())
+ Monster.addMana(fbb2, 32.toShort())
+ Monster.addTestnestedflatbuffer(fbb2, nestedBuffer)
+ val monster = Monster.endMonster(fbb2)
+ Monster.finishMonsterBuffer(fbb2, monster)
+
+ // Now test the data extracted from the nested buffer
+ val mons = Monster.getRootAsMonster(fbb2.dataBuffer())
+ val nestedMonster = mons.testnestedflatbufferAsMonster!!
+
+ assert(nestedMonsterMana == nestedMonster.mana)
+ assert(nestedMonsterHp == nestedMonster.hp)
+ assert(nestedMonsterName == nestedMonster.name)
+ }
+
+ fun TestCreateByteVector() {
+ val fbb = FlatBufferBuilder(16)
+ val str = fbb.createString("MyMonster")
+ val inventory = byteArrayOf(0, 1, 2, 3, 4)
+ val vec = fbb.createByteVector(inventory)
+ Monster.startMonster(fbb)
+ Monster.addInventory(fbb, vec)
+ Monster.addName(fbb, str)
+ val monster1 = Monster.endMonster(fbb)
+ Monster.finishMonsterBuffer(fbb, monster1)
+ val monsterObject = Monster.getRootAsMonster(fbb.dataBuffer())
+
+ assert(monsterObject.inventory(1) == inventory[1].toUByte())
+ assert(monsterObject.inventoryLength == inventory.size)
+ assert(ByteBuffer.wrap(inventory) == monsterObject.inventoryAsByteBuffer)
+ }
+
+ fun TestCreateUninitializedVector() {
+ val fbb = FlatBufferBuilder(16)
+ val str = fbb.createString("MyMonster")
+ val inventory = byteArrayOf(0, 1, 2, 3, 4)
+ val bb = fbb.createUnintializedVector(1, inventory.size, 1)
+ for (i in inventory) {
+ bb.put(i)
+ }
+ val vec = fbb.endVector()
+ Monster.startMonster(fbb)
+ Monster.addInventory(fbb, vec)
+ Monster.addName(fbb, str)
+ val monster1 = Monster.endMonster(fbb)
+ Monster.finishMonsterBuffer(fbb, monster1)
+ val monsterObject = Monster.getRootAsMonster(fbb.dataBuffer())
+
+ assert(monsterObject.inventory(1) == inventory[1].toUByte())
+ assert(monsterObject.inventoryLength == inventory.size)
+ assert(ByteBuffer.wrap(inventory) == monsterObject.inventoryAsByteBuffer)
+ }
+
+ fun TestByteBufferFactory() {
+ class MappedByteBufferFactory : FlatBufferBuilder.ByteBufferFactory() {
+ override fun newByteBuffer(capacity: Int): ByteBuffer? {
+ var bb: ByteBuffer?
+ try {
+ bb = RandomAccessFile("javatest.bin", "rw").channel.map(
+ FileChannel.MapMode.READ_WRITE,
+ 0,
+ capacity.toLong()
+ ).order(ByteOrder.LITTLE_ENDIAN)
+ } catch (e: Throwable) {
+ println("FlatBuffers test: couldn't map ByteBuffer to a file")
+ bb = null
+ }
+
+ return bb
+ }
+ }
+
+ val fbb = FlatBufferBuilder(1, MappedByteBufferFactory())
+
+ TestBuilderBasics(fbb, false)
+ }
+
+ fun TestSizedInputStream() {
+ // Test on default FlatBufferBuilder that uses HeapByteBuffer
+ val fbb = FlatBufferBuilder(1)
+
+ TestBuilderBasics(fbb, false)
+
+ val `in` = fbb.sizedInputStream()
+ val array = fbb.sizedByteArray()
+ var count = 0
+ var currentVal = 0
+
+ while (currentVal != -1 && count < array.size) {
+ try {
+ currentVal = `in`.read()
+ } catch (e: java.io.IOException) {
+ println("FlatBuffers test: couldn't read from InputStream")
+ return
+ }
+
+ assert(currentVal.toByte() == array[count])
+ count++
+ }
+ assert(count == array.size)
+ }
+
+ fun TestBuilderBasics(fbb: FlatBufferBuilder, sizePrefix: Boolean) {
+ val names = intArrayOf(fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma"))
+ val off = IntArray(3)
+ Monster.startMonster(fbb)
+ Monster.addName(fbb, names[0])
+ off[0] = Monster.endMonster(fbb)
+ Monster.startMonster(fbb)
+ Monster.addName(fbb, names[1])
+ off[1] = Monster.endMonster(fbb)
+ Monster.startMonster(fbb)
+ Monster.addName(fbb, names[2])
+ off[2] = Monster.endMonster(fbb)
+ val sortMons = fbb.createSortedVectorOfTables(Monster(), off)
+
+ // We set up the same values as monsterdata.json:
+
+ val str = fbb.createString("MyMonster")
+
+ val inv = Monster.createInventoryVector(fbb, byteArrayOf(0, 1, 2, 3, 4).asUByteArray())
+
+ val fred = fbb.createString("Fred")
+ Monster.startMonster(fbb)
+ Monster.addName(fbb, fred)
+ val mon2 = Monster.endMonster(fbb)
+
+ Monster.startTest4Vector(fbb, 2)
+ Test.createTest(fbb, 10.toShort(), 20.toByte())
+ Test.createTest(fbb, 30.toShort(), 40.toByte())
+ val test4 = fbb.endVector()
+
+ val testArrayOfString =
+ Monster.createTestarrayofstringVector(fbb, intArrayOf(fbb.createString("test1"), fbb.createString("test2")))
+
+ Monster.startMonster(fbb)
+ Monster.addPos(
+ fbb, Vec3.createVec3(
+ fbb, 1.0f, 2.0f, 3.0f, 3.0,
+ Color.Green, 5.toShort(), 6.toByte()
+ )
+ )
+ Monster.addHp(fbb, 80.toShort())
+ Monster.addName(fbb, str)
+ Monster.addInventory(fbb, inv)
+ Monster.addTestType(fbb, Any_.Monster)
+ Monster.addTest(fbb, mon2)
+ Monster.addTest4(fbb, test4)
+ Monster.addTestarrayofstring(fbb, testArrayOfString)
+ Monster.addTestbool(fbb, true)
+ Monster.addTesthashu32Fnv1(fbb, UInt.MAX_VALUE + 1u)
+ Monster.addTestarrayoftables(fbb, sortMons)
+ val mon = Monster.endMonster(fbb)
+
+ if (sizePrefix) {
+ Monster.finishSizePrefixedMonsterBuffer(fbb, mon)
+ } else {
+ Monster.finishMonsterBuffer(fbb, mon)
+ }
+
+ // Write the result to a file for debugging purposes:
+ // Note that the binaries are not necessarily identical, since the JSON
+ // parser may serialize in a slightly different order than the above
+ // Java code. They are functionally equivalent though.
+
+ try {
+ val filename = "monsterdata_java_wire" + (if (sizePrefix) "_sp" else "") + ".mon"
+ val fc = FileOutputStream(filename).channel
+ fc.write(fbb.dataBuffer().duplicate())
+ fc.close()
+ } catch (e: java.io.IOException) {
+ println("FlatBuffers test: couldn't write file")
+ return
+ }
+
+ // Test it:
+ var dataBuffer = fbb.dataBuffer()
+ if (sizePrefix) {
+ assert(
+ ByteBufferUtil.getSizePrefix(dataBuffer) + SIZE_PREFIX_LENGTH ==
+ dataBuffer.remaining()
+ )
+ dataBuffer = ByteBufferUtil.removeSizePrefix(dataBuffer)
+ }
+ TestExtendedBuffer(dataBuffer)
+
+ // Make sure it also works with read only ByteBuffers. This is slower,
+ // since creating strings incurs an additional copy
+ // (see Table.__string).
+ TestExtendedBuffer(dataBuffer.asReadOnlyBuffer())
+
+ TestEnums()
+
+ //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
+ // revert to original values after testing
+ val monster = Monster.getRootAsMonster(dataBuffer)
+
+ // mana is optional and does not exist in the buffer so the mutation should fail
+ // the mana field should retain its default value
+ assert(monster.mutateMana(10.toShort()) == false)
+ assert(monster.mana == 150.toShort())
+
+ // Accessing a vector of sorted by the key tables
+ assert(monster.testarrayoftables(0)!!.name == "Barney")
+ assert(monster.testarrayoftables(1)!!.name == "Frodo")
+ assert(monster.testarrayoftables(2)!!.name == "Wilma")
+
+ // Example of searching for a table by the key
+ assert(monster.testarrayoftablesByKey("Frodo")!!.name == "Frodo")
+ assert(monster.testarrayoftablesByKey("Barney")!!.name == "Barney")
+ assert(monster.testarrayoftablesByKey("Wilma")!!.name == "Wilma")
+
+ // testType is an existing field and mutating it should succeed
+ assert(monster.testType == Any_.Monster)
+ assert(monster.mutateTestType(Any_.NONE) == true)
+ assert(monster.testType == Any_.NONE)
+ assert(monster.mutateTestType(Any_.Monster) == true)
+ assert(monster.testType == Any_.Monster)
+
+ //mutate the inventory vector
+ assert(monster.mutateInventory(0, 1u) == true)
+ assert(monster.mutateInventory(1, 2u) == true)
+ assert(monster.mutateInventory(2, 3u) == true)
+ assert(monster.mutateInventory(3, 4u) == true)
+ assert(monster.mutateInventory(4, 5u) == true)
+
+ for (i in 0 until monster.inventoryLength) {
+ assert(monster.inventory(i) == (i.toUByte() + 1u).toUByte())
+ }
+
+ //reverse mutation
+ assert(monster.mutateInventory(0, 0u) == true)
+ assert(monster.mutateInventory(1, 1u) == true)
+ assert(monster.mutateInventory(2, 2u) == true)
+ assert(monster.mutateInventory(3, 3u) == true)
+ assert(monster.mutateInventory(4, 4u) == true)
+
+ // get a struct field and edit one of its fields
+ val pos = monster.pos!!
+ assert(pos.x == 1.0f)
+ pos.mutateX(55.0f)
+ assert(pos.x == 55.0f)
+ pos.mutateX(1.0f)
+ assert(pos.x == 1.0f)
+ }
+
+ fun TestVectorOfUnions() {
+ val fbb = FlatBufferBuilder()
+
+ val swordAttackDamage = 1
+
+ val characterVector = intArrayOf(Attacker.createAttacker(fbb, swordAttackDamage))
+
+ val characterTypeVector = ubyteArrayOf(Character_.MuLan)
+
+ Movie.finishMovieBuffer(
+ fbb,
+ Movie.createMovie(
+ fbb,
+ 0u,
+ 0,
+ Movie.createCharactersTypeVector(fbb, characterTypeVector),
+ Movie.createCharactersVector(fbb, characterVector)
+ )
+ )
+
+ val movie = Movie.getRootAsMovie(fbb.dataBuffer())
+
+ assert(movie.charactersTypeLength == characterTypeVector.size)
+ assert(movie.charactersLength == characterVector.size)
+
+ assert(movie.charactersType(0) == characterTypeVector[0])
+
+ assert((movie.characters(Attacker(), 0) as Attacker).swordAttackDamage == swordAttackDamage)
+ }
+}
+ }