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)
+    }
+}
+  }