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