• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 Google Inc. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 using System.IO;
18 using System.Text;
19 using System.Threading;
20 using MyGame.Example;
21 using optional_scalars;
22 using KeywordTest;
23 
24 namespace Google.FlatBuffers.Test
25 {
26     [FlatBuffersTestClass]
27     public class FlatBuffersExampleTests
28     {
RunTests()29         public void RunTests()
30         {
31             CanCreateNewFlatBufferFromScratch();
32             CanReadCppGeneratedWireFile();
33             TestEnums();
34         }
35 
36         [FlatBuffersTestMethod]
CanCreateNewFlatBufferFromScratch()37         public void CanCreateNewFlatBufferFromScratch()
38         {
39             CanCreateNewFlatBufferFromScratch(true);
40             CanCreateNewFlatBufferFromScratch(false);
41         }
42 
CanCreateNewFlatBufferFromScratch(bool sizePrefix)43         private void CanCreateNewFlatBufferFromScratch(bool sizePrefix)
44         {
45             // Second, let's create a FlatBuffer from scratch in C#, and test it also.
46             // We use an initial size of 1 to exercise the reallocation algorithm,
47             // normally a size larger than the typical FlatBuffer you generate would be
48             // better for performance.
49             var fbb = new FlatBufferBuilder(1);
50 
51             StringOffset[] names = { fbb.CreateString("Frodo"), fbb.CreateString("Barney"), fbb.CreateString("Wilma") };
52             Offset<Monster>[] off = new Offset<Monster>[3];
53             Monster.StartMonster(fbb);
54             Monster.AddName(fbb, names[0]);
55             off[0] = Monster.EndMonster(fbb);
56             Monster.StartMonster(fbb);
57             Monster.AddName(fbb, names[1]);
58             off[1] = Monster.EndMonster(fbb);
59             Monster.StartMonster(fbb);
60             Monster.AddName(fbb, names[2]);
61             off[2] = Monster.EndMonster(fbb);
62             var sortMons = Monster.CreateSortedVectorOfMonster(fbb, off);
63 
64             // We set up the same values as monsterdata.json:
65 
66             var str = fbb.CreateString("MyMonster");
67             var test1 = fbb.CreateString("test1");
68             var test2 = fbb.CreateString("test2");
69 
70 
71             Monster.StartInventoryVector(fbb, 5);
72             for (int i = 4; i >= 0; i--)
73             {
74                 fbb.AddByte((byte)i);
75             }
76             var inv = fbb.EndVector();
77 
78             var fred = fbb.CreateString("Fred");
79             Monster.StartMonster(fbb);
80             Monster.AddName(fbb, fred);
81             var mon2 = Monster.EndMonster(fbb);
82 
83             Monster.StartTest4Vector(fbb, 2);
84             MyGame.Example.Test.CreateTest(fbb, (short)10, (sbyte)20);
85             MyGame.Example.Test.CreateTest(fbb, (short)30, (sbyte)40);
86             var test4 = fbb.EndVector();
87 
88             Monster.StartTestarrayofstringVector(fbb, 2);
89             fbb.AddOffset(test2.Value);
90             fbb.AddOffset(test1.Value);
91             var testArrayOfString = fbb.EndVector();
92 
93             Monster.StartMonster(fbb);
94             Monster.AddPos(fbb, Vec3.CreateVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
95                                                      Color.Green, (short)5, (sbyte)6));
96             Monster.AddHp(fbb, (short)80);
97             Monster.AddName(fbb, str);
98             Monster.AddInventory(fbb, inv);
99             Monster.AddTestType(fbb, Any.Monster);
100             Monster.AddTest(fbb, mon2.Value);
101             Monster.AddTest4(fbb, test4);
102             Monster.AddTestarrayofstring(fbb, testArrayOfString);
103             Monster.AddTestbool(fbb, true);
104             Monster.AddTestarrayoftables(fbb, sortMons);
105             var mon = Monster.EndMonster(fbb);
106 
107             if (sizePrefix)
108             {
109                 Monster.FinishSizePrefixedMonsterBuffer(fbb, mon);
110             }
111             else
112             {
113                 Monster.FinishMonsterBuffer(fbb, mon);
114             }
115 
116             // Dump to output directory so we can inspect later, if needed
117             #if ENABLE_SPAN_T
118             var data = fbb.DataBuffer.ToSizedArray();
119             string filename = @"monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
120             File.WriteAllBytes(filename, data);
121             #else
122             using (var ms = fbb.DataBuffer.ToMemoryStream(fbb.DataBuffer.Position, fbb.Offset))
123             {
124                 var data = ms.ToArray();
125                 string filename = @"monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
126                 File.WriteAllBytes(filename, data);
127             }
128             #endif
129 
130             // Remove the size prefix if necessary for further testing
131             ByteBuffer dataBuffer = fbb.DataBuffer;
132             if (sizePrefix)
133             {
134                 Assert.AreEqual(ByteBufferUtil.GetSizePrefix(dataBuffer) + FlatBufferConstants.SizePrefixLength,
135                                 dataBuffer.Length - dataBuffer.Position);
136                 dataBuffer = ByteBufferUtil.RemoveSizePrefix(dataBuffer);
137             }
138 
139             // Now assert the buffer
140             TestBuffer(dataBuffer);
141 
142             //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
143             // revert to original values after testing
144             Monster monster = Monster.GetRootAsMonster(dataBuffer);
145 
146 
147             // mana is optional and does not exist in the buffer so the mutation should fail
148             // the mana field should retain its default value
149             Assert.AreEqual(monster.MutateMana((short)10), false);
150             Assert.AreEqual(monster.Mana, (short)150);
151 
152             // Accessing a vector of sorted by the key tables
153             Assert.AreEqual(monster.Testarrayoftables(0).Value.Name, "Barney");
154             Assert.AreEqual(monster.Testarrayoftables(1).Value.Name, "Frodo");
155             Assert.AreEqual(monster.Testarrayoftables(2).Value.Name, "Wilma");
156 
157             // Example of searching for a table by the key
158             Assert.IsTrue(monster.TestarrayoftablesByKey("Frodo") != null);
159             Assert.AreEqual(monster.TestarrayoftablesByKey("Frodo").Value.Name, "Frodo");
160             Assert.IsTrue(monster.TestarrayoftablesByKey("Barney") != null);
161             Assert.AreEqual(monster.TestarrayoftablesByKey("Barney").Value.Name, "Barney");
162             Assert.IsTrue(monster.TestarrayoftablesByKey("Wilma") != null);
163             Assert.AreEqual(monster.TestarrayoftablesByKey("Wilma").Value.Name, "Wilma");
164 
165             // testType is an existing field
166             Assert.AreEqual(monster.TestType, Any.Monster);
167 
168             //mutate the inventory vector
169             Assert.AreEqual(monster.MutateInventory(0, 1), true);
170             Assert.AreEqual(monster.MutateInventory(1, 2), true);
171             Assert.AreEqual(monster.MutateInventory(2, 3), true);
172             Assert.AreEqual(monster.MutateInventory(3, 4), true);
173             Assert.AreEqual(monster.MutateInventory(4, 5), true);
174 
175             for (int i = 0; i < monster.InventoryLength; i++)
176             {
177                 Assert.AreEqual(monster.Inventory(i), i + 1);
178             }
179 
180             //reverse mutation
181             Assert.AreEqual(monster.MutateInventory(0, 0), true);
182             Assert.AreEqual(monster.MutateInventory(1, 1), true);
183             Assert.AreEqual(monster.MutateInventory(2, 2), true);
184             Assert.AreEqual(monster.MutateInventory(3, 3), true);
185             Assert.AreEqual(monster.MutateInventory(4, 4), true);
186 
187             // get a struct field and edit one of its fields
188             Vec3 pos = (Vec3)monster.Pos;
189             Assert.AreEqual(pos.X, 1.0f);
190             pos.MutateX(55.0f);
191             Assert.AreEqual(pos.X, 55.0f);
192             pos.MutateX(1.0f);
193             Assert.AreEqual(pos.X, 1.0f);
194 
195             TestBuffer(dataBuffer);
196             TestObjectAPI(Monster.GetRootAsMonster(dataBuffer));
197         }
198 
TestBuffer(ByteBuffer bb)199         private void TestBuffer(ByteBuffer bb)
200         {
201             bool test = Monster.VerifyMonster(bb);
202             Assert.AreEqual(true, test);
203 
204             Monster monster = Monster.GetRootAsMonster(bb);
205 
206             Assert.AreEqual(80, monster.Hp);
207             Assert.AreEqual(150, monster.Mana);
208             Assert.AreEqual("MyMonster", monster.Name);
209 
210             var pos = monster.Pos.Value;
211             Assert.AreEqual(1.0f, pos.X);
212             Assert.AreEqual(2.0f, pos.Y);
213             Assert.AreEqual(3.0f, pos.Z);
214 
215             Assert.AreEqual(3.0f, pos.Test1);
216             Assert.AreEqual(Color.Green, pos.Test2);
217             var t = (MyGame.Example.Test)pos.Test3;
218             Assert.AreEqual((short)5, t.A);
219             Assert.AreEqual((sbyte)6, t.B);
220 
221             Assert.AreEqual(Any.Monster, monster.TestType);
222 
223             var monster2 = monster.Test<Monster>().Value;
224             Assert.AreEqual("Fred", monster2.Name);
225 
226 
227             Assert.AreEqual(5, monster.InventoryLength);
228             var invsum = 0;
229             for (var i = 0; i < monster.InventoryLength; i++)
230             {
231                 invsum += monster.Inventory(i);
232             }
233             Assert.AreEqual(10, invsum);
234 
235             // Get the inventory as an array and subtract the
236             // sum to get it back to 0
237             var inventoryArray = monster.GetInventoryArray();
238             Assert.AreEqual(5, inventoryArray.Length);
239             foreach(var inv in inventoryArray)
240             {
241                 invsum -= inv;
242             }
243             Assert.AreEqual(0, invsum);
244 
245             var test0 = monster.Test4(0).Value;
246             var test1 = monster.Test4(1).Value;
247             Assert.AreEqual(2, monster.Test4Length);
248 
249             Assert.AreEqual(100, test0.A + test0.B + test1.A + test1.B);
250 
251             Assert.AreEqual(2, monster.TestarrayofstringLength);
252             Assert.AreEqual("test1", monster.Testarrayofstring(0));
253             Assert.AreEqual("test2", monster.Testarrayofstring(1));
254 
255             Assert.AreEqual(true, monster.Testbool);
256 
257             #if ENABLE_SPAN_T
258             var nameBytes = monster.GetNameBytes();
259             Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.ToArray(), 0, nameBytes.Length));
260 
261             if (0 == monster.TestarrayofboolsLength)
262             {
263                 Assert.IsFalse(monster.GetTestarrayofboolsBytes().Length != 0);
264             }
265             else
266             {
267                 Assert.IsTrue(monster.GetTestarrayofboolsBytes().Length != 0);
268             }
269 
270             var longArrayBytes = monster.GetVectorOfLongsBytes();
271             Assert.IsTrue(monster.VectorOfLongsLength * 8 == longArrayBytes.Length);
272 
273             var doubleArrayBytes = monster.GetVectorOfDoublesBytes();
274             Assert.IsTrue(monster.VectorOfDoublesLength * 8 == doubleArrayBytes.Length);
275             #else
276             var nameBytes = monster.GetNameBytes().Value;
277             Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.Array, nameBytes.Offset, nameBytes.Count));
278 
279             if (0 == monster.TestarrayofboolsLength)
280             {
281                 Assert.IsFalse(monster.GetTestarrayofboolsBytes().HasValue);
282             }
283             else
284             {
285                 Assert.IsTrue(monster.GetTestarrayofboolsBytes().HasValue);
286             }
287             #endif
288         }
289 
290         [FlatBuffersTestMethod]
CanReadCppGeneratedWireFile()291         public void CanReadCppGeneratedWireFile()
292         {
293             var data = File.ReadAllBytes(@"../monsterdata_test.mon");
294             var bb = new ByteBuffer(data);
295             TestBuffer(bb);
296             TestObjectAPI(Monster.GetRootAsMonster(bb));
297         }
298 
299         [FlatBuffersTestMethod]
CanReadJsonFile()300         public void CanReadJsonFile()
301         {
302             var jsonText = File.ReadAllText(@"../monsterdata_test.json");
303             var mon = MonsterT.DeserializeFromJson(jsonText);
304             var fbb = new FlatBufferBuilder(1);
305             Monster.FinishMonsterBuffer(fbb, Monster.Pack(fbb, mon));
306             TestBuffer(fbb.DataBuffer);
307         }
308 
309         [FlatBuffersTestMethod]
TestEnums()310         public void TestEnums()
311         {
312             Assert.AreEqual("Red", Color.Red.ToString());
313             Assert.AreEqual("Blue", Color.Blue.ToString());
314             Assert.AreEqual("NONE", Any.NONE.ToString());
315             Assert.AreEqual("Monster", Any.Monster.ToString());
316         }
317 
318         [FlatBuffersTestMethod]
TestVectorOfEnums()319         public void TestVectorOfEnums()
320         {
321             const string monsterName = "TestVectorOfEnumsMonster";
322             var colorVec = new Color[] { Color.Red, Color.Green, Color.Blue };
323             var fbb = new FlatBufferBuilder(32);
324             var str1 = fbb.CreateString(monsterName);
325             var vec1 = Monster.CreateVectorOfEnumsVector(fbb, colorVec);
326             Monster.StartMonster(fbb);
327             Monster.AddName(fbb, str1);
328             Monster.AddVectorOfEnums(fbb, vec1);
329             var monster1 = Monster.EndMonster(fbb);
330             Monster.FinishMonsterBuffer(fbb, monster1);
331 
332             var mons = Monster.GetRootAsMonster(fbb.DataBuffer);
333             var colors = mons.GetVectorOfEnumsArray();
334             Assert.ArrayEqual(colorVec, colors);
335 
336             TestObjectAPI(mons);
337         }
338 
339         [FlatBuffersTestMethod]
TestNestedFlatBuffer()340         public void TestNestedFlatBuffer()
341         {
342             const string nestedMonsterName = "NestedMonsterName";
343             const short nestedMonsterHp = 600;
344             const short nestedMonsterMana = 1024;
345             // Create nested buffer as a Monster type
346             var fbb1 = new FlatBufferBuilder(16);
347             var str1 = fbb1.CreateString(nestedMonsterName);
348             Monster.StartMonster(fbb1);
349             Monster.AddName(fbb1, str1);
350             Monster.AddHp(fbb1, nestedMonsterHp);
351             Monster.AddMana(fbb1, nestedMonsterMana);
352             var monster1 = Monster.EndMonster(fbb1);
353             Monster.FinishMonsterBuffer(fbb1, monster1);
354             var fbb1Bytes = fbb1.SizedByteArray();
355             fbb1 = null;
356 
357             // Create a Monster which has the first buffer as a nested buffer
358             var fbb2 = new FlatBufferBuilder(16);
359             var str2 = fbb2.CreateString("My Monster");
360             var nestedBuffer = Monster.CreateTestnestedflatbufferVector(fbb2, fbb1Bytes);
361             Monster.StartMonster(fbb2);
362             Monster.AddName(fbb2, str2);
363             Monster.AddHp(fbb2, 50);
364             Monster.AddMana(fbb2, 32);
365             Monster.AddTestnestedflatbuffer(fbb2, nestedBuffer);
366             var monster = Monster.EndMonster(fbb2);
367             Monster.FinishMonsterBuffer(fbb2, monster);
368 
369             // Now test the data extracted from the nested buffer
370             var mons = Monster.GetRootAsMonster(fbb2.DataBuffer);
371             var nestedMonster = mons.GetTestnestedflatbufferAsMonster().Value;
372 
373             Assert.AreEqual(nestedMonsterMana, nestedMonster.Mana);
374             Assert.AreEqual(nestedMonsterHp, nestedMonster.Hp);
375             Assert.AreEqual(nestedMonsterName, nestedMonster.Name);
376 
377             TestObjectAPI(mons);
378             TestObjectAPI(nestedMonster);
379         }
380 
381         [FlatBuffersTestMethod]
TestFixedLenghtArrays()382         public void TestFixedLenghtArrays()
383         {
384             FlatBufferBuilder builder = new FlatBufferBuilder(100);
385 
386             float   a;
387             int[]   b = new int[15];
388             sbyte   c;
389             int[,]  d_a = new int[2, 2];
390             TestEnum[]  d_b = new TestEnum[2];
391             TestEnum[,] d_c = new TestEnum[2, 2];
392             long[,]     d_d = new long[2, 2];
393             int         e;
394             long[]      f = new long[2];
395 
396             a = 0.5f;
397             for (int i = 0; i < 15; i++) b[i] = i;
398             c = 1;
399             d_a[0, 0] = 1;
400             d_a[0, 1] = 2;
401             d_a[1, 0] = 3;
402             d_a[1, 1] = 4;
403             d_b[0] = TestEnum.B;
404             d_b[1] = TestEnum.C;
405             d_c[0, 0] = TestEnum.A;
406             d_c[0, 1] = TestEnum.B;
407             d_c[1, 0] = TestEnum.C;
408             d_c[1, 1] = TestEnum.B;
409             d_d[0, 0] = -1;
410             d_d[0, 1] = 1;
411             d_d[1, 0] = -2;
412             d_d[1, 1] = 2;
413             e = 2;
414             f[0] = -1;
415             f[1] = 1;
416 
417             Offset<ArrayStruct> arrayOffset = ArrayStruct.CreateArrayStruct(
418                 builder, a, b, c, d_a, d_b, d_c, d_d, e, f);
419 
420             // Create a table with the ArrayStruct.
421             ArrayTable.StartArrayTable(builder);
422             ArrayTable.AddA(builder, arrayOffset);
423             Offset<ArrayTable> tableOffset = ArrayTable.EndArrayTable(builder);
424 
425             ArrayTable.FinishArrayTableBuffer(builder, tableOffset);
426 
427             ArrayTable table = ArrayTable.GetRootAsArrayTable(builder.DataBuffer);
428 
429             Assert.AreEqual(table.A.Value.A, 0.5f);
430             for (int i = 0; i < 15; i++) Assert.AreEqual(table.A.Value.B(i), i);
431             Assert.AreEqual(table.A.Value.C, (sbyte)1);
432             Assert.AreEqual(table.A.Value.D(0).A(0), 1);
433             Assert.AreEqual(table.A.Value.D(0).A(1), 2);
434             Assert.AreEqual(table.A.Value.D(1).A(0), 3);
435             Assert.AreEqual(table.A.Value.D(1).A(1), 4);
436             Assert.AreEqual(table.A.Value.D(0).B, TestEnum.B);
437             Assert.AreEqual(table.A.Value.D(1).B, TestEnum.C);
438             Assert.AreEqual(table.A.Value.D(0).C(0), TestEnum.A);
439             Assert.AreEqual(table.A.Value.D(0).C(1), TestEnum.B);
440             Assert.AreEqual(table.A.Value.D(1).C(0), TestEnum.C);
441             Assert.AreEqual(table.A.Value.D(1).C(1), TestEnum.B);
442             Assert.AreEqual(table.A.Value.D(0).D(0), -1);
443             Assert.AreEqual(table.A.Value.D(0).D(1), 1);
444             Assert.AreEqual(table.A.Value.D(1).D(0), -2);
445             Assert.AreEqual(table.A.Value.D(1).D(1), 2);
446             Assert.AreEqual(table.A.Value.E, 2);
447             Assert.AreEqual(table.A.Value.F(0), -1);
448             Assert.AreEqual(table.A.Value.F(1), 1);
449 
450             TestObjectAPI(table);
451         }
452 
453         [FlatBuffersTestMethod]
TestUnionVector()454         public void TestUnionVector()
455         {
456             var fbb = new FlatBufferBuilder(100);
457             var rapunzel = Rapunzel.CreateRapunzel(fbb, 40).Value;
458 
459             var characterTypes = new[]
460             {
461                 Character.MuLan,
462                 Character.Belle,
463                 Character.Other,
464             };
465             var characterTypesOffset = Movie.CreateCharactersTypeVector(fbb, characterTypes);
466 
467             var characters = new[]
468             {
469                 Attacker.CreateAttacker(fbb, 10).Value,
470                 BookReader.CreateBookReader(fbb, 20).Value,
471                 fbb.CreateSharedString("Chip").Value,
472             };
473             var charactersOffset = Movie.CreateCharactersVector(fbb, characters);
474 
475             var movieOffset = Movie.CreateMovie(
476                 fbb,
477                 Character.Rapunzel,
478                 rapunzel,
479                 characterTypesOffset,
480                 charactersOffset);
481             Movie.FinishMovieBuffer(fbb, movieOffset);
482 
483             var movie = Movie.GetRootAsMovie(fbb.DataBuffer);
484             Assert.AreEqual(Character.Rapunzel, movie.MainCharacterType);
485             Assert.AreEqual(40, movie.MainCharacter<Rapunzel>().Value.HairLength);
486 
487             Assert.AreEqual(3, movie.CharactersLength);
488             Assert.AreEqual(Character.MuLan, movie.CharactersType(0));
489             Assert.AreEqual(10, movie.Characters<Attacker>(0).Value.SwordAttackDamage);
490             Assert.AreEqual(Character.Belle, movie.CharactersType(1));
491             Assert.AreEqual(20, movie.Characters<BookReader>(1).Value.BooksRead);
492             Assert.AreEqual(Character.Other, movie.CharactersType(2));
493             Assert.AreEqual("Chip", movie.CharactersAsString(2));
494 
495             TestObjectAPI(movie);
496         }
497 
498         [FlatBuffersTestMethod]
TestUnionUtility()499         public void TestUnionUtility()
500         {
501             var movie = new MovieT
502             {
503                 MainCharacter = CharacterUnion.FromRapunzel(new RapunzelT { HairLength = 40 }),
504                 Characters = new System.Collections.Generic.List<CharacterUnion>
505                 {
506                     CharacterUnion.FromMuLan(new AttackerT { SwordAttackDamage = 10 }),
507                     CharacterUnion.FromBelle(new BookReaderT { BooksRead = 20 }),
508                     CharacterUnion.FromOther("Chip"),
509                 },
510             };
511 
512             var fbb = new FlatBufferBuilder(100);
513             Movie.FinishMovieBuffer(fbb, Movie.Pack(fbb, movie));
514 
515             TestObjectAPI(Movie.GetRootAsMovie(fbb.DataBuffer));
516         }
517 
AreEqual(Monster a, MonsterT b)518         private void AreEqual(Monster a, MonsterT b)
519         {
520             Assert.AreEqual(a.Hp, b.Hp);
521             Assert.AreEqual(a.Mana, b.Mana);
522             Assert.AreEqual(a.Name, b.Name);
523 
524             var posA = a.Pos;
525             var posB = b.Pos;
526             if (posA != null)
527             {
528                 Assert.AreEqual(posA.Value.X, posB.X);
529                 Assert.AreEqual(posA.Value.Y, posB.Y);
530                 Assert.AreEqual(posA.Value.Z, posB.Z);
531 
532                 Assert.AreEqual(posA.Value.Test1, posB.Test1);
533                 Assert.AreEqual(posA.Value.Test2, posB.Test2);
534                 var tA = posA.Value.Test3;
535                 var tB = posB.Test3;
536                 Assert.AreEqual(tA.A, tB.A);
537                 Assert.AreEqual(tA.B, tB.B);
538             }
539 
540             Assert.AreEqual(a.TestType, b.Test.Type);
541             if (a.TestType == Any.Monster)
542             {
543                 var monster2A = a.Test<Monster>().Value;
544                 var monster2B = b.Test.AsMonster();
545                 Assert.AreEqual(monster2A.Name, monster2B.Name);
546             }
547 
548             Assert.AreEqual(a.InventoryLength, b.Inventory.Count);
549             for (var i = 0; i < a.InventoryLength; ++i)
550             {
551                 Assert.AreEqual(a.Inventory(i), b.Inventory[i]);
552             }
553 
554             var inventoryArray = a.GetInventoryArray();
555             var inventoryArrayLength = inventoryArray == null ? 0 : inventoryArray.Length;
556             Assert.AreEqual(inventoryArrayLength, b.Inventory.Count);
557             for (var i = 0; i < inventoryArrayLength; ++i)
558             {
559                 Assert.AreEqual(inventoryArray[i], b.Inventory[i]);
560             }
561 
562             Assert.AreEqual(a.Test4Length, b.Test4.Count);
563             for (var i = 0; i < a.Test4Length; ++i)
564             {
565                 var t4A = a.Test4(i);
566                 var t4B = b.Test4[i];
567                 Assert.AreEqual(t4A.Value.A, t4B.A);
568                 Assert.AreEqual(t4A.Value.B, t4B.B);
569             }
570 
571             Assert.AreEqual(a.TestarrayofstringLength, b.Testarrayofstring.Count);
572             for (var i = 0; i < a.TestarrayofstringLength; ++i)
573             {
574                 Assert.AreEqual(a.Testarrayofstring(i), b.Testarrayofstring[i]);
575             }
576 
577             Assert.AreEqual(a.Testbool, b.Testbool);
578 
579             Assert.AreEqual(a.TestarrayofboolsLength, b.Testarrayofbools.Count);
580             for (var i = 0; i < a.TestarrayofboolsLength; ++i)
581             {
582                 Assert.AreEqual(a.Testarrayofbools(i), b.Testarrayofbools[i]);
583             }
584 
585             Assert.AreEqual(a.VectorOfLongsLength, b.VectorOfLongs.Count);
586             for (var i = 0; i < a.VectorOfLongsLength; ++i)
587             {
588                 Assert.AreEqual(a.VectorOfLongs(i), b.VectorOfLongs[i]);
589             }
590 
591             Assert.AreEqual(a.VectorOfDoublesLength, b.VectorOfDoubles.Count);
592             for (var i = 0; i < a.VectorOfDoublesLength; ++i)
593             {
594                 Assert.AreEqual(a.VectorOfDoubles(i), b.VectorOfDoubles[i]);
595             }
596 
597             Assert.AreEqual(a.VectorOfEnumsLength, b.VectorOfEnums.Count);
598             for (var i = 0; i < a.VectorOfEnumsLength; ++i)
599             {
600                 Assert.AreEqual(a.VectorOfEnums(i), b.VectorOfEnums[i]);
601             }
602         }
603 
AreEqual(Monster a, Monster b)604         private void AreEqual(Monster a, Monster b)
605         {
606             Assert.AreEqual(a.Hp, b.Hp);
607             Assert.AreEqual(a.Mana, b.Mana);
608             Assert.AreEqual(a.Name, b.Name);
609 
610             var posA = a.Pos;
611             var posB = b.Pos;
612             if (posA != null)
613             {
614                 Assert.AreEqual(posA.Value.X, posB.Value.X);
615                 Assert.AreEqual(posA.Value.Y, posB.Value.Y);
616                 Assert.AreEqual(posA.Value.Z, posB.Value.Z);
617 
618                 Assert.AreEqual(posA.Value.Test1, posB.Value.Test1);
619                 Assert.AreEqual(posA.Value.Test2, posB.Value.Test2);
620                 var tA = posA.Value.Test3;
621                 var tB = posB.Value.Test3;
622                 Assert.AreEqual(tA.A, tB.A);
623                 Assert.AreEqual(tA.B, tB.B);
624             }
625 
626             Assert.AreEqual(a.TestType, b.TestType);
627             if (a.TestType == Any.Monster)
628             {
629                 var monster2A = a.Test<Monster>().Value;
630                 var monster2B = b.Test<Monster>().Value;
631                 Assert.AreEqual(monster2A.Name, monster2B.Name);
632             }
633 
634             Assert.AreEqual(a.InventoryLength, b.InventoryLength);
635             for (var i = 0; i < a.InventoryLength; ++i)
636             {
637                 Assert.AreEqual(a.Inventory(i), b.Inventory(i));
638             }
639 
640             var inventoryArrayA = a.GetInventoryArray();
641             var inventoryArrayALength = inventoryArrayA == null ? 0 : inventoryArrayA.Length;
642             var inventoryArrayB = b.GetInventoryArray();
643             var inventoryArrayBLength = inventoryArrayB == null ? 0 : inventoryArrayB.Length;
644             Assert.AreEqual(inventoryArrayALength, inventoryArrayBLength);
645             for (var i = 0; i < inventoryArrayALength; ++i)
646             {
647                 Assert.AreEqual(inventoryArrayA[i], inventoryArrayB[i]);
648             }
649 
650             Assert.AreEqual(a.Test4Length, b.Test4Length);
651             for (var i = 0; i < a.Test4Length; ++i)
652             {
653                 var t4A = a.Test4(i);
654                 var t4B = b.Test4(i);
655                 Assert.AreEqual(t4A.Value.A, t4B.Value.A);
656                 Assert.AreEqual(t4A.Value.B, t4B.Value.B);
657             }
658 
659             Assert.AreEqual(a.TestarrayofstringLength, b.TestarrayofstringLength);
660             for (var i = 0; i < a.TestarrayofstringLength; ++i)
661             {
662                 Assert.AreEqual(a.Testarrayofstring(i), b.Testarrayofstring(i));
663             }
664 
665             Assert.AreEqual(a.Testbool, b.Testbool);
666 
667             Assert.AreEqual(a.TestarrayofboolsLength, b.TestarrayofboolsLength);
668             for (var i = 0; i < a.TestarrayofboolsLength; ++i)
669             {
670                 Assert.AreEqual(a.Testarrayofbools(i), b.Testarrayofbools(i));
671             }
672 
673             Assert.AreEqual(a.VectorOfLongsLength, b.VectorOfLongsLength);
674             for (var i = 0; i < a.VectorOfLongsLength; ++i)
675             {
676                 Assert.AreEqual(a.VectorOfLongs(i), b.VectorOfLongs(i));
677             }
678 
679             Assert.AreEqual(a.VectorOfDoublesLength, b.VectorOfDoublesLength);
680             for (var i = 0; i < a.VectorOfDoublesLength; ++i)
681             {
682                 Assert.AreEqual(a.VectorOfDoubles(i), b.VectorOfDoubles(i));
683             }
684 
685             Assert.AreEqual(a.VectorOfEnumsLength, b.VectorOfEnumsLength);
686             for (var i = 0; i < a.VectorOfEnumsLength; ++i)
687             {
688                 Assert.AreEqual(a.VectorOfEnums(i), b.VectorOfEnums(i));
689             }
690         }
691 
TestObjectAPI(Monster a)692         private void TestObjectAPI(Monster a)
693         {
694             var b = a.UnPack();
695             AreEqual(a, b);
696 
697             var fbb = new FlatBufferBuilder(1);
698             fbb.Finish(Monster.Pack(fbb, b).Value);
699             var c = Monster.GetRootAsMonster(fbb.DataBuffer);
700             AreEqual(a, c);
701 
702             var jsonText = b.SerializeToJson();
703             var d = MonsterT.DeserializeFromJson(jsonText);
704             AreEqual(a, d);
705 
706             var fbBuffer = b.SerializeToBinary();
707             Assert.IsTrue(Monster.MonsterBufferHasIdentifier(new ByteBuffer(fbBuffer)));
708             var e = MonsterT.DeserializeFromBinary(fbBuffer);
709             AreEqual(a, e);
710         }
711 
AreEqual(ArrayTable a, ArrayTableT b)712         private void AreEqual(ArrayTable a, ArrayTableT b)
713         {
714             Assert.AreEqual(a.A.Value.A, b.A.A);
715 
716             for (int i = 0; i < 15; ++i)
717             {
718                 Assert.AreEqual(a.A.Value.B(i), b.A.B[i]);
719             }
720 
721             Assert.AreEqual(a.A.Value.C, b.A.C);
722 
723             for (int i = 0; i < 2; ++i)
724             {
725                 var ad = a.A.Value.D(i);
726                 var bd = b.A.D[i];
727 
728                 for (int j = 0; j < 2; ++j)
729                 {
730                     Assert.AreEqual(ad.A(j), bd.A[j]);
731                 }
732 
733                 Assert.AreEqual(ad.B, bd.B);
734 
735                 for (int j = 0; j < 2; ++j)
736                 {
737                     Assert.AreEqual(ad.C(j), bd.C[j]);
738                 }
739 
740                 for (int j = 0; j < 2; ++j)
741                 {
742                     Assert.AreEqual(ad.D(j), bd.D[j]);
743                 }
744             }
745 
746             Assert.AreEqual(a.A.Value.E, b.A.E);
747 
748             for (int i = 0; i < 2; ++i)
749             {
750                 Assert.AreEqual(a.A.Value.F(i), b.A.F[i]);
751             }
752         }
753 
AreEqual(ArrayTable a, ArrayTable b)754         private void AreEqual(ArrayTable a, ArrayTable b)
755         {
756             Assert.AreEqual(a.A.Value.A, b.A.Value.A);
757 
758             for (int i = 0; i < 15; ++i)
759             {
760                 Assert.AreEqual(a.A.Value.B(i), b.A.Value.B(i));
761             }
762 
763             Assert.AreEqual(a.A.Value.C, b.A.Value.C);
764 
765             for (int i = 0; i < 2; ++i)
766             {
767                 var ad = a.A.Value.D(i);
768                 var bd = b.A.Value.D(i);
769 
770                 for (int j = 0; j < 2; ++j)
771                 {
772                     Assert.AreEqual(ad.A(j), bd.A(j));
773                 }
774 
775                 Assert.AreEqual(ad.B, bd.B);
776 
777                 for (int j = 0; j < 2; ++j)
778                 {
779                     Assert.AreEqual(ad.C(j), bd.C(j));
780                 }
781 
782                 for (int j = 0; j < 2; ++j)
783                 {
784                     Assert.AreEqual(ad.D(j), bd.D(j));
785                 }
786             }
787 
788             Assert.AreEqual(a.A.Value.E, b.A.Value.E);
789 
790             for (int i = 0; i < 2; ++i)
791             {
792                 Assert.AreEqual(a.A.Value.F(i), b.A.Value.F(i));
793             }
794         }
795 
TestObjectAPI(ArrayTable a)796         private void TestObjectAPI(ArrayTable a)
797         {
798             var b = a.UnPack();
799             AreEqual(a, b);
800 
801             var fbb = new FlatBufferBuilder(1);
802             fbb.Finish(ArrayTable.Pack(fbb, b).Value);
803             var c = ArrayTable.GetRootAsArrayTable(fbb.DataBuffer);
804             AreEqual(a, c);
805 
806             var jsonText = b.SerializeToJson();
807             var d = ArrayTableT.DeserializeFromJson(jsonText);
808             AreEqual(a, d);
809 
810             var fbBuffer = b.SerializeToBinary();
811             Assert.IsTrue(ArrayTable.ArrayTableBufferHasIdentifier(new ByteBuffer(fbBuffer)));
812             var e = ArrayTableT.DeserializeFromBinary(fbBuffer);
813             AreEqual(a, e);
814         }
815 
AreEqual(Movie a, MovieT b)816         private void AreEqual(Movie a, MovieT b)
817         {
818             Assert.AreEqual(a.MainCharacterType, b.MainCharacter.Type);
819             Assert.AreEqual(a.MainCharacter<Rapunzel>().Value.HairLength, b.MainCharacter.AsRapunzel().HairLength);
820 
821             Assert.AreEqual(a.CharactersLength, b.Characters.Count);
822             Assert.AreEqual(a.CharactersType(0), b.Characters[0].Type);
823             Assert.AreEqual(a.Characters<Attacker>(0).Value.SwordAttackDamage, b.Characters[0].AsMuLan().SwordAttackDamage);
824             Assert.AreEqual(a.CharactersType(1), b.Characters[1].Type);
825             Assert.AreEqual(a.Characters<BookReader>(1).Value.BooksRead, b.Characters[1].AsBelle().BooksRead);
826             Assert.AreEqual(a.CharactersType(2), b.Characters[2].Type);
827             Assert.AreEqual(a.CharactersAsString(2), b.Characters[2].AsOther());
828         }
829 
AreEqual(Movie a, Movie b)830         private void AreEqual(Movie a, Movie b)
831         {
832             Assert.AreEqual(a.MainCharacterType, b.MainCharacterType);
833             Assert.AreEqual(a.MainCharacter<Rapunzel>().Value.HairLength, b.MainCharacter<Rapunzel>().Value.HairLength);
834 
835             Assert.AreEqual(a.CharactersLength, b.CharactersLength);
836             Assert.AreEqual(a.CharactersType(0), b.CharactersType(0));
837             Assert.AreEqual(a.Characters<Attacker>(0).Value.SwordAttackDamage, b.Characters<Attacker>(0).Value.SwordAttackDamage);
838             Assert.AreEqual(a.CharactersType(1), b.CharactersType(1));
839             Assert.AreEqual(a.Characters<BookReader>(1).Value.BooksRead, b.Characters<BookReader>(1).Value.BooksRead);
840             Assert.AreEqual(a.CharactersType(2), b.CharactersType(2));
841             Assert.AreEqual(a.CharactersAsString(2), b.CharactersAsString(2));
842         }
843 
TestObjectAPI(Movie a)844         private void TestObjectAPI(Movie a)
845         {
846             var b = a.UnPack();
847             AreEqual(a, b);
848 
849             var fbb = new FlatBufferBuilder(1);
850             fbb.Finish(Movie.Pack(fbb, b).Value);
851             var c = Movie.GetRootAsMovie(fbb.DataBuffer);
852             AreEqual(a, c);
853 
854             var jsonText = b.SerializeToJson();
855             var d = MovieT.DeserializeFromJson(jsonText);
856             AreEqual(a, d);
857 
858             var fbBuffer = b.SerializeToBinary();
859             Assert.IsTrue(Movie.MovieBufferHasIdentifier(new ByteBuffer(fbBuffer)));
860             var e = MovieT.DeserializeFromBinary(fbBuffer);
861             AreEqual(a, e);
862         }
863 
864         // For use in TestParallelAccess test case.
865         static private int _comparisons = 0;
866         static private int _failures = 0;
KeepComparing(Monster mon, int count, float floatValue, double doubleValue)867         static private void KeepComparing(Monster mon, int count, float floatValue, double doubleValue)
868         {
869             int i = 0;
870             while (++i <= count)
871             {
872                 Interlocked.Add(ref _comparisons, 1);
873                 if(mon.Pos.Value.Test1 != doubleValue || mon.Pos.Value.Z != floatValue) {
874                     Interlocked.Add(ref _failures, 1);
875                 }
876             }
877         }
878 
879         [FlatBuffersTestMethod]
TestParallelAccess()880         public void TestParallelAccess() {
881             // Tests that reading from a flatbuffer over multiple threads is thread-safe in regard to double and float
882             // values, since they previously were non-thread safe
883             const float floatValue = 3.141592F;
884             const double doubleValue = 1.618033988;
885 
886             var fbb = new FlatBufferBuilder(1);
887             var str = fbb.CreateString("ParallelTest");
888             Monster.StartMonster(fbb);
889             Monster.AddPos(fbb, Vec3.CreateVec3(fbb, 1.0f, 2.0f, floatValue, doubleValue,
890                                                      Color.Green, (short)5, (sbyte)6));
891 
892             Monster.AddName(fbb, str);
893             Monster.FinishMonsterBuffer(fbb, Monster.EndMonster(fbb));
894 
895             var mon = Monster.GetRootAsMonster(fbb.DataBuffer);
896 
897             var pos = mon.Pos.Value;
898             Assert.AreEqual(pos.Test1, doubleValue);
899             Assert.AreEqual(pos.Z, floatValue);
900 
901             const int thread_count = 10;
902             const int reps = 1000000;
903 
904             // Need to use raw Threads since Tasks are not supported in .NET 3.5
905             Thread[] threads = new Thread[thread_count];
906             for(int i = 0; i < thread_count; i++) {
907                threads[i] = new Thread(() => KeepComparing(mon, reps, floatValue, doubleValue));
908             }
909             for(int i = 0; i < thread_count; i++) {
910                threads[i].Start();
911             }
912             for(int i = 0; i < thread_count; i++) {
913                threads[i].Join();
914             }
915 
916             // Make sure the threads actually did the comparisons.
917             Assert.AreEqual(thread_count * reps, _comparisons);
918 
919             // Make sure we never read the values incorrectly.
920             Assert.AreEqual(0, _failures);
921         }
922 
923         [FlatBuffersTestMethod]
TestScalarOptional_EmptyBuffer()924         public void TestScalarOptional_EmptyBuffer() {
925             var fbb = new FlatBufferBuilder(1);
926             ScalarStuff.StartScalarStuff(fbb);
927             var offset = ScalarStuff.EndScalarStuff(fbb);
928             ScalarStuff.FinishScalarStuffBuffer(fbb, offset);
929 
930             ScalarStuff scalarStuff = ScalarStuff.GetRootAsScalarStuff(fbb.DataBuffer);
931             Assert.AreEqual((sbyte)0, scalarStuff.JustI8);
932             Assert.AreEqual(null, scalarStuff.MaybeI8);
933             Assert.AreEqual((sbyte)42, scalarStuff.DefaultI8);
934             Assert.AreEqual((byte)0, scalarStuff.JustU8);
935             Assert.AreEqual(null, scalarStuff.MaybeU8);
936             Assert.AreEqual((byte)42, scalarStuff.DefaultU8);
937 
938             Assert.AreEqual((short)0, scalarStuff.JustI16);
939             Assert.AreEqual(null, scalarStuff.MaybeI16);
940             Assert.AreEqual((short)42, scalarStuff.DefaultI16);
941             Assert.AreEqual((ushort)0, scalarStuff.JustU16);
942             Assert.AreEqual(null, scalarStuff.MaybeU16);
943             Assert.AreEqual((ushort)42, scalarStuff.DefaultU16);
944 
945             Assert.AreEqual((int)0, scalarStuff.JustI32);
946             Assert.AreEqual(null, scalarStuff.MaybeI32);
947             Assert.AreEqual((int)42, scalarStuff.DefaultI32);
948             Assert.AreEqual((uint)0, scalarStuff.JustU32);
949             Assert.AreEqual(null, scalarStuff.MaybeU32);
950             Assert.AreEqual((uint)42, scalarStuff.DefaultU32);
951 
952             Assert.AreEqual((long)0, scalarStuff.JustI64);
953             Assert.AreEqual(null, scalarStuff.MaybeI64);
954             Assert.AreEqual((long)42, scalarStuff.DefaultI64);
955             Assert.AreEqual((ulong)0, scalarStuff.JustU64);
956             Assert.AreEqual(null, scalarStuff.MaybeU64);
957             Assert.AreEqual((ulong)42, scalarStuff.DefaultU64);
958 
959             Assert.AreEqual((float)0.0F, scalarStuff.JustF32);
960             Assert.AreEqual(null, scalarStuff.MaybeF32);
961             Assert.AreEqual((float)42.0F, scalarStuff.DefaultF32);
962 
963             Assert.AreEqual((double)0.0, scalarStuff.JustF64);
964             Assert.AreEqual(null, scalarStuff.MaybeF64);
965             Assert.AreEqual((double)42.0, scalarStuff.DefaultF64);
966 
967             Assert.AreEqual(false, scalarStuff.JustBool);
968             Assert.AreEqual(null, scalarStuff.MaybeBool);
969             Assert.AreEqual(true, scalarStuff.DefaultBool);
970 
971             Assert.AreEqual(OptionalByte.None, scalarStuff.JustEnum);
972             Assert.AreEqual(null, scalarStuff.MaybeEnum);
973             Assert.AreEqual(OptionalByte.One, scalarStuff.DefaultEnum);
974         }
975 
976         [FlatBuffersTestMethod]
TestScalarOptional_Construction()977         public void TestScalarOptional_Construction() {
978             var fbb = new FlatBufferBuilder(1);
979             ScalarStuff.StartScalarStuff(fbb);
980             ScalarStuff.AddJustI8(fbb, 5);
981             ScalarStuff.AddMaybeI8(fbb, 5);
982             ScalarStuff.AddDefaultI8(fbb, 5);
983             ScalarStuff.AddJustU8(fbb, 6);
984             ScalarStuff.AddMaybeU8(fbb, 6);
985             ScalarStuff.AddDefaultU8(fbb, 6);
986 
987             ScalarStuff.AddJustI16(fbb, 7);
988             ScalarStuff.AddMaybeI16(fbb, 7);
989             ScalarStuff.AddDefaultI16(fbb, 7);
990             ScalarStuff.AddJustU16(fbb, 8);
991             ScalarStuff.AddMaybeU16(fbb, 8);
992             ScalarStuff.AddDefaultU16(fbb, 8);
993 
994             ScalarStuff.AddJustI32(fbb, 9);
995             ScalarStuff.AddMaybeI32(fbb, 9);
996             ScalarStuff.AddDefaultI32(fbb, 9);
997             ScalarStuff.AddJustU32(fbb, 10);
998             ScalarStuff.AddMaybeU32(fbb, 10);
999             ScalarStuff.AddDefaultU32(fbb, 10);
1000 
1001             ScalarStuff.AddJustI64(fbb, 11);
1002             ScalarStuff.AddMaybeI64(fbb, 11);
1003             ScalarStuff.AddDefaultI64(fbb, 11);
1004             ScalarStuff.AddJustU64(fbb, 12);
1005             ScalarStuff.AddMaybeU64(fbb, 12);
1006             ScalarStuff.AddDefaultU64(fbb, 12);
1007 
1008             ScalarStuff.AddJustF32(fbb, 13.0f);
1009             ScalarStuff.AddMaybeF32(fbb, 13.0f);
1010             ScalarStuff.AddDefaultF32(fbb, 13.0f);
1011             ScalarStuff.AddJustF64(fbb, 14.0);
1012             ScalarStuff.AddMaybeF64(fbb, 14.0);
1013             ScalarStuff.AddDefaultF64(fbb, 14.0);
1014 
1015             ScalarStuff.AddJustBool(fbb, true);
1016             ScalarStuff.AddMaybeBool(fbb, true);
1017             ScalarStuff.AddDefaultBool(fbb, false); // note this is the opposite
1018 
1019             ScalarStuff.AddJustEnum(fbb, OptionalByte.Two);
1020             ScalarStuff.AddMaybeEnum(fbb, OptionalByte.Two);
1021             ScalarStuff.AddDefaultEnum(fbb, OptionalByte.Two);
1022 
1023             var offset = ScalarStuff.EndScalarStuff(fbb);
1024             ScalarStuff.FinishScalarStuffBuffer(fbb, offset);
1025 
1026             ScalarStuff scalarStuff = ScalarStuff.GetRootAsScalarStuff(fbb.DataBuffer);
1027             Assert.AreEqual((sbyte)5, scalarStuff.JustI8);
1028             Assert.AreEqual((sbyte)5, scalarStuff.MaybeI8);
1029             Assert.AreEqual((sbyte)5, scalarStuff.DefaultI8);
1030             Assert.AreEqual((byte)6, scalarStuff.JustU8);
1031             Assert.AreEqual((byte)6, scalarStuff.MaybeU8);
1032             Assert.AreEqual((byte)6, scalarStuff.DefaultU8);
1033 
1034             Assert.AreEqual((short)7, scalarStuff.JustI16);
1035             Assert.AreEqual((short)7, scalarStuff.MaybeI16);
1036             Assert.AreEqual((short)7, scalarStuff.DefaultI16);
1037             Assert.AreEqual((ushort)8, scalarStuff.JustU16);
1038             Assert.AreEqual((ushort)8, scalarStuff.MaybeU16);
1039             Assert.AreEqual((ushort)8, scalarStuff.DefaultU16);
1040 
1041             Assert.AreEqual((int)9, scalarStuff.JustI32);
1042             Assert.AreEqual((int)9, scalarStuff.MaybeI32);
1043             Assert.AreEqual((int)9, scalarStuff.DefaultI32);
1044             Assert.AreEqual((uint)10, scalarStuff.JustU32);
1045             Assert.AreEqual((uint)10, scalarStuff.MaybeU32);
1046             Assert.AreEqual((uint)10, scalarStuff.DefaultU32);
1047 
1048             Assert.AreEqual((long)11, scalarStuff.JustI64);
1049             Assert.AreEqual((long)11, scalarStuff.MaybeI64);
1050             Assert.AreEqual((long)11, scalarStuff.DefaultI64);
1051             Assert.AreEqual((ulong)12, scalarStuff.JustU64);
1052             Assert.AreEqual((ulong)12, scalarStuff.MaybeU64);
1053             Assert.AreEqual((ulong)12, scalarStuff.DefaultU64);
1054 
1055             Assert.AreEqual((float)13.0F, scalarStuff.JustF32);
1056             Assert.AreEqual((float)13.0F, scalarStuff.MaybeF32);
1057             Assert.AreEqual((float)13.0F, scalarStuff.DefaultF32);
1058 
1059             Assert.AreEqual((double)14.0, scalarStuff.JustF64);
1060             Assert.AreEqual((double)14.0, scalarStuff.MaybeF64);
1061             Assert.AreEqual((double)14.0, scalarStuff.DefaultF64);
1062 
1063             Assert.AreEqual(true, scalarStuff.JustBool);
1064             Assert.AreEqual(true, scalarStuff.MaybeBool);
1065             Assert.AreEqual(false, scalarStuff.DefaultBool);
1066 
1067             Assert.AreEqual(OptionalByte.Two, scalarStuff.JustEnum);
1068             Assert.AreEqual(OptionalByte.Two, scalarStuff.MaybeEnum);
1069             Assert.AreEqual(OptionalByte.Two, scalarStuff.DefaultEnum);
1070         }
1071 
1072         [FlatBuffersTestMethod]
TestScalarOptional_Construction_CreatorMethod()1073         public void TestScalarOptional_Construction_CreatorMethod() {
1074             var fbb = new FlatBufferBuilder(1);
1075 
1076             var offset = ScalarStuff.CreateScalarStuff(fbb,5,5,5,6,6,6,7,7,7,
1077                 8,8,8,9,9,9,10,10,10,11,11,11,12,12,12,13.0f,13.0f,13.0f,14.0,
1078                 14.0,14.0,true,true,false,OptionalByte.Two,OptionalByte.Two,
1079                 OptionalByte.Two);
1080             ScalarStuff.FinishScalarStuffBuffer(fbb, offset);
1081 
1082             ScalarStuff scalarStuff = ScalarStuff.GetRootAsScalarStuff(fbb.DataBuffer);
1083             Assert.AreEqual((sbyte)5, scalarStuff.JustI8);
1084             Assert.AreEqual((sbyte)5, scalarStuff.MaybeI8);
1085             Assert.AreEqual((sbyte)5, scalarStuff.DefaultI8);
1086             Assert.AreEqual((byte)6, scalarStuff.JustU8);
1087             Assert.AreEqual((byte)6, scalarStuff.MaybeU8);
1088             Assert.AreEqual((byte)6, scalarStuff.DefaultU8);
1089 
1090             Assert.AreEqual((short)7, scalarStuff.JustI16);
1091             Assert.AreEqual((short)7, scalarStuff.MaybeI16);
1092             Assert.AreEqual((short)7, scalarStuff.DefaultI16);
1093             Assert.AreEqual((ushort)8, scalarStuff.JustU16);
1094             Assert.AreEqual((ushort)8, scalarStuff.MaybeU16);
1095             Assert.AreEqual((ushort)8, scalarStuff.DefaultU16);
1096 
1097             Assert.AreEqual((int)9, scalarStuff.JustI32);
1098             Assert.AreEqual((int)9, scalarStuff.MaybeI32);
1099             Assert.AreEqual((int)9, scalarStuff.DefaultI32);
1100             Assert.AreEqual((uint)10, scalarStuff.JustU32);
1101             Assert.AreEqual((uint)10, scalarStuff.MaybeU32);
1102             Assert.AreEqual((uint)10, scalarStuff.DefaultU32);
1103 
1104             Assert.AreEqual((long)11, scalarStuff.JustI64);
1105             Assert.AreEqual((long)11, scalarStuff.MaybeI64);
1106             Assert.AreEqual((long)11, scalarStuff.DefaultI64);
1107             Assert.AreEqual((ulong)12, scalarStuff.JustU64);
1108             Assert.AreEqual((ulong)12, scalarStuff.MaybeU64);
1109             Assert.AreEqual((ulong)12, scalarStuff.DefaultU64);
1110 
1111             Assert.AreEqual((float)13.0F, scalarStuff.JustF32);
1112             Assert.AreEqual((float)13.0F, scalarStuff.MaybeF32);
1113             Assert.AreEqual((float)13.0F, scalarStuff.DefaultF32);
1114 
1115             Assert.AreEqual((double)14.0, scalarStuff.JustF64);
1116             Assert.AreEqual((double)14.0, scalarStuff.MaybeF64);
1117             Assert.AreEqual((double)14.0, scalarStuff.DefaultF64);
1118 
1119             Assert.AreEqual(true, scalarStuff.JustBool);
1120             Assert.AreEqual(true, scalarStuff.MaybeBool);
1121             Assert.AreEqual(false, scalarStuff.DefaultBool);
1122 
1123             Assert.AreEqual(OptionalByte.Two, scalarStuff.JustEnum);
1124             Assert.AreEqual(OptionalByte.Two, scalarStuff.MaybeEnum);
1125             Assert.AreEqual(OptionalByte.Two, scalarStuff.DefaultEnum);
1126         }
1127 
1128 
1129         [FlatBuffersTestMethod]
TestKeywordEscaping()1130         public void TestKeywordEscaping() {
1131             Assert.AreEqual((int)KeywordTest.@public.NONE, 0);
1132 
1133             Assert.AreEqual((int)KeywordTest.ABC.@void, 0);
1134             Assert.AreEqual((int)KeywordTest.ABC.where, 1);
1135             Assert.AreEqual((int)KeywordTest.ABC.@stackalloc, 2);
1136 
1137             var fbb = new FlatBufferBuilder(1);
1138             var offset = KeywordsInTable.CreateKeywordsInTable(
1139                 fbb, KeywordTest.ABC.@stackalloc, KeywordTest.@public.NONE);
1140             fbb.Finish(offset.Value);
1141 
1142             KeywordsInTable keywordsInTable =
1143                 KeywordsInTable.GetRootAsKeywordsInTable(fbb.DataBuffer);
1144 
1145             Assert.AreEqual(keywordsInTable.Is, KeywordTest.ABC.@stackalloc);
1146             Assert.AreEqual(keywordsInTable.Private, KeywordTest.@public.NONE);
1147         }
1148 
1149 
1150         [FlatBuffersTestMethod]
AddOptionalEnum_WhenPassNull_ShouldWorkProperly()1151         public void AddOptionalEnum_WhenPassNull_ShouldWorkProperly() {
1152           var fbb = new FlatBufferBuilder(1);
1153           ScalarStuff.StartScalarStuff(fbb);
1154           ScalarStuff.AddMaybeEnum(fbb, null);
1155           var offset = ScalarStuff.EndScalarStuff(fbb);
1156           ScalarStuff.FinishScalarStuffBuffer(fbb, offset);
1157 
1158           ScalarStuff scalarStuff = ScalarStuff.GetRootAsScalarStuff(fbb.DataBuffer);
1159           Assert.AreEqual(null, scalarStuff.MaybeEnum);
1160         }
1161 
1162 
1163         [FlatBuffersTestMethod]
SortKey_WithDefaultedValue_IsFindable()1164         public void SortKey_WithDefaultedValue_IsFindable() {
1165             // This checks if using the `key` attribute that includes the
1166             // default value (e.g., 0) is still searchable. This is a regression
1167             // test for https://github.com/google/flatbuffers/issues/7380.
1168             var fbb = new FlatBufferBuilder(1);
1169 
1170             // Create a vector of Stat objects, with Count being the key.
1171             var stat_offsets = new Offset<Stat>[4];
1172             for(ushort i = 0; i < stat_offsets.Length; i++) {
1173                 Stat.StartStat(fbb);
1174                 Stat.AddCount(fbb, i);
1175                 stat_offsets[stat_offsets.Length - 1 - i] = Stat.EndStat(fbb);
1176             }
1177 
1178             // Ensure the sort works.
1179             var sort = Stat.CreateSortedVectorOfStat(fbb, stat_offsets);
1180 
1181             // Create the monster with the sorted vector of Stat objects.
1182             var str = fbb.CreateString("MyMonster");
1183             Monster.StartMonster(fbb);
1184             Monster.AddName(fbb, str);
1185             Monster.AddScalarKeySortedTables(fbb, sort);
1186             fbb.Finish(Monster.EndMonster(fbb).Value);
1187 
1188             // Get the monster.
1189             var monster = Monster.GetRootAsMonster(fbb.DataBuffer);
1190 
1191             // Ensure each key is findable.
1192             for(ushort i =0 ; i < stat_offsets.Length; i++) {
1193                 Assert.IsTrue(monster.ScalarKeySortedTablesByKey(i) != null);
1194                 Assert.AreEqual(monster.ScalarKeySortedTablesByKey(i).Value.Count, i);
1195             }
1196         }
1197     }
1198 }
1199