1 
2 import static com.google.flatbuffers.Constants.*;
3 
4 import MyGame.Example.*;
5 import optional_scalars.ScalarStuff;
6 import optional_scalars.OptionalByte;
7 import MyGame.MonsterExtra;
8 import NamespaceA.*;
9 import NamespaceA.NamespaceB.*;
10 import com.google.flatbuffers.ByteBufferUtil;
11 import com.google.flatbuffers.ByteVector;
12 import com.google.flatbuffers.FlatBufferBuilder;
13 import com.google.flatbuffers.FlexBuffers;
14 import com.google.flatbuffers.FlexBuffersBuilder;
15 import com.google.flatbuffers.StringVector;
16 import com.google.flatbuffers.UnionVector;
17 
18 import com.google.flatbuffers.FlexBuffers.FlexBufferException;
19 import com.google.flatbuffers.FlexBuffers.Reference;
20 import com.google.flatbuffers.FlexBuffers.Vector;
21 import com.google.flatbuffers.ArrayReadWriteBuf;
22 import com.google.flatbuffers.FlexBuffers.KeyVector;
23 
24 import java.io.*;
25 import java.math.BigInteger;
26 import java.nio.ByteBuffer;
27 import java.nio.ByteOrder;
28 import java.nio.CharBuffer;
29 import java.nio.channels.FileChannel;
30 import java.nio.charset.StandardCharsets;
31 import java.util.Arrays;
32 import java.util.HashMap;
33 import java.util.Map;
34 
35 /*
36  * Copyright 2014 Google Inc. All rights reserved.
37  *
38  * Licensed under the Apache License, Version 2.0 (the "License");
39  * you may not use this file except in compliance with the License.
40  * You may obtain a copy of the License at
41  *
42  *     http://www.apache.org/licenses/LICENSE-2.0
43  *
44  * Unless required by applicable law or agreed to in writing, software
45  * distributed under the License is distributed on an "AS IS" BASIS,
46  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47  * See the License for the specific language governing permissions and
48  * limitations under the License.
49  */
50 
51 
52 
53 class JavaTest {
main(String[] args)54     public static void main(String[] args) {
55 
56         // First, let's test reading a FlatBuffer generated by C++ code:
57         // This file was generated from monsterdata_test.json
58 
59         byte[] data = null;
60         File file = new File("monsterdata_test.mon");
61         RandomAccessFile f = null;
62         try {
63             f = new RandomAccessFile(file, "r");
64             data = new byte[(int)f.length()];
65             f.readFully(data);
66             f.close();
67         } catch(java.io.IOException e) {
68             System.out.println("FlatBuffers test: couldn't read file");
69             return;
70         }
71 
72         // Now test it:
73 
74         ByteBuffer bb = ByteBuffer.wrap(data);
75         TestBuffer(bb);
76 
77         // Second, let's create a FlatBuffer from scratch in Java, and test it also.
78         // We use an initial size of 1 to exercise the reallocation algorithm,
79         // normally a size larger than the typical FlatBuffer you generate would be
80         // better for performance.
81         FlatBufferBuilder fbb = new FlatBufferBuilder(1);
82 
83         TestBuilderBasics(fbb, true);
84         TestBuilderBasics(fbb, false);
85 
86         TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer());
87 
88         TestNamespaceNesting();
89 
90         TestNestedFlatBuffer();
91 
92         TestCreateByteVector();
93 
94         TestCreateUninitializedVector();
95 
96         TestByteBufferFactory();
97 
98         TestSizedInputStream();
99 
100         TestVectorOfUnions();
101 
102         TestFixedLengthArrays();
103 
104         TestFlexBuffers();
105 
106         TestVectorOfBytes();
107 
108         TestSharedStringPool();
109 
110         TestScalarOptional();
111 
112         System.out.println("FlatBuffers test: completed successfully");
113     }
114 
TestEnums()115     static void TestEnums() {
116       TestEq(Color.name(Color.Red), "Red");
117       TestEq(Color.name(Color.Blue), "Blue");
118       TestEq(Any.name(Any.NONE), "NONE");
119       TestEq(Any.name(Any.Monster), "Monster");
120     }
121 
TestBuffer(ByteBuffer bb)122     static void TestBuffer(ByteBuffer bb) {
123         TestEq(Monster.MonsterBufferHasIdentifier(bb), true);
124 
125         Monster monster = Monster.getRootAsMonster(bb);
126 
127         TestEq(monster.hp(), (short)80);
128         TestEq(monster.mana(), (short)150);  // default
129 
130         TestEq(monster.name(), "MyMonster");
131         // monster.friendly() // can't access, deprecated
132 
133         Vec3 pos = monster.pos();
134         TestEq(pos.x(), 1.0f);
135         TestEq(pos.y(), 2.0f);
136         TestEq(pos.z(), 3.0f);
137         TestEq(pos.test1(), 3.0);
138         // issue: int != byte
139         TestEq(pos.test2(), (int) Color.Green);
140         Test t = pos.test3();
141         TestEq(t.a(), (short)5);
142         TestEq(t.b(), (byte)6);
143 
144         TestEq(monster.testType(), (byte)Any.Monster);
145         Monster monster2 = new Monster();
146         TestEq(monster.test(monster2) != null, true);
147         TestEq(monster2.name(), "Fred");
148 
149         TestEq(monster.inventoryLength(), 5);
150         int invsum = 0;
151         for (int i = 0; i < monster.inventoryLength(); i++)
152             invsum += monster.inventory(i);
153         TestEq(invsum, 10);
154 
155         // Method using a vector access object:
156         ByteVector inventoryVector = monster.inventoryVector();
157         TestEq(inventoryVector.length(), 5);
158         invsum = 0;
159         for (int i = 0; i < inventoryVector.length(); i++)
160             invsum += inventoryVector.getAsUnsigned(i);
161         TestEq(invsum, 10);
162 
163         // Alternative way of accessing a vector:
164         ByteBuffer ibb = monster.inventoryAsByteBuffer();
165         invsum = 0;
166         while (ibb.position() < ibb.limit())
167             invsum += ibb.get();
168         TestEq(invsum, 10);
169 
170         Test test_0 = monster.test4(0);
171         Test test_1 = monster.test4(1);
172         TestEq(monster.test4Length(), 2);
173         TestEq(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100);
174 
175         Test.Vector test4Vector = monster.test4Vector();
176         test_0 = test4Vector.get(0);
177         test_1 = test4Vector.get(1);
178         TestEq(test4Vector.length(), 2);
179         TestEq(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100);
180 
181         TestEq(monster.testarrayofstringLength(), 2);
182         TestEq(monster.testarrayofstring(0),"test1");
183         TestEq(monster.testarrayofstring(1),"test2");
184 
185         // Method using a vector access object:
186         StringVector testarrayofstringVector = monster.testarrayofstringVector();
187         TestEq(testarrayofstringVector.length(), 2);
188         TestEq(testarrayofstringVector.get(0),"test1");
189         TestEq(testarrayofstringVector.get(1),"test2");
190 
191         TestEq(monster.testbool(), true);
192     }
193 
194     // this method checks additional fields not present in the binary buffer read from file
195     // these new tests are performed on top of the regular tests
TestExtendedBuffer(ByteBuffer bb)196     static void TestExtendedBuffer(ByteBuffer bb) {
197         TestBuffer(bb);
198 
199         Monster monster = Monster.getRootAsMonster(bb);
200 
201         TestEq(monster.testhashu32Fnv1(), Integer.MAX_VALUE + 1L);
202     }
203 
TestNamespaceNesting()204     static void TestNamespaceNesting() {
205         // reference / manipulate these to verify compilation
206         FlatBufferBuilder fbb = new FlatBufferBuilder(1);
207 
208         TableInNestedNS.startTableInNestedNS(fbb);
209         TableInNestedNS.addFoo(fbb, 1234);
210         int nestedTableOff = TableInNestedNS.endTableInNestedNS(fbb);
211 
212         TableInFirstNS.startTableInFirstNS(fbb);
213         TableInFirstNS.addFooTable(fbb, nestedTableOff);
214         int off = TableInFirstNS.endTableInFirstNS(fbb);
215     }
216 
TestNestedFlatBuffer()217     static void TestNestedFlatBuffer() {
218         final String nestedMonsterName = "NestedMonsterName";
219         final short nestedMonsterHp = 600;
220         final short nestedMonsterMana = 1024;
221 
222         FlatBufferBuilder fbb1 = new FlatBufferBuilder(16);
223         int str1 = fbb1.createString(nestedMonsterName);
224         Monster.startMonster(fbb1);
225         Monster.addName(fbb1, str1);
226         Monster.addHp(fbb1, nestedMonsterHp);
227         Monster.addMana(fbb1, nestedMonsterMana);
228         int monster1 = Monster.endMonster(fbb1);
229         Monster.finishMonsterBuffer(fbb1, monster1);
230         byte[] fbb1Bytes = fbb1.sizedByteArray();
231         fbb1 = null;
232 
233         FlatBufferBuilder fbb2 = new FlatBufferBuilder(16);
234         int str2 = fbb2.createString("My Monster");
235         int nestedBuffer = Monster.createTestnestedflatbufferVector(fbb2, fbb1Bytes);
236         Monster.startMonster(fbb2);
237         Monster.addName(fbb2, str2);
238         Monster.addHp(fbb2, (short)50);
239         Monster.addMana(fbb2, (short)32);
240         Monster.addTestnestedflatbuffer(fbb2, nestedBuffer);
241         int monster = Monster.endMonster(fbb2);
242         Monster.finishMonsterBuffer(fbb2, monster);
243 
244         // Now test the data extracted from the nested buffer
245         Monster mons = Monster.getRootAsMonster(fbb2.dataBuffer());
246         Monster nestedMonster = mons.testnestedflatbufferAsMonster();
247 
248         TestEq(nestedMonsterMana, nestedMonster.mana());
249         TestEq(nestedMonsterHp, nestedMonster.hp());
250         TestEq(nestedMonsterName, nestedMonster.name());
251     }
252 
TestCreateByteVector()253     static void TestCreateByteVector() {
254         FlatBufferBuilder fbb = new FlatBufferBuilder(16);
255         int str = fbb.createString("MyMonster");
256         byte[] inventory = new byte[] { 0, 1, 2, 3, 4 };
257         int vec = fbb.createByteVector(inventory);
258         Monster.startMonster(fbb);
259         Monster.addInventory(fbb, vec);
260         Monster.addName(fbb, str);
261         int monster1 = Monster.endMonster(fbb);
262         Monster.finishMonsterBuffer(fbb, monster1);
263         Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
264 
265         TestEq(monsterObject.inventory(1), (int)inventory[1]);
266         TestEq(monsterObject.inventoryLength(), inventory.length);
267         ByteVector inventoryVector = monsterObject.inventoryVector();
268         TestEq(inventoryVector.getAsUnsigned(1), (int)inventory[1]);
269         TestEq(inventoryVector.length(), inventory.length);
270 
271         TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
272     }
273 
TestCreateUninitializedVector()274     static void TestCreateUninitializedVector() {
275         FlatBufferBuilder fbb = new FlatBufferBuilder(16);
276         int str = fbb.createString("MyMonster");
277         byte[] inventory = new byte[] { 0, 1, 2, 3, 4 };
278         ByteBuffer bb = fbb.createUnintializedVector(1, inventory.length, 1);
279         for (byte i:inventory) {
280             bb.put(i);
281         }
282         int vec = fbb.endVector();
283         Monster.startMonster(fbb);
284         Monster.addInventory(fbb, vec);
285         Monster.addName(fbb, str);
286         int monster1 = Monster.endMonster(fbb);
287         Monster.finishMonsterBuffer(fbb, monster1);
288         Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
289 
290         TestEq(monsterObject.inventory(1), (int)inventory[1]);
291         TestEq(monsterObject.inventoryLength(), inventory.length);
292         ByteVector inventoryVector = monsterObject.inventoryVector();
293         TestEq(inventoryVector.getAsUnsigned(1), (int)inventory[1]);
294         TestEq(inventoryVector.length(), inventory.length);
295         TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
296     }
297 
TestByteBufferFactory()298     static void TestByteBufferFactory() {
299         final class MappedByteBufferFactory extends FlatBufferBuilder.ByteBufferFactory {
300             @Override
301             public ByteBuffer newByteBuffer(int capacity) {
302                 ByteBuffer bb;
303                 try {
304                     RandomAccessFile f = new RandomAccessFile("javatest.bin", "rw");
305                     bb =  f.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, capacity).order(ByteOrder.LITTLE_ENDIAN);
306                     f.close();
307                 } catch(Throwable e) {
308                     System.out.println("FlatBuffers test: couldn't map ByteBuffer to a file");
309                     bb = null;
310                 }
311                 return bb;
312             }
313         }
314 
315         FlatBufferBuilder fbb = new FlatBufferBuilder(1, new MappedByteBufferFactory());
316 
317         TestBuilderBasics(fbb, false);
318     }
319 
TestSizedInputStream()320     static void TestSizedInputStream() {
321         // Test on default FlatBufferBuilder that uses HeapByteBuffer
322         FlatBufferBuilder fbb = new FlatBufferBuilder(1);
323 
324         TestBuilderBasics(fbb, false);
325 
326         InputStream in = fbb.sizedInputStream();
327         byte[] array = fbb.sizedByteArray();
328         int count = 0;
329         int currentVal = 0;
330 
331         while (currentVal != -1 && count < array.length) {
332             try {
333                 currentVal = in.read();
334             } catch(java.io.IOException e) {
335                 System.out.println("FlatBuffers test: couldn't read from InputStream");
336                 return;
337             }
338             TestEq((byte)currentVal, array[count]);
339             count++;
340         }
341         TestEq(count, array.length);
342     }
343 
TestBuilderBasics(FlatBufferBuilder fbb, boolean sizePrefix)344     static void TestBuilderBasics(FlatBufferBuilder fbb, boolean sizePrefix) {
345         int[] names = {fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma")};
346         int[] off = new int[3];
347         Monster.startMonster(fbb);
348         Monster.addName(fbb, names[0]);
349         off[0] = Monster.endMonster(fbb);
350         Monster.startMonster(fbb);
351         Monster.addName(fbb, names[1]);
352         off[1] = Monster.endMonster(fbb);
353         Monster.startMonster(fbb);
354         Monster.addName(fbb, names[2]);
355         off[2] = Monster.endMonster(fbb);
356         int sortMons = fbb.createSortedVectorOfTables(new Monster(), off);
357 
358         // We set up the same values as monsterdata.json:
359 
360         int str = fbb.createString("MyMonster");
361 
362         int inv = Monster.createInventoryVector(fbb, new byte[] { 0, 1, 2, 3, 4 });
363 
364         int fred = fbb.createString("Fred");
365         Monster.startMonster(fbb);
366         Monster.addName(fbb, fred);
367         int mon2 = Monster.endMonster(fbb);
368 
369         Monster.startTest4Vector(fbb, 2);
370         Test.createTest(fbb, (short)10, (byte)20);
371         Test.createTest(fbb, (short)30, (byte)40);
372         int test4 = fbb.endVector();
373 
374         int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] {
375                 fbb.createString("test1"),
376                 fbb.createString("test2")
377         });
378 
379         Monster.startMonster(fbb);
380         Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
381                 Color.Green, (short)5, (byte)6));
382         Monster.addHp(fbb, (short)80);
383         Monster.addName(fbb, str);
384         Monster.addInventory(fbb, inv);
385         Monster.addTestType(fbb, (byte)Any.Monster);
386         Monster.addTest(fbb, mon2);
387         Monster.addTest4(fbb, test4);
388         Monster.addTestarrayofstring(fbb, testArrayOfString);
389         Monster.addTestbool(fbb, true);
390         Monster.addTesthashu32Fnv1(fbb, Integer.MAX_VALUE + 1L);
391         Monster.addTestarrayoftables(fbb, sortMons);
392         int mon = Monster.endMonster(fbb);
393 
394         if (sizePrefix) {
395             Monster.finishSizePrefixedMonsterBuffer(fbb, mon);
396         } else {
397             Monster.finishMonsterBuffer(fbb, mon);
398         }
399 
400         // Write the result to a file for debugging purposes:
401         // Note that the binaries are not necessarily identical, since the JSON
402         // parser may serialize in a slightly different order than the above
403         // Java code. They are functionally equivalent though.
404 
405         try {
406             String filename = "monsterdata_java_wire" + (sizePrefix ? "_sp" : "") + ".mon";
407             FileChannel fc = new FileOutputStream(filename).getChannel();
408             fc.write(fbb.dataBuffer().duplicate());
409             fc.close();
410         } catch(java.io.IOException e) {
411             System.out.println("FlatBuffers test: couldn't write file");
412             return;
413         }
414 
415         // Test it:
416         ByteBuffer dataBuffer = fbb.dataBuffer();
417         if (sizePrefix) {
418             TestEq(ByteBufferUtil.getSizePrefix(dataBuffer) + SIZE_PREFIX_LENGTH,
419                    dataBuffer.remaining());
420             dataBuffer = ByteBufferUtil.removeSizePrefix(dataBuffer);
421         }
422         TestExtendedBuffer(dataBuffer);
423 
424         // Make sure it also works with read only ByteBuffers. This is slower,
425         // since creating strings incurs an additional copy
426         // (see Table.__string).
427         TestExtendedBuffer(dataBuffer.asReadOnlyBuffer());
428 
429         TestEnums();
430 
431         //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
432         // revert to original values after testing
433         Monster monster = Monster.getRootAsMonster(dataBuffer);
434 
435         // mana is optional and does not exist in the buffer so the mutation should fail
436         // the mana field should retain its default value
437         TestEq(monster.mutateMana((short)10), false);
438         TestEq(monster.mana(), (short)150);
439 
440         // Accessing a vector of sorted by the key tables
441         TestEq(monster.testarrayoftables(0).name(), "Barney");
442         TestEq(monster.testarrayoftables(1).name(), "Frodo");
443         TestEq(monster.testarrayoftables(2).name(), "Wilma");
444         Monster.Vector testarrayoftablesVector = monster.testarrayoftablesVector();
445         TestEq(testarrayoftablesVector.get(0).name(), "Barney");
446         TestEq(testarrayoftablesVector.get(1).name(), "Frodo");
447         TestEq(testarrayoftablesVector.get(2).name(), "Wilma");
448 
449         // Example of searching for a table by the key
450         TestEq(monster.testarrayoftablesByKey("Frodo").name(), "Frodo");
451         TestEq(monster.testarrayoftablesByKey("Barney").name(), "Barney");
452         TestEq(monster.testarrayoftablesByKey("Wilma").name(), "Wilma");
453         TestEq(testarrayoftablesVector.getByKey("Frodo").name(), "Frodo");
454         TestEq(testarrayoftablesVector.getByKey("Barney").name(), "Barney");
455         TestEq(testarrayoftablesVector.getByKey("Wilma").name(), "Wilma");
456 
457         // testType is an existing field and mutating it should succeed
458         TestEq(monster.testType(), (byte)Any.Monster);
459 
460         //mutate the inventory vector
461         TestEq(monster.mutateInventory(0, 1), true);
462         TestEq(monster.mutateInventory(1, 2), true);
463         TestEq(monster.mutateInventory(2, 3), true);
464         TestEq(monster.mutateInventory(3, 4), true);
465         TestEq(monster.mutateInventory(4, 5), true);
466 
467         for (int i = 0; i < monster.inventoryLength(); i++) {
468             TestEq(monster.inventory(i), i + 1);
469         }
470         ByteVector inventoryVector =  monster.inventoryVector();
471         for (int i = 0; i < inventoryVector.length(); i++) {
472             TestEq((int)inventoryVector.get(i), i + 1);
473         }
474 
475         //reverse mutation
476         TestEq(monster.mutateInventory(0, 0), true);
477         TestEq(monster.mutateInventory(1, 1), true);
478         TestEq(monster.mutateInventory(2, 2), true);
479         TestEq(monster.mutateInventory(3, 3), true);
480         TestEq(monster.mutateInventory(4, 4), true);
481 
482         // get a struct field and edit one of its fields
483         Vec3 pos = monster.pos();
484         TestEq(pos.x(), 1.0f);
485         pos.mutateX(55.0f);
486         TestEq(pos.x(), 55.0f);
487         pos.mutateX(1.0f);
488         TestEq(pos.x(), 1.0f);
489     }
490 
TestVectorOfUnions()491     static void TestVectorOfUnions() {
492         final FlatBufferBuilder fbb = new FlatBufferBuilder();
493 
494         final int swordAttackDamage = 1;
495 
496         final int[] characterVector = new int[] {
497             Attacker.createAttacker(fbb, swordAttackDamage),
498         };
499 
500         final byte[] characterTypeVector = new byte[]{
501             Character.MuLan,
502         };
503 
504         Movie.finishMovieBuffer(
505             fbb,
506             Movie.createMovie(
507                 fbb,
508                 (byte)0,
509                 (byte)0,
510                 Movie.createCharactersTypeVector(fbb, characterTypeVector),
511                 Movie.createCharactersVector(fbb, characterVector)
512             )
513         );
514 
515         final Movie movie = Movie.getRootAsMovie(fbb.dataBuffer());
516         ByteVector charactersTypeByteVector = movie.charactersTypeVector();
517         UnionVector charactersVector = movie.charactersVector();
518 
519         TestEq(movie.charactersTypeLength(), characterTypeVector.length);
520         TestEq(charactersTypeByteVector.length(), characterTypeVector.length);
521         TestEq(movie.charactersLength(), characterVector.length);
522         TestEq(charactersVector.length(), characterVector.length);
523 
524         TestEq(movie.charactersType(0), characterTypeVector[0]);
525         TestEq(charactersTypeByteVector.get(0), characterTypeVector[0]);
526 
527         TestEq(((Attacker)movie.characters(new Attacker(), 0)).swordAttackDamage(), swordAttackDamage);
528     }
529 
TestFixedLengthArrays()530     static void TestFixedLengthArrays() {
531         FlatBufferBuilder builder = new FlatBufferBuilder(0);
532 
533         float       a;
534         int[]       b = new int[15];
535         byte        c;
536         int[][]     d_a = new int[2][2];
537         byte[]      d_b = new byte[2];
538         byte[][]    d_c = new byte[2][2];
539         long[][]    d_d = new long[2][2];
540         int         e;
541         long[]      f = new long[2];
542 
543         a = 0.5f;
544         for (int i = 0; i < 15; i++) b[i] = i;
545         c = 1;
546         d_a[0][0] = 1;
547         d_a[0][1] = 2;
548         d_a[1][0] = 3;
549         d_a[1][1] = 4;
550         d_b[0] = TestEnum.B;
551         d_b[1] = TestEnum.C;
552         d_c[0][0] = TestEnum.A;
553         d_c[0][1] = TestEnum.B;
554         d_c[1][0] = TestEnum.C;
555         d_c[1][1] = TestEnum.B;
556         d_d[0][0] = -1;
557         d_d[0][1] = 1;
558         d_d[1][0] = -2;
559         d_d[1][1] = 2;
560         e = 2;
561         f[0] = -1;
562         f[1] = 1;
563 
564         int arrayOffset = ArrayStruct.createArrayStruct(builder,
565             a, b, c, d_a, d_b, d_c, d_d, e, f);
566 
567         // Create a table with the ArrayStruct.
568         ArrayTable.startArrayTable(builder);
569         ArrayTable.addA(builder, arrayOffset);
570         int tableOffset = ArrayTable.endArrayTable(builder);
571 
572         ArrayTable.finishArrayTableBuffer(builder, tableOffset);
573 
574         ArrayTable table = ArrayTable.getRootAsArrayTable(builder.dataBuffer());
575         NestedStruct nested = new NestedStruct();
576 
577         TestEq(table.a().a(), 0.5f);
578         for (int i = 0; i < 15; i++) TestEq(table.a().b(i), i);
579         TestEq(table.a().c(), (byte)1);
580         TestEq(table.a().d(nested, 0).a(0), 1);
581         TestEq(table.a().d(nested, 0).a(1), 2);
582         TestEq(table.a().d(nested, 1).a(0), 3);
583         TestEq(table.a().d(nested, 1).a(1), 4);
584         TestEq(table.a().d(nested, 0).b(), TestEnum.B);
585         TestEq(table.a().d(nested, 1).b(), TestEnum.C);
586         TestEq(table.a().d(nested, 0).c(0), TestEnum.A);
587         TestEq(table.a().d(nested, 0).c(1), TestEnum.B);
588         TestEq(table.a().d(nested, 1).c(0), TestEnum.C);
589         TestEq(table.a().d(nested, 1).c(1), TestEnum.B);
590         TestEq(table.a().d(nested, 0).d(0), (long)-1);
591         TestEq(table.a().d(nested, 0).d(1), (long)1);
592         TestEq(table.a().d(nested, 1).d(0), (long)-2);
593         TestEq(table.a().d(nested, 1).d(1), (long)2);
594         TestEq(table.a().e(), 2);
595         TestEq(table.a().f(0), (long)-1);
596         TestEq(table.a().f(1), (long)1);
597     }
598 
testFlexBuffersTest()599     public static void testFlexBuffersTest() {
600         FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
601                 FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
602         testFlexBuffersTest(builder);
603         int bufferLimit1 = ((ArrayReadWriteBuf) builder.getBuffer()).limit();
604 
605         // Repeat after clearing the builder to ensure the builder is reusable
606         builder.clear();
607         testFlexBuffersTest(builder);
608         int bufferLimit2 = ((ArrayReadWriteBuf) builder.getBuffer()).limit();
609         TestEq(bufferLimit1, bufferLimit2);
610     }
611 
testFlexBuffersTest(FlexBuffersBuilder builder)612     public static void testFlexBuffersTest(FlexBuffersBuilder builder) {
613         // Write the equivalent of:
614         // { vec: [ -100, "Fred", 4.0, false ], bar: [ 1, 2, 3 ], bar3: [ 1, 2, 3 ],
615         // foo: 100, bool: true, mymap: { foo: "Fred" } }
616         // It's possible to do this without std::function support as well.
617         int map1 = builder.startMap();
618 
619         int vec1 = builder.startVector();
620         builder.putInt(-100);
621         builder.putString("Fred");
622         builder.putBlob(new byte[]{(byte) 77});
623         builder.putBoolean(false);
624         builder.putInt(Long.MAX_VALUE);
625 
626         int map2 = builder.startMap();
627         builder.putInt("test", 200);
628         builder.endMap(null, map2);
629 
630         builder.putFloat(150.9);
631         builder.putFloat(150.9999998);
632         builder.endVector("vec", vec1, false, false);
633 
634         vec1 = builder.startVector();
635         builder.putInt(1);
636         builder.putInt(2);
637         builder.putInt(3);
638         builder.endVector("bar", vec1, true, false);
639 
640         vec1 = builder.startVector();
641         builder.putBoolean(true);
642         builder.putBoolean(false);
643         builder.putBoolean(true);
644         builder.putBoolean(false);
645         builder.endVector("bools", vec1, true, false);
646 
647         builder.putBoolean("bool", true);
648         builder.putFloat("foo", 100);
649 
650         map2 = builder.startMap();
651         builder.putString("bar", "Fred");  // Testing key and string reuse.
652         builder.putInt("int", -120);
653         builder.putFloat("float", -123.0f);
654         builder.putBlob("blob", new byte[]{ 65, 67 });
655         builder.endMap("mymap", map2);
656 
657         builder.endMap(null, map1);
658         builder.finish();
659 
660         FlexBuffers.Map m = FlexBuffers.getRoot(builder.getBuffer()).asMap();
661 
662         TestEq(m.size(), 6);
663 
664         // test empty (an null)
665         TestEq(m.get("no_key").asString(), ""); // empty if fail
666         TestEq(m.get("no_key").asMap(), FlexBuffers.Map.empty()); // empty if fail
667         TestEq(m.get("no_key").asKey(), FlexBuffers.Key.empty()); // empty if fail
668         TestEq(m.get("no_key").asVector(), FlexBuffers.Vector.empty()); // empty if fail
669         TestEq(m.get("no_key").asBlob(), FlexBuffers.Blob.empty()); // empty if fail
670         assert(m.get("no_key").asVector().isEmpty()); // empty if fail
671 
672         // testing "vec" field
673         FlexBuffers.Vector vec = m.get("vec").asVector();
674         TestEq(vec.size(), 8);
675         TestEq(vec.get(0).asLong(), (long) -100);
676         TestEq(vec.get(1).asString(), "Fred");
677         TestEq(vec.get(2).isBlob(), true);
678         TestEq(vec.get(2).asBlob().size(), 1);
679         TestEq(vec.get(2).asBlob().data().get(0), (byte) 77);
680         TestEq(vec.get(3).isBoolean(), true);   // Check if type is a bool
681         TestEq(vec.get(3).asBoolean(), false);  // Check if value is false
682         TestEq(vec.get(4).asLong(), Long.MAX_VALUE);
683         TestEq(vec.get(5).isMap(), true);
684         TestEq(vec.get(5).asMap().get("test").asInt(), 200);
685         TestEq(Float.compare((float)vec.get(6).asFloat(), 150.9f), 0);
686         TestEq(Double.compare(vec.get(7).asFloat(), 150.9999998), 0);
687         TestEq((long)0, (long)vec.get(1).asLong()); //conversion fail returns 0 as C++
688 
689         // bar vector
690         FlexBuffers.Vector tvec = m.get("bar").asVector();
691         TestEq(tvec.size(), 3);
692         TestEq(tvec.get(0).asInt(), 1);
693         TestEq(tvec.get(1).asInt(), 2);
694         TestEq(tvec.get(2).asInt(), 3);
695         TestEq(((FlexBuffers.TypedVector) tvec).getElemType(), FlexBuffers.FBT_INT);
696 
697         // bools vector
698         FlexBuffers.Vector bvec = m.get("bools").asVector();
699         TestEq(bvec.size(), 4);
700         TestEq(bvec.get(0).asBoolean(), true);
701         TestEq(bvec.get(1).asBoolean(), false);
702         TestEq(bvec.get(2).asBoolean(), true);
703         TestEq(bvec.get(3).asBoolean(), false);
704         TestEq(((FlexBuffers.TypedVector) bvec).getElemType(), FlexBuffers.FBT_BOOL);
705 
706 
707         TestEq((float)m.get("foo").asFloat(), (float) 100);
708         TestEq(m.get("unknown").isNull(), true);
709 
710         // mymap vector
711         FlexBuffers.Map mymap = m.get("mymap").asMap();
712         TestEq(mymap.keys().get(0), m.keys().get(0)); // These should be equal by pointer equality, since key and value are shared.
713         TestEq(mymap.keys().get(0).toString(), "bar");
714         TestEq(mymap.values().get(0).asString(), vec.get(1).asString());
715         TestEq(mymap.get("int").asInt(), -120);
716         TestEq((float)mymap.get("float").asFloat(), -123.0f);
717         TestEq(Arrays.equals(mymap.get("blob").asBlob().getBytes(), new byte[]{ 65, 67 }), true);
718         TestEq(mymap.get("blob").asBlob().toString(), "AC");
719         TestEq(mymap.get("blob").toString(), "\"AC\"");
720     }
721 
testFlexBufferVectorStrings()722     public static void testFlexBufferVectorStrings() {
723         FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000000));
724 
725         int size = 3000;
726         StringBuilder sb = new StringBuilder();
727         for (int i=0; i< size; i++) {
728             sb.append("a");
729         }
730 
731         String text = sb.toString();
732         TestEq(text.length(), size);
733 
734         int pos = builder.startVector();
735 
736         for (int i=0; i<size; i++) {
737             builder.putString(text);
738         }
739 
740         try {
741             builder.endVector(null, pos, true, false);
742             // this should raise an exception as
743             // typed vector of string was deprecated
744             assert false;
745         } catch(FlexBufferException fb) {
746             // no op
747         }
748         // we finish the vector again as non-typed
749         builder.endVector(null, pos, false, false);
750 
751         ByteBuffer b = builder.finish();
752         Vector v = FlexBuffers.getRoot(b).asVector();
753 
754         TestEq(v.size(), size);
755         for (int i=0; i<size; i++) {
756             TestEq(v.get(i).asString().length(), size);
757             TestEq(v.get(i).asString(), text);
758         }
759     }
760 
testDeprecatedTypedVectorString()761     public static void testDeprecatedTypedVectorString() {
762         // tests whether we are able to support reading deprecated typed vector string
763         // data is equivalent to [ "abc", "abc", "abc", "abc"]
764         byte[] data = new byte[] {0x03, 0x61, 0x62, 0x63, 0x00, 0x03, 0x61, 0x62, 0x63, 0x00,
765             0x03, 0x61, 0x62, 0x63, 0x00, 0x03, 0x61, 0x62, 0x63, 0x00, 0x04, 0x14, 0x10,
766              0x0c, 0x08, 0x04, 0x3c, 0x01};
767         Reference ref = FlexBuffers.getRoot(ByteBuffer.wrap(data));
768         TestEq(ref.getType(), FlexBuffers.FBT_VECTOR_STRING_DEPRECATED);
769         TestEq(ref.isTypedVector(), true);
770         Vector vec = ref.asVector();
771         for (int i=0; i< vec.size(); i++) {
772             TestEq("abc", vec.get(i).asString());
773         }
774     }
775 
testSingleElementBoolean()776     public static void testSingleElementBoolean() {
777         FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(100));
778         builder.putBoolean(true);
779         ByteBuffer b = builder.finish();
780         assert(FlexBuffers.getRoot(b).asBoolean());
781     }
782 
testSingleElementByte()783     public static void testSingleElementByte() {
784         FlexBuffersBuilder builder = new FlexBuffersBuilder();
785         builder.putInt(10);
786         ByteBuffer b = builder.finish();
787         TestEq(10, FlexBuffers.getRoot(b).asInt());
788     }
789 
testSingleElementShort()790     public static void testSingleElementShort() {
791         FlexBuffersBuilder builder = new FlexBuffersBuilder();
792         builder.putInt(Short.MAX_VALUE);
793         ByteBuffer b = builder.finish();
794         TestEq(Short.MAX_VALUE, (short)FlexBuffers.getRoot(b).asInt());
795     }
796 
testSingleElementInt()797     public static void testSingleElementInt() {
798         FlexBuffersBuilder builder = new FlexBuffersBuilder();
799         builder.putInt(Integer.MIN_VALUE);
800         ByteBuffer b = builder.finish();
801         TestEq(Integer.MIN_VALUE, FlexBuffers.getRoot(b).asInt());
802     }
803 
testSingleElementLong()804     public static void testSingleElementLong() {
805         FlexBuffersBuilder builder = new FlexBuffersBuilder();
806         builder.putInt(Long.MAX_VALUE);
807         ByteBuffer b = builder.finish();
808         TestEq(Long.MAX_VALUE, FlexBuffers.getRoot(b).asLong());
809     }
810 
testSingleElementFloat()811     public static void testSingleElementFloat() {
812         FlexBuffersBuilder builder = new FlexBuffersBuilder();
813         builder.putFloat(Float.MAX_VALUE);
814         ByteBuffer b = builder.finish();
815         TestEq(Float.compare(Float.MAX_VALUE, (float) FlexBuffers.getRoot(b).asFloat()), 0);
816     }
817 
testSingleElementDouble()818     public static void testSingleElementDouble() {
819         FlexBuffersBuilder builder = new FlexBuffersBuilder();
820         builder.putFloat(Double.MAX_VALUE);
821         ByteBuffer b = builder.finish();
822         TestEq(Double.compare(Double.MAX_VALUE, FlexBuffers.getRoot(b).asFloat()), 0);
823     }
824 
testSingleElementBigString()825     public static void testSingleElementBigString() {
826         FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000));
827         StringBuilder sb = new StringBuilder();
828 
829         for (int i=0; i< 3000; i++) {
830             sb.append("a");
831         }
832 
833         builder.putString(sb.toString());
834         ByteBuffer b = builder.finish();
835 
836         FlexBuffers.Reference r = FlexBuffers.getRoot(b);
837 
838         TestEq(FlexBuffers.FBT_STRING, r.getType());
839         TestEq(sb.toString(), r.asString());
840     }
841 
testSingleElementSmallString()842     public static void testSingleElementSmallString() {
843         FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000));
844 
845         builder.putString("aa");
846         ByteBuffer b = builder.finish();
847         FlexBuffers.Reference r = FlexBuffers.getRoot(b);
848 
849         TestEq(FlexBuffers.FBT_STRING, r.getType());
850         TestEq("aa", r.asString());
851     }
852 
testSingleElementBlob()853     public static void testSingleElementBlob() {
854         FlexBuffersBuilder builder = new FlexBuffersBuilder();
855         builder.putBlob(new byte[]{5, 124, 118, -1});
856         ByteBuffer b = builder.finish();
857         FlexBuffers.Reference r = FlexBuffers.getRoot(b);
858         byte[] result = r.asBlob().getBytes();
859         TestEq((byte)5, result[0]);
860         TestEq((byte)124, result[1]);
861         TestEq((byte)118, result[2]);
862         TestEq((byte)-1, result[3]);
863     }
864 
testSingleElementUByte()865     public static void testSingleElementUByte() {
866         FlexBuffersBuilder builder = new FlexBuffersBuilder();
867         builder.putUInt(0xFF);
868         ByteBuffer b = builder.finish();
869         FlexBuffers.Reference r = FlexBuffers.getRoot(b);
870         TestEq(255, (int)r.asUInt());
871     }
872 
testSingleElementUShort()873     public static void testSingleElementUShort() {
874         FlexBuffersBuilder builder = new FlexBuffersBuilder();
875         builder.putUInt(0xFFFF);
876         ByteBuffer b = builder.finish();
877         FlexBuffers.Reference r = FlexBuffers.getRoot(b);
878         TestEq(65535, (int)r.asUInt());
879     }
880 
testSingleElementUInt()881     public static void testSingleElementUInt() {
882         FlexBuffersBuilder builder = new FlexBuffersBuilder();
883         builder.putUInt(0xFFFF_FFFFL);
884         ByteBuffer b = builder.finish();
885         FlexBuffers.Reference r = FlexBuffers.getRoot(b);
886         TestEq(4294967295L, r.asUInt());
887     }
888 
testSingleFixedTypeVector()889     public static void testSingleFixedTypeVector() {
890 
891         int[] ints = new int[]{5, 124, 118, -1};
892         float[] floats = new float[]{5.5f, 124.124f, 118.118f, -1.1f};
893         String[] strings = new String[]{"This", "is", "a", "typed", "array"};
894         boolean[] booleans = new boolean[]{false, true, true, false};
895 
896 
897         FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
898                 FlexBuffersBuilder.BUILDER_FLAG_NONE);
899 
900         int mapPos = builder.startMap();
901 
902         int vecPos = builder.startVector();
903         for (final int i : ints) {
904             builder.putInt(i);
905         }
906         builder.endVector("ints", vecPos, true, false);
907 
908         vecPos = builder.startVector();
909         for (final float i : floats) {
910             builder.putFloat(i);
911         }
912         builder.endVector("floats", vecPos, true, false);
913 
914         vecPos = builder.startVector();
915         for (final boolean i : booleans) {
916             builder.putBoolean(i);
917         }
918         builder.endVector("booleans", vecPos, true, false);
919 
920         builder.endMap(null, mapPos);
921 
922 
923         ByteBuffer b = builder.finish();
924         FlexBuffers.Reference r = FlexBuffers.getRoot(b);
925         assert(r.asMap().get("ints").isTypedVector());
926         assert(r.asMap().get("floats").isTypedVector());
927         assert(r.asMap().get("booleans").isTypedVector());
928     }
929 
testSingleElementVector()930     public static void testSingleElementVector() {
931         FlexBuffersBuilder b = new FlexBuffersBuilder();
932 
933         int vecPos = b.startVector();
934         b.putInt(99);
935         b.putString("wow");
936         int vecpos2 = b.startVector();
937         b.putInt(99);
938         b.putString("wow");
939         b.endVector(null, vecpos2, false, false);
940         b.endVector(null, vecPos, false, false);
941         b.finish();
942 
943         FlexBuffers.Reference r = FlexBuffers.getRoot(b.getBuffer());
944         TestEq(FlexBuffers.FBT_VECTOR, r.getType());
945         FlexBuffers.Vector vec = FlexBuffers.getRoot(b.getBuffer()).asVector();
946         TestEq(3, vec.size());
947         TestEq(99, vec.get(0).asInt());
948         TestEq("wow", vec.get(1).asString());
949         TestEq("[ 99, \"wow\" ]", vec.get(2).toString());
950         TestEq("[ 99, \"wow\", [ 99, \"wow\" ] ]", FlexBuffers.getRoot(b.getBuffer()).toString());
951     }
952 
testSingleElementMap()953     public static void testSingleElementMap() {
954         FlexBuffersBuilder b = new FlexBuffersBuilder();
955 
956         int mapPost = b.startMap();
957         b.putInt("myInt", 0x7fffffbbbfffffffL);
958         b.putString("myString", "wow");
959         b.putString("myString2", "incredible");
960         int start = b.startVector();
961         b.putInt(99);
962         b.putString("wow");
963         b.endVector("myVec", start, false, false);
964 
965         b.putFloat("double", 0x1.ffffbbbffffffP+1023);
966         b.endMap(null, mapPost);
967         b.finish();
968 
969         FlexBuffers.Reference r = FlexBuffers.getRoot(b.getBuffer());
970         TestEq(FlexBuffers.FBT_MAP, r.getType());
971         FlexBuffers.Map map = FlexBuffers.getRoot(b.getBuffer()).asMap();
972         TestEq(5, map.size());
973         TestEq(0x7fffffbbbfffffffL, map.get("myInt").asLong());
974         TestEq("wow", map.get("myString").asString());
975         TestEq("incredible", map.get("myString2").asString());
976         TestEq(99, map.get("myVec").asVector().get(0).asInt());
977         TestEq("wow", map.get("myVec").asVector().get(1).asString());
978         TestEq(Double.compare(0x1.ffffbbbffffffP+1023, map.get("double").asFloat()), 0);
979         TestEq("{ \"double\" : 1.7976894783391937E308, \"myInt\" : 9223371743723257855, \"myString\" : \"wow\", \"myString2\" : \"incredible\", \"myVec\" : [ 99, \"wow\" ] }",
980                 FlexBuffers.getRoot(b.getBuffer()).toString());
981     }
982 
testFlexBuferEmpty()983     public static void testFlexBuferEmpty() {
984         FlexBuffers.Blob blob = FlexBuffers.Blob.empty();
985         FlexBuffers.Map ary = FlexBuffers.Map.empty();
986         FlexBuffers.Vector map = FlexBuffers.Vector.empty();
987         FlexBuffers.TypedVector typedAry = FlexBuffers.TypedVector.empty();
988         TestEq(blob.size(), 0);
989         TestEq(map.size(), 0);
990         TestEq(ary.size(), 0);
991         TestEq(typedAry.size(), 0);
992     }
993 
testHashMapToMap()994     public static void testHashMapToMap() {
995         int entriesCount = 12;
996 
997         HashMap<String, String> source =  new HashMap<>();
998         for (int i = 0; i < entriesCount; i++) {
999             source.put("foo_param_" + i, "foo_value_" + i);
1000         }
1001 
1002         FlexBuffersBuilder builder = new FlexBuffersBuilder(1000);
1003         int mapStart = builder.startMap();
1004         for (Map.Entry<String, String> entry : source.entrySet()) {
1005             builder.putString(entry.getKey(), entry.getValue());
1006         }
1007         builder.endMap(null, mapStart);
1008         ByteBuffer bb = builder.finish();
1009         bb.rewind();
1010 
1011         FlexBuffers.Reference rootReference = FlexBuffers.getRoot(bb);
1012 
1013         TestEq(rootReference.isMap(), true);
1014 
1015         FlexBuffers.Map flexMap = rootReference.asMap();
1016 
1017         FlexBuffers.KeyVector keys = flexMap.keys();
1018         FlexBuffers.Vector values = flexMap.values();
1019 
1020         TestEq(entriesCount, keys.size());
1021         TestEq(entriesCount, values.size());
1022 
1023         HashMap<String, String> result =  new HashMap<>();
1024         for (int i = 0; i < keys.size(); i++) {
1025             result.put(keys.get(i).toString(), values.get(i).asString());
1026         }
1027 
1028         TestEq(source, result);
1029     }
1030 
testBuilderGrowth()1031     public static void testBuilderGrowth() {
1032         FlexBuffersBuilder builder = new FlexBuffersBuilder();
1033         String someString = "This is a small string";
1034         builder.putString(someString);
1035         ByteBuffer b = builder.finish();
1036         TestEq(someString, FlexBuffers.getRoot(b).asString());
1037 
1038         FlexBuffersBuilder failBuilder = new FlexBuffersBuilder(ByteBuffer.allocate(1));
1039         failBuilder.putString(someString);
1040     }
1041 
testFlexBuffersUtf8Map()1042     public static void testFlexBuffersUtf8Map() {
1043         FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
1044                 FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
1045 
1046         String key0 = "�� face1";
1047         String key1 = "�� face2";
1048         String key2 = "�� face3";
1049         String key3 = "trademark ®";
1050         String key4 = "€ euro";
1051         String utf8keys[] = { "�� face1", "�� face2", "�� face3", "trademark ®", "€ euro"};
1052 
1053         int map = builder.startMap();
1054 
1055         for (int i=0; i< utf8keys.length; i++) {
1056             builder.putString(utf8keys[i], utf8keys[i]);  // Testing key and string reuse.
1057         }
1058         builder.endMap(null, map);
1059         builder.finish();
1060 
1061         FlexBuffers.Map m = FlexBuffers.getRoot(builder.getBuffer()).asMap();
1062 
1063         TestEq(m.size(), 5);
1064 
1065         KeyVector kv = m.keys();
1066         for (int i=0; i< utf8keys.length; i++) {
1067             TestEq(kv.get(i).toString(), m.get(i).asString());
1068         }
1069 
1070         TestEq(m.get(key0).asString(), utf8keys[0]);
1071         TestEq(m.get(key1).asString(), utf8keys[1]);
1072         TestEq(m.get(key2).asString(), utf8keys[2]);
1073         TestEq(m.get(key3).asString(), utf8keys[3]);
1074         TestEq(m.get(key4).asString(), utf8keys[4]);
1075     }
1076 
TestFlexBuffers()1077     public static void TestFlexBuffers() {
1078         testSingleElementByte();
1079         testSingleElementShort();
1080         testSingleElementInt();
1081         testSingleElementLong();
1082         testSingleElementFloat();
1083         testSingleElementDouble();
1084         testSingleElementSmallString();
1085         testSingleElementBigString();
1086         testSingleElementBlob();
1087         testSingleElementVector();
1088         testSingleFixedTypeVector();
1089         testSingleElementUShort();
1090         testSingleElementUInt();
1091         testSingleElementUByte();
1092         testSingleElementMap();
1093         testFlexBuffersTest();
1094         testHashMapToMap();
1095         testFlexBuferEmpty();
1096         testFlexBufferVectorStrings();
1097         testDeprecatedTypedVectorString();
1098         testBuilderGrowth();
1099         testFlexBuffersUtf8Map();
1100     }
1101 
TestVectorOfBytes()1102     static void TestVectorOfBytes() {
1103         FlatBufferBuilder fbb = new FlatBufferBuilder(16);
1104         int str = fbb.createString("ByteMonster");
1105         byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
1106         int offset = Monster.createInventoryVector(fbb, data);
1107         Monster.startMonster(fbb);
1108         Monster.addName(fbb, str);
1109         Monster.addInventory(fbb, offset);
1110         int monster1 = Monster.endMonster(fbb);
1111         Monster.finishMonsterBuffer(fbb, monster1);
1112         Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
1113 
1114         TestEq(monsterObject.inventoryLength(), data.length);
1115         TestEq(monsterObject.inventory(4), (int) data[4]);
1116         TestEq(ByteBuffer.wrap(data), monsterObject.inventoryAsByteBuffer());
1117 
1118         fbb.clear();
1119         ByteBuffer bb = ByteBuffer.wrap(data);
1120         offset = fbb.createByteVector(bb);
1121         str = fbb.createString("ByteMonster");
1122         Monster.startMonster(fbb);
1123         Monster.addName(fbb, str);
1124         Monster.addInventory(fbb, offset);
1125         monster1 = Monster.endMonster(fbb);
1126         Monster.finishMonsterBuffer(fbb, monster1);
1127         Monster monsterObject2 = Monster.getRootAsMonster(fbb.dataBuffer());
1128 
1129         TestEq(monsterObject2.inventoryLength(), data.length);
1130         for (int i = 0; i < data.length; i++) {
1131           TestEq(monsterObject2.inventory(i), (int) bb.get(i));
1132         }
1133 
1134         fbb.clear();
1135         offset = fbb.createByteVector(data, 3, 4);
1136         str = fbb.createString("ByteMonster");
1137         Monster.startMonster(fbb);
1138         Monster.addName(fbb, str);
1139         Monster.addInventory(fbb, offset);
1140         monster1 = Monster.endMonster(fbb);
1141         Monster.finishMonsterBuffer(fbb, monster1);
1142         Monster monsterObject3 = Monster.getRootAsMonster(fbb.dataBuffer());
1143 
1144         TestEq(monsterObject3.inventoryLength(), 4);
1145         TestEq(monsterObject3.inventory(0), (int) data[3]);
1146 
1147         fbb.clear();
1148         bb = ByteBuffer.wrap(data);
1149         offset = Monster.createInventoryVector(fbb, bb);
1150         str = fbb.createString("ByteMonster");
1151         Monster.startMonster(fbb);
1152         Monster.addName(fbb, str);
1153         Monster.addInventory(fbb, offset);
1154         monster1 = Monster.endMonster(fbb);
1155         Monster.finishMonsterBuffer(fbb, monster1);
1156         Monster monsterObject4 = Monster.getRootAsMonster(fbb.dataBuffer());
1157 
1158         TestEq(monsterObject4.inventoryLength(), data.length);
1159         TestEq(monsterObject4.inventory(8), (int) 8);
1160 
1161         fbb.clear();
1162         byte[] largeData = new byte[1024];
1163         offset = fbb.createByteVector(largeData);
1164         str = fbb.createString("ByteMonster");
1165         Monster.startMonster(fbb);
1166         Monster.addName(fbb, str);
1167         Monster.addInventory(fbb, offset);
1168         monster1 = Monster.endMonster(fbb);
1169         Monster.finishMonsterBuffer(fbb, monster1);
1170         Monster monsterObject5 = Monster.getRootAsMonster(fbb.dataBuffer());
1171 
1172         TestEq(monsterObject5.inventoryLength(), largeData.length);
1173         TestEq(monsterObject5.inventory(25), (int) largeData[25]);
1174 
1175         fbb.clear();
1176         bb = ByteBuffer.wrap(largeData);
1177         bb.position(512);
1178         ByteBuffer bb2 = bb.slice();
1179         TestEq(bb2.arrayOffset(), 512);
1180         offset = fbb.createByteVector(bb2);
1181         str = fbb.createString("ByteMonster");
1182         Monster.startMonster(fbb);
1183         Monster.addName(fbb, str);
1184         Monster.addInventory(fbb, offset);
1185         monster1 = Monster.endMonster(fbb);
1186         Monster.finishMonsterBuffer(fbb, monster1);
1187         Monster monsterObject6 = Monster.getRootAsMonster(fbb.dataBuffer());
1188 
1189         TestEq(monsterObject6.inventoryLength(), 512);
1190         TestEq(monsterObject6.inventory(0), (int) largeData[512]);
1191 
1192         fbb.clear();
1193         bb = ByteBuffer.wrap(largeData);
1194         bb.limit(256);
1195         offset = fbb.createByteVector(bb);
1196         str = fbb.createString("ByteMonster");
1197         Monster.startMonster(fbb);
1198         Monster.addName(fbb, str);
1199         Monster.addInventory(fbb, offset);
1200         monster1 = Monster.endMonster(fbb);
1201         Monster.finishMonsterBuffer(fbb, monster1);
1202         Monster monsterObject7 = Monster.getRootAsMonster(fbb.dataBuffer());
1203 
1204         TestEq(monsterObject7.inventoryLength(), 256);
1205 
1206         fbb.clear();
1207         bb = ByteBuffer.allocateDirect(2048);
1208         offset = fbb.createByteVector(bb);
1209         str = fbb.createString("ByteMonster");
1210         Monster.startMonster(fbb);
1211         Monster.addName(fbb, str);
1212         Monster.addInventory(fbb, offset);
1213         monster1 = Monster.endMonster(fbb);
1214         Monster.finishMonsterBuffer(fbb, monster1);
1215         Monster monsterObject8 = Monster.getRootAsMonster(fbb.dataBuffer());
1216 
1217         TestEq(monsterObject8.inventoryLength(), 2048);
1218     }
1219 
TestSharedStringPool()1220     static void TestSharedStringPool() {
1221         FlatBufferBuilder fb = new FlatBufferBuilder(1);
1222         String testString = "My string";
1223         int offset = fb.createSharedString(testString);
1224         for (int i=0; i< 10; i++) {
1225             TestEq(offset, fb.createSharedString(testString));
1226         }
1227     }
1228 
TestScalarOptional()1229     static void TestScalarOptional() {
1230         FlatBufferBuilder fbb = new FlatBufferBuilder(1);
1231         ScalarStuff.startScalarStuff(fbb);
1232         int pos = ScalarStuff.endScalarStuff(fbb);
1233         fbb.finish(pos);
1234 
1235         ScalarStuff scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer());
1236         TestEq(scalarStuff.justI8(), (byte)0);
1237         TestEq(scalarStuff.maybeI8(), (byte)0);
1238         TestEq(scalarStuff.defaultI8(), (byte)42);
1239         TestEq(scalarStuff.justU8(), 0);
1240         TestEq(scalarStuff.maybeU8(), 0);
1241         TestEq(scalarStuff.defaultU8(), 42);
1242         TestEq(scalarStuff.justI16(), (short)0);
1243         TestEq(scalarStuff.maybeI16(), (short)0);
1244         TestEq(scalarStuff.defaultI16(), (short)42);
1245         TestEq(scalarStuff.justU16(), 0);
1246         TestEq(scalarStuff.maybeU16(), 0);
1247         TestEq(scalarStuff.defaultU16(), 42);
1248         TestEq(scalarStuff.justI32(), 0);
1249         TestEq(scalarStuff.maybeI32(), 0);
1250         TestEq(scalarStuff.defaultI32(), 42);
1251         TestEq(scalarStuff.justU32(), 0L);
1252         TestEq(scalarStuff.maybeU32(), 0L);
1253         TestEq(scalarStuff.defaultU32(), 42L);
1254         TestEq(scalarStuff.justI64(), 0L);
1255         TestEq(scalarStuff.maybeI64(), 0L);
1256         TestEq(scalarStuff.defaultI64(), 42L);
1257         TestEq(scalarStuff.justU64(), 0L);
1258         TestEq(scalarStuff.maybeU64(), 0L);
1259         TestEq(scalarStuff.defaultU64(), 42L);
1260         TestEq(scalarStuff.justF32(), 0.0f);
1261         TestEq(scalarStuff.maybeF32(), 0f);
1262         TestEq(scalarStuff.defaultF32(), 42.0f);
1263         TestEq(scalarStuff.justF64(), 0.0);
1264         TestEq(scalarStuff.maybeF64(), 0.0);
1265         TestEq(scalarStuff.defaultF64(), 42.0);
1266         TestEq(scalarStuff.justBool(), false);
1267         TestEq(scalarStuff.maybeBool(), false);
1268         TestEq(scalarStuff.defaultBool(), true);
1269         TestEq(scalarStuff.justEnum(), OptionalByte.None);
1270         TestEq(scalarStuff.maybeEnum(), OptionalByte.None);
1271         TestEq(scalarStuff.defaultEnum(), OptionalByte.One);
1272 
1273         TestEq(scalarStuff.hasMaybeI8(), false);
1274         TestEq(scalarStuff.hasMaybeI16(), false);
1275         TestEq(scalarStuff.hasMaybeI32(), false);
1276         TestEq(scalarStuff.hasMaybeI64(), false);
1277         TestEq(scalarStuff.hasMaybeU8(), false);
1278         TestEq(scalarStuff.hasMaybeU16(), false);
1279         TestEq(scalarStuff.hasMaybeU32(), false);
1280         TestEq(scalarStuff.hasMaybeU64(), false);
1281         TestEq(scalarStuff.hasMaybeF32(), false);
1282         TestEq(scalarStuff.hasMaybeF64(), false);
1283         TestEq(scalarStuff.hasMaybeBool(), false);
1284         TestEq(scalarStuff.hasMaybeEnum(), false);
1285 
1286         fbb.clear();
1287 
1288         ScalarStuff.startScalarStuff(fbb);
1289         ScalarStuff.addJustI8(fbb, (byte)5);
1290         ScalarStuff.addMaybeI8(fbb, (byte)5);
1291         ScalarStuff.addDefaultI8(fbb, (byte)5);
1292         ScalarStuff.addJustU8(fbb, 6);
1293         ScalarStuff.addMaybeU8(fbb, 6);
1294         ScalarStuff.addDefaultU8(fbb, 6);
1295         ScalarStuff.addJustI16(fbb, (short)7);
1296         ScalarStuff.addMaybeI16(fbb, (short)7);
1297         ScalarStuff.addDefaultI16(fbb, (short)7);
1298         ScalarStuff.addJustU16(fbb, 8);
1299         ScalarStuff.addMaybeU16(fbb, 8);
1300         ScalarStuff.addDefaultU16(fbb, 8);
1301         ScalarStuff.addJustI32(fbb, 9);
1302         ScalarStuff.addMaybeI32(fbb, 9);
1303         ScalarStuff.addDefaultI32(fbb, 9);
1304         ScalarStuff.addJustU32(fbb, (long)10);
1305         ScalarStuff.addMaybeU32(fbb, (long)10);
1306         ScalarStuff.addDefaultU32(fbb, (long)10);
1307         ScalarStuff.addJustI64(fbb, 11L);
1308         ScalarStuff.addMaybeI64(fbb, 11L);
1309         ScalarStuff.addDefaultI64(fbb, 11L);
1310         ScalarStuff.addJustU64(fbb, 12L);
1311         ScalarStuff.addMaybeU64(fbb, 12L);
1312         ScalarStuff.addDefaultU64(fbb, 12L);
1313         ScalarStuff.addJustF32(fbb, 13.0f);
1314         ScalarStuff.addMaybeF32(fbb, 13.0f);
1315         ScalarStuff.addDefaultF32(fbb, 13.0f);
1316         ScalarStuff.addJustF64(fbb, 14.0);
1317         ScalarStuff.addMaybeF64(fbb, 14.0);
1318         ScalarStuff.addDefaultF64(fbb, 14.0);
1319         ScalarStuff.addJustBool(fbb, true);
1320         ScalarStuff.addMaybeBool(fbb, true);
1321         ScalarStuff.addDefaultBool(fbb, true);
1322         ScalarStuff.addJustEnum(fbb, OptionalByte.Two);
1323         ScalarStuff.addMaybeEnum(fbb, OptionalByte.Two);
1324         ScalarStuff.addDefaultEnum(fbb, OptionalByte.Two);
1325 
1326         pos = ScalarStuff.endScalarStuff(fbb);
1327 
1328         fbb.finish(pos);
1329 
1330         scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer());
1331 
1332         TestEq(scalarStuff.justI8(), (byte)5);
1333         TestEq(scalarStuff.maybeI8(), (byte)5);
1334         TestEq(scalarStuff.defaultI8(), (byte)5);
1335         TestEq(scalarStuff.justU8(), 6);
1336         TestEq(scalarStuff.maybeU8(), 6);
1337         TestEq(scalarStuff.defaultU8(), 6);
1338         TestEq(scalarStuff.justI16(), (short)7);
1339         TestEq(scalarStuff.maybeI16(), (short)7);
1340         TestEq(scalarStuff.defaultI16(), (short)7);
1341         TestEq(scalarStuff.justU16(), 8);
1342         TestEq(scalarStuff.maybeU16(), 8);
1343         TestEq(scalarStuff.defaultU16(), 8);
1344         TestEq(scalarStuff.justI32(), 9);
1345         TestEq(scalarStuff.maybeI32(), 9);
1346         TestEq(scalarStuff.defaultI32(), 9);
1347         TestEq(scalarStuff.justU32(), 10L);
1348         TestEq(scalarStuff.maybeU32(), 10L);
1349         TestEq(scalarStuff.defaultU32(), 10L);
1350         TestEq(scalarStuff.justI64(), 11L);
1351         TestEq(scalarStuff.maybeI64(), 11L);
1352         TestEq(scalarStuff.defaultI64(), 11L);
1353         TestEq(scalarStuff.justU64(), 12L);
1354         TestEq(scalarStuff.maybeU64(), 12L);
1355         TestEq(scalarStuff.defaultU64(), 12L);
1356         TestEq(scalarStuff.justF32(), 13.0f);
1357         TestEq(scalarStuff.maybeF32(), 13.0f);
1358         TestEq(scalarStuff.defaultF32(), 13.0f);
1359         TestEq(scalarStuff.justF64(), 14.0);
1360         TestEq(scalarStuff.maybeF64(), 14.0);
1361         TestEq(scalarStuff.defaultF64(), 14.0);
1362         TestEq(scalarStuff.justBool(), true);
1363         TestEq(scalarStuff.maybeBool(), true);
1364         TestEq(scalarStuff.defaultBool(), true);
1365         TestEq(scalarStuff.justEnum(), OptionalByte.Two);
1366         TestEq(scalarStuff.maybeEnum(), OptionalByte.Two);
1367         TestEq(scalarStuff.defaultEnum(), OptionalByte.Two);
1368 
1369         TestEq(scalarStuff.hasMaybeI8(), true);
1370         TestEq(scalarStuff.hasMaybeI16(), true);
1371         TestEq(scalarStuff.hasMaybeI32(), true);
1372         TestEq(scalarStuff.hasMaybeI64(), true);
1373         TestEq(scalarStuff.hasMaybeU8(), true);
1374         TestEq(scalarStuff.hasMaybeU16(), true);
1375         TestEq(scalarStuff.hasMaybeU32(), true);
1376         TestEq(scalarStuff.hasMaybeU64(), true);
1377         TestEq(scalarStuff.hasMaybeF32(), true);
1378         TestEq(scalarStuff.hasMaybeF64(), true);
1379         TestEq(scalarStuff.hasMaybeBool(), true);
1380         TestEq(scalarStuff.hasMaybeEnum(), true);
1381     }
1382 
TestEq(T a, T b)1383     static <T> void TestEq(T a, T b) {
1384         if ((a == null && a != b) || (a != null && !a.equals(b))) {
1385             System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
1386             System.out.println("FlatBuffers test FAILED: \'" + a + "\' != \'" + b + "\'");
1387             new Throwable().printStackTrace();
1388             assert false;
1389             System.exit(1);
1390         }
1391     }
1392 
1393 }
1394