• 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 MyGame.Example;
20 
21 namespace FlatBuffers.Test
22 {
23     [FlatBuffersTestClass]
24     public class FlatBuffersExampleTests
25     {
RunTests()26         public void RunTests()
27         {
28             CanCreateNewFlatBufferFromScratch();
29             CanReadCppGeneratedWireFile();
30             TestEnums();
31         }
32 
33         [FlatBuffersTestMethod]
CanCreateNewFlatBufferFromScratch()34         public void CanCreateNewFlatBufferFromScratch()
35         {
36             CanCreateNewFlatBufferFromScratch(true);
37             CanCreateNewFlatBufferFromScratch(false);
38         }
39 
CanCreateNewFlatBufferFromScratch(bool sizePrefix)40         private void CanCreateNewFlatBufferFromScratch(bool sizePrefix)
41         {
42             // Second, let's create a FlatBuffer from scratch in C#, and test it also.
43             // We use an initial size of 1 to exercise the reallocation algorithm,
44             // normally a size larger than the typical FlatBuffer you generate would be
45             // better for performance.
46             var fbb = new FlatBufferBuilder(1);
47 
48             StringOffset[] names = { fbb.CreateString("Frodo"), fbb.CreateString("Barney"), fbb.CreateString("Wilma") };
49             Offset<Monster>[] off = new Offset<Monster>[3];
50             Monster.StartMonster(fbb);
51             Monster.AddName(fbb, names[0]);
52             off[0] = Monster.EndMonster(fbb);
53             Monster.StartMonster(fbb);
54             Monster.AddName(fbb, names[1]);
55             off[1] = Monster.EndMonster(fbb);
56             Monster.StartMonster(fbb);
57             Monster.AddName(fbb, names[2]);
58             off[2] = Monster.EndMonster(fbb);
59             var sortMons = Monster.CreateSortedVectorOfMonster(fbb, off);
60 
61             // We set up the same values as monsterdata.json:
62 
63             var str = fbb.CreateString("MyMonster");
64             var test1 = fbb.CreateString("test1");
65             var test2 = fbb.CreateString("test2");
66 
67 
68             Monster.StartInventoryVector(fbb, 5);
69             for (int i = 4; i >= 0; i--)
70             {
71                 fbb.AddByte((byte)i);
72             }
73             var inv = fbb.EndVector();
74 
75             var fred = fbb.CreateString("Fred");
76             Monster.StartMonster(fbb);
77             Monster.AddName(fbb, fred);
78             var mon2 = Monster.EndMonster(fbb);
79 
80             Monster.StartTest4Vector(fbb, 2);
81             MyGame.Example.Test.CreateTest(fbb, (short)10, (sbyte)20);
82             MyGame.Example.Test.CreateTest(fbb, (short)30, (sbyte)40);
83             var test4 = fbb.EndVector();
84 
85             Monster.StartTestarrayofstringVector(fbb, 2);
86             fbb.AddOffset(test2.Value);
87             fbb.AddOffset(test1.Value);
88             var testArrayOfString = fbb.EndVector();
89 
90             Monster.StartMonster(fbb);
91             Monster.AddPos(fbb, Vec3.CreateVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
92                                                      Color.Green, (short)5, (sbyte)6));
93             Monster.AddHp(fbb, (short)80);
94             Monster.AddName(fbb, str);
95             Monster.AddInventory(fbb, inv);
96             Monster.AddTestType(fbb, Any.Monster);
97             Monster.AddTest(fbb, mon2.Value);
98             Monster.AddTest4(fbb, test4);
99             Monster.AddTestarrayofstring(fbb, testArrayOfString);
100             Monster.AddTestbool(fbb, true);
101             Monster.AddTestarrayoftables(fbb, sortMons);
102             var mon = Monster.EndMonster(fbb);
103 
104             if (sizePrefix)
105             {
106                 Monster.FinishSizePrefixedMonsterBuffer(fbb, mon);
107             }
108             else
109             {
110                 Monster.FinishMonsterBuffer(fbb, mon);
111             }
112 
113             // Dump to output directory so we can inspect later, if needed
114 #if ENABLE_SPAN_T
115             var data = fbb.DataBuffer.ToSizedArray();
116             string filename = @"Resources/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
117             File.WriteAllBytes(filename, data);
118 #else
119             using (var ms = fbb.DataBuffer.ToMemoryStream(fbb.DataBuffer.Position, fbb.Offset))
120             {
121                 var data = ms.ToArray();
122                 string filename = @"Resources/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
123                 File.WriteAllBytes(filename, data);
124             }
125 #endif
126 
127             // Remove the size prefix if necessary for further testing
128             ByteBuffer dataBuffer = fbb.DataBuffer;
129             if (sizePrefix)
130             {
131                 Assert.AreEqual(ByteBufferUtil.GetSizePrefix(dataBuffer) + FlatBufferConstants.SizePrefixLength,
132                                 dataBuffer.Length - dataBuffer.Position);
133                 dataBuffer = ByteBufferUtil.RemoveSizePrefix(dataBuffer);
134             }
135 
136             // Now assert the buffer
137             TestBuffer(dataBuffer);
138 
139             //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
140             // revert to original values after testing
141             Monster monster = Monster.GetRootAsMonster(dataBuffer);
142 
143 
144             // mana is optional and does not exist in the buffer so the mutation should fail
145             // the mana field should retain its default value
146             Assert.AreEqual(monster.MutateMana((short)10), false);
147             Assert.AreEqual(monster.Mana, (short)150);
148 
149             // Accessing a vector of sorted by the key tables
150             Assert.AreEqual(monster.Testarrayoftables(0).Value.Name, "Barney");
151             Assert.AreEqual(monster.Testarrayoftables(1).Value.Name, "Frodo");
152             Assert.AreEqual(monster.Testarrayoftables(2).Value.Name, "Wilma");
153 
154             // Example of searching for a table by the key
155             Assert.IsTrue(monster.TestarrayoftablesByKey("Frodo") != null);
156             Assert.IsTrue(monster.TestarrayoftablesByKey("Barney") != null);
157             Assert.IsTrue(monster.TestarrayoftablesByKey("Wilma") != null);
158 
159             // testType is an existing field and mutating it should succeed
160             Assert.AreEqual(monster.TestType, Any.Monster);
161             Assert.AreEqual(monster.MutateTestType(Any.NONE), true);
162             Assert.AreEqual(monster.TestType, Any.NONE);
163             Assert.AreEqual(monster.MutateTestType(Any.Monster), true);
164             Assert.AreEqual(monster.TestType, Any.Monster);
165 
166             //mutate the inventory vector
167             Assert.AreEqual(monster.MutateInventory(0, 1), true);
168             Assert.AreEqual(monster.MutateInventory(1, 2), true);
169             Assert.AreEqual(monster.MutateInventory(2, 3), true);
170             Assert.AreEqual(monster.MutateInventory(3, 4), true);
171             Assert.AreEqual(monster.MutateInventory(4, 5), true);
172 
173             for (int i = 0; i < monster.InventoryLength; i++)
174             {
175                 Assert.AreEqual(monster.Inventory(i), i + 1);
176             }
177 
178             //reverse mutation
179             Assert.AreEqual(monster.MutateInventory(0, 0), true);
180             Assert.AreEqual(monster.MutateInventory(1, 1), true);
181             Assert.AreEqual(monster.MutateInventory(2, 2), true);
182             Assert.AreEqual(monster.MutateInventory(3, 3), true);
183             Assert.AreEqual(monster.MutateInventory(4, 4), true);
184 
185             // get a struct field and edit one of its fields
186             Vec3 pos = (Vec3)monster.Pos;
187             Assert.AreEqual(pos.X, 1.0f);
188             pos.MutateX(55.0f);
189             Assert.AreEqual(pos.X, 55.0f);
190             pos.MutateX(1.0f);
191             Assert.AreEqual(pos.X, 1.0f);
192 
193             TestBuffer(dataBuffer);
194         }
195 
TestBuffer(ByteBuffer bb)196         private void TestBuffer(ByteBuffer bb)
197         {
198             Monster monster = Monster.GetRootAsMonster(bb);
199 
200             Assert.AreEqual(80, monster.Hp);
201             Assert.AreEqual(150, monster.Mana);
202             Assert.AreEqual("MyMonster", monster.Name);
203 
204             var pos = monster.Pos.Value;
205             Assert.AreEqual(1.0f, pos.X);
206             Assert.AreEqual(2.0f, pos.Y);
207             Assert.AreEqual(3.0f, pos.Z);
208 
209             Assert.AreEqual(3.0f, pos.Test1);
210             Assert.AreEqual(Color.Green, pos.Test2);
211             var t = (MyGame.Example.Test)pos.Test3;
212             Assert.AreEqual((short)5, t.A);
213             Assert.AreEqual((sbyte)6, t.B);
214 
215             Assert.AreEqual(Any.Monster, monster.TestType);
216 
217             var monster2 = monster.Test<Monster>().Value;
218             Assert.AreEqual("Fred", monster2.Name);
219 
220 
221             Assert.AreEqual(5, monster.InventoryLength);
222             var invsum = 0;
223             for (var i = 0; i < monster.InventoryLength; i++)
224             {
225                 invsum += monster.Inventory(i);
226             }
227             Assert.AreEqual(10, invsum);
228 
229             // Get the inventory as an array and subtract the
230             // sum to get it back to 0
231             var inventoryArray = monster.GetInventoryArray();
232             Assert.AreEqual(5, inventoryArray.Length);
233             foreach(var inv in inventoryArray)
234             {
235                 invsum -= inv;
236             }
237             Assert.AreEqual(0, invsum);
238 
239             var test0 = monster.Test4(0).Value;
240             var test1 = monster.Test4(1).Value;
241             Assert.AreEqual(2, monster.Test4Length);
242 
243             Assert.AreEqual(100, test0.A + test0.B + test1.A + test1.B);
244 
245             Assert.AreEqual(2, monster.TestarrayofstringLength);
246             Assert.AreEqual("test1", monster.Testarrayofstring(0));
247             Assert.AreEqual("test2", monster.Testarrayofstring(1));
248 
249             Assert.AreEqual(true, monster.Testbool);
250 
251 #if ENABLE_SPAN_T
252             var nameBytes = monster.GetNameBytes();
253             Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.ToArray(), 0, nameBytes.Length));
254 
255             if (0 == monster.TestarrayofboolsLength)
256             {
257                 Assert.IsFalse(monster.GetTestarrayofboolsBytes().Length != 0);
258             }
259             else
260             {
261                 Assert.IsTrue(monster.GetTestarrayofboolsBytes().Length != 0);
262             }
263 #else
264             var nameBytes = monster.GetNameBytes().Value;
265             Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.Array, nameBytes.Offset, nameBytes.Count));
266 
267             if (0 == monster.TestarrayofboolsLength)
268             {
269                 Assert.IsFalse(monster.GetTestarrayofboolsBytes().HasValue);
270             }
271             else
272             {
273                 Assert.IsTrue(monster.GetTestarrayofboolsBytes().HasValue);
274             }
275 #endif
276         }
277 
278         [FlatBuffersTestMethod]
CanReadCppGeneratedWireFile()279         public void CanReadCppGeneratedWireFile()
280         {
281             var data = File.ReadAllBytes(@"Resources/monsterdata_test.mon");
282             var bb = new ByteBuffer(data);
283             TestBuffer(bb);
284         }
285 
286         [FlatBuffersTestMethod]
TestEnums()287         public void TestEnums()
288         {
289             Assert.AreEqual("Red", Color.Red.ToString());
290             Assert.AreEqual("Blue", Color.Blue.ToString());
291             Assert.AreEqual("NONE", Any.NONE.ToString());
292             Assert.AreEqual("Monster", Any.Monster.ToString());
293         }
294 
295         [FlatBuffersTestMethod]
TestNestedFlatBuffer()296         public void TestNestedFlatBuffer()
297         {
298             const string nestedMonsterName = "NestedMonsterName";
299             const short nestedMonsterHp = 600;
300             const short nestedMonsterMana = 1024;
301             // Create nested buffer as a Monster type
302             var fbb1 = new FlatBufferBuilder(16);
303             var str1 = fbb1.CreateString(nestedMonsterName);
304             Monster.StartMonster(fbb1);
305             Monster.AddName(fbb1, str1);
306             Monster.AddHp(fbb1, nestedMonsterHp);
307             Monster.AddMana(fbb1, nestedMonsterMana);
308             var monster1 = Monster.EndMonster(fbb1);
309             Monster.FinishMonsterBuffer(fbb1, monster1);
310             var fbb1Bytes = fbb1.SizedByteArray();
311             fbb1 = null;
312 
313             // Create a Monster which has the first buffer as a nested buffer
314             var fbb2 = new FlatBufferBuilder(16);
315             var str2 = fbb2.CreateString("My Monster");
316             var nestedBuffer = Monster.CreateTestnestedflatbufferVector(fbb2, fbb1Bytes);
317             Monster.StartMonster(fbb2);
318             Monster.AddName(fbb2, str2);
319             Monster.AddHp(fbb2, 50);
320             Monster.AddMana(fbb2, 32);
321             Monster.AddTestnestedflatbuffer(fbb2, nestedBuffer);
322             var monster = Monster.EndMonster(fbb2);
323             Monster.FinishMonsterBuffer(fbb2, monster);
324 
325             // Now test the data extracted from the nested buffer
326             var mons = Monster.GetRootAsMonster(fbb2.DataBuffer);
327             var nestedMonster = mons.GetTestnestedflatbufferAsMonster().Value;
328 
329             Assert.AreEqual(nestedMonsterMana, nestedMonster.Mana);
330             Assert.AreEqual(nestedMonsterHp, nestedMonster.Hp);
331             Assert.AreEqual(nestedMonsterName, nestedMonster.Name);
332         }
333     }
334 }
335