1
16
17 package main
18
19 import (
20 mygame "MyGame"
21 example "MyGame/Example"
22 pizza "Pizza"
23 "encoding/json"
24 optional_scalars "optional_scalars"
25 order "order"
26
27 "bytes"
28 "flag"
29 "fmt"
30 "os"
31 "reflect"
32 "sort"
33 "testing"
34 "testing/quick"
35
36 flatbuffers "github.com/google/flatbuffers/go"
37 )
38
39 var (
40 cppData, javaData, outData string
41 fuzz bool
42 fuzzFields, fuzzObjects int
43 )
44
45 func init() {
46 flag.StringVar(&cppData, "cpp_data", "",
47 "location of monsterdata_test.mon to verify against (required)")
48 flag.StringVar(&javaData, "java_data", "",
49 "location of monsterdata_java_wire.mon to verify against (optional)")
50 flag.StringVar(&outData, "out_data", "",
51 "location to write generated Go data")
52 flag.BoolVar(&fuzz, "fuzz", false, "perform fuzzing")
53 flag.IntVar(&fuzzFields, "fuzz_fields", 4, "fields per fuzzer object")
54 flag.IntVar(&fuzzObjects, "fuzz_objects", 10000,
55 "number of fuzzer objects (higher is slower and more thorough")
56 }
57
58
59
60 var (
61 overflowingInt32Val = flatbuffers.GetInt32([]byte{0x83, 0x33, 0x33, 0x33})
62 overflowingInt64Val = flatbuffers.GetInt64([]byte{0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44})
63 )
64
65 func TestMain(m *testing.M) {
66 flag.Parse()
67 if cppData == "" {
68 fmt.Fprintf(os.Stderr, "cpp_data argument is required\n")
69 os.Exit(1)
70 }
71 os.Exit(m.Run())
72 }
73
74
75 func TestTextParsing(t *testing.T) {
76 expectedMonster := example.MonsterT{
77 Mana: 42,
78 Name: "foo",
79 LongEnumNormalDefault: example.LongEnumLongTwo,
80 }
81
82 buf := new(bytes.Buffer)
83 if err := json.NewEncoder(buf).Encode(expectedMonster); err != nil {
84 t.Fatal(err)
85 }
86
87 var monster example.MonsterT
88 if err := json.NewDecoder(buf).Decode(&monster); err != nil {
89 t.Fatal(err)
90 }
91
92 if monster.Mana != expectedMonster.Mana {
93 t.Fatal("wrong mana:", monster.Mana)
94 }
95 if monster.Name != expectedMonster.Name {
96 t.Fatal("wrong name:", monster.Name)
97 }
98 if monster.LongEnumNormalDefault != expectedMonster.LongEnumNormalDefault {
99 t.Fatal("wrong enum:", monster.LongEnumNormalDefault)
100 }
101 }
102
103 func CheckNoNamespaceImport(fail func(string, ...interface{})) {
104 const size = 13
105
106 builder := flatbuffers.NewBuilder(0)
107 ordered_pizza := pizza.PizzaT{Size: size}
108 food := order.FoodT{Pizza: &ordered_pizza}
109 builder.Finish(food.Pack(builder))
110
111
112 received_food := order.GetRootAsFood(builder.FinishedBytes(), 0)
113 received_pizza := received_food.Pizza(nil).UnPack()
114
115
116 if !reflect.DeepEqual(ordered_pizza, *received_pizza) {
117 fail(FailString("no namespace import", ordered_pizza, received_pizza))
118 }
119 }
120
121
122 func TestAll(t *testing.T) {
123
124
125 CheckByteLayout(t.Fatalf)
126 CheckMutateMethods(t.Fatalf)
127
128
129 CheckNotInObjectError(t.Fatalf)
130 CheckStringIsNestedError(t.Fatalf)
131 CheckByteStringIsNestedError(t.Fatalf)
132 CheckStructIsNotInlineError(t.Fatalf)
133 CheckFinishedBytesError(t.Fatalf)
134 CheckSharedStrings(t.Fatalf)
135 CheckEmptiedBuilder(t.Fatalf)
136
137
138 CheckGetRootAsForNonRootTable(t.Fatalf)
139 CheckTableAccessors(t.Fatalf)
140
141
142
143 generated, off := CheckGeneratedBuild(false, false, t.Fatalf)
144
145
146
147 CheckReadBuffer(generated, off, false, t.Fatalf)
148 CheckMutateBuffer(generated, off, false, t.Fatalf)
149 CheckObjectAPI(generated, off, false, t.Fatalf)
150
151
152 generated, off = CheckGeneratedBuild(false, true, t.Fatalf)
153
154
155
156 CheckReadBuffer(generated, off, false, t.Fatalf)
157 CheckMutateBuffer(generated, off, false, t.Fatalf)
158 CheckObjectAPI(generated, off, false, t.Fatalf)
159 CheckFileIdentifier(generated, off, false, t.Fatalf)
160
161
162
163 monsterDataCpp, err := os.ReadFile(cppData)
164 if err != nil {
165 t.Fatal(err)
166 }
167 CheckReadBuffer(monsterDataCpp, 0, false, t.Fatalf)
168 CheckMutateBuffer(monsterDataCpp, 0, false, t.Fatalf)
169 CheckObjectAPI(monsterDataCpp, 0, false, t.Fatalf)
170 CheckFileIdentifier(monsterDataCpp, 0, false, t.Fatalf)
171
172
173 CheckVtableDeduplication(t.Fatalf)
174
175
176 CheckEnumNames(t.Fatalf)
177
178
179 CheckEnumString(t.Fatalf)
180
181
182 CheckEnumValues(t.Fatalf)
183
184
185
186 CheckDocExample(generated, off, t.Fatalf)
187
188
189 CheckCreateByteVector(t.Fatalf)
190
191
192 CheckParentNamespace(t.Fatalf)
193
194
195 CheckNoNamespaceImport(t.Fatalf)
196
197
198 CheckSizePrefixedBuffer(t.Fatalf)
199
200
201 CheckOptionalScalars(t.Fatalf)
202
203
204 CheckByKey(t.Fatalf)
205
206
207
208
209 if javaData != "" {
210 monsterDataJava, err := os.ReadFile(javaData)
211 if err != nil {
212 t.Fatal(err)
213 }
214 CheckReadBuffer(monsterDataJava, 0, false, t.Fatalf)
215 CheckByteEquality(generated[off:], monsterDataJava, t.Fatalf)
216 }
217
218
219 if fuzz {
220 checkFuzz(fuzzFields, fuzzObjects, t.Fatalf)
221 }
222
223
224 err = os.WriteFile(outData, generated[off:], os.FileMode(0644))
225 if err != nil {
226 t.Fatal(err)
227 }
228 }
229
230
231
232 func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, sizePrefix bool, fail func(string, ...interface{})) {
233
234 var monster1 *example.Monster
235 monster2 := &example.Monster{}
236
237 if sizePrefix {
238 monster1 = example.GetSizePrefixedRootAsMonster(buf, offset)
239 flatbuffers.GetSizePrefixedRootAs(buf, offset, monster2)
240 } else {
241 monster1 = example.GetRootAsMonster(buf, offset)
242 flatbuffers.GetRootAs(buf, offset, monster2)
243 }
244
245 for _, monster := range []*example.Monster{monster1, monster2} {
246 if got := monster.Hp(); 80 != got {
247 fail(FailString("hp", 80, got))
248 }
249
250
251 if got := monster.Mana(); 150 != got {
252 fail(FailString("mana", 150, got))
253 }
254
255 if got := monster.Name(); !bytes.Equal([]byte("MyMonster"), got) {
256 fail(FailString("name", "MyMonster", got))
257 }
258
259 if got := monster.Color(); example.ColorBlue != got {
260 fail(FailString("color", example.ColorBlue, got))
261 }
262
263 if got := monster.Testbool(); true != got {
264 fail(FailString("testbool", true, got))
265 }
266
267
268 vec := new(example.Vec3)
269 vec = monster.Pos(vec)
270 if vec == nil {
271 fail("vec3 initialization failed")
272 }
273
274
275 vec2 := monster.Pos(nil)
276 if !reflect.DeepEqual(vec, vec2) {
277 fail("fresh allocation failed")
278 }
279
280
281 if got := vec.X(); float32(1.0) != got {
282 fail(FailString("Pos.X", float32(1.0), got))
283 }
284
285 if got := vec.Y(); float32(2.0) != got {
286 fail(FailString("Pos.Y", float32(2.0), got))
287 }
288
289 if got := vec.Z(); float32(3.0) != got {
290 fail(FailString("Pos.Z", float32(3.0), got))
291 }
292
293 if got := vec.Test1(); float64(3.0) != got {
294 fail(FailString("Pos.Test1", float64(3.0), got))
295 }
296
297 if got := vec.Test2(); example.ColorGreen != got {
298 fail(FailString("Pos.Test2", example.ColorGreen, got))
299 }
300
301
302 t := new(example.Test)
303 t = vec.Test3(t)
304 if t == nil {
305 fail("vec.Test3(&t) failed")
306 }
307
308
309 t2 := vec.Test3(nil)
310 if !reflect.DeepEqual(t, t2) {
311 fail("fresh allocation failed")
312 }
313
314
315 if got := t.A(); int16(5) != got {
316 fail(FailString("t.A()", int16(5), got))
317 }
318
319 if got := t.B(); int8(6) != got {
320 fail(FailString("t.B()", int8(6), got))
321 }
322
323 if got := monster.TestType(); example.AnyMonster != got {
324 fail(FailString("monster.TestType()", example.AnyMonster, got))
325 }
326
327
328 var table2 flatbuffers.Table
329 if ok := monster.Test(&table2); !ok {
330 fail("monster.Test(&monster2) failed")
331 }
332
333
334 var monster2 example.Monster
335 monster2.Init(table2.Bytes, table2.Pos)
336
337 if got := monster2.Name(); !bytes.Equal([]byte("Fred"), got) {
338 fail(FailString("monster2.Name()", "Fred", got))
339 }
340
341 inventorySlice := monster.InventoryBytes()
342 if len(inventorySlice) != monster.InventoryLength() {
343 fail(FailString("len(monster.InventoryBytes) != monster.InventoryLength", len(inventorySlice), monster.InventoryLength()))
344 }
345
346 if got := monster.InventoryLength(); 5 != got {
347 fail(FailString("monster.InventoryLength", 5, got))
348 }
349
350 invsum := 0
351 l := monster.InventoryLength()
352 for i := 0; i < l; i++ {
353 v := monster.Inventory(i)
354 if v != inventorySlice[i] {
355 fail(FailString("monster inventory slice[i] != Inventory(i)", v, inventorySlice[i]))
356 }
357 invsum += int(v)
358 }
359 if invsum != 10 {
360 fail(FailString("monster inventory sum", 10, invsum))
361 }
362
363 if got := monster.Test4Length(); 2 != got {
364 fail(FailString("monster.Test4Length()", 2, got))
365 }
366
367 var test0 example.Test
368 ok := monster.Test4(&test0, 0)
369 if !ok {
370 fail(FailString("monster.Test4(&test0, 0)", true, ok))
371 }
372
373 var test1 example.Test
374 ok = monster.Test4(&test1, 1)
375 if !ok {
376 fail(FailString("monster.Test4(&test1, 1)", true, ok))
377 }
378
379
380
381 v0 := test0.A()
382 v1 := test0.B()
383 v2 := test1.A()
384 v3 := test1.B()
385 sum := int(v0) + int(v1) + int(v2) + int(v3)
386
387 if 100 != sum {
388 fail(FailString("test0 and test1 sum", 100, sum))
389 }
390
391 if got := monster.TestarrayofstringLength(); 2 != got {
392 fail(FailString("Testarrayofstring length", 2, got))
393 }
394
395 if got := monster.Testarrayofstring(0); !bytes.Equal([]byte("test1"), got) {
396 fail(FailString("Testarrayofstring(0)", "test1", got))
397 }
398
399 if got := monster.Testarrayofstring(1); !bytes.Equal([]byte("test2"), got) {
400 fail(FailString("Testarrayofstring(1)", "test2", got))
401 }
402 }
403 }
404
405
406 func CheckFileIdentifier(buf []byte, offset flatbuffers.UOffsetT, sizePrefix bool, fail func(string, ...interface{})) {
407
408 buf = buf[offset:]
409
410 var fileIdentifier string
411 var hasFileIdentifier bool
412
413 if sizePrefix {
414 fileIdentifier = flatbuffers.GetSizePrefixedBufferIdentifier(buf)
415 hasFileIdentifier = example.SizePrefixedMonsterBufferHasIdentifier(buf)
416 } else {
417 fileIdentifier = flatbuffers.GetBufferIdentifier(buf)
418 hasFileIdentifier = example.MonsterBufferHasIdentifier(buf)
419 }
420
421 expectedFileIdentifier := "MONS"
422 if fileIdentifier != expectedFileIdentifier {
423 fail("expected file identifier %q, got %q", expectedFileIdentifier, fileIdentifier)
424 }
425 if !hasFileIdentifier {
426 fail("did not find file identifier")
427 }
428 }
429
430
431
432 func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, sizePrefix bool, fail func(string, ...interface{})) {
433
434 buf := make([]byte, len(org))
435 copy(buf, org)
436
437
438 var monster *example.Monster
439 if sizePrefix {
440 monster = example.GetSizePrefixedRootAsMonster(buf, offset)
441 } else {
442 monster = example.GetRootAsMonster(buf, offset)
443 }
444
445
446 type testcase struct {
447 field string
448 testfn func() bool
449 }
450
451 testForOriginalValues := []testcase{
452 testcase{"Hp", func() bool { return monster.Hp() == 80 }},
453 testcase{"Mana", func() bool { return monster.Mana() == 150 }},
454 testcase{"Testbool", func() bool { return monster.Testbool() == true }},
455 testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(1.0) }},
456 testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(2.0) }},
457 testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(3.0) }},
458 testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(3.0) }},
459 testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorGreen }},
460 testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(5) }},
461 testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(6) }},
462 testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(2) }},
463 }
464
465 testMutability := []testcase{
466 testcase{"Hp", func() bool { return monster.MutateHp(70) }},
467 testcase{"Mana", func() bool { return !monster.MutateMana(140) }},
468 testcase{"Testbool", func() bool { return monster.MutateTestbool(false) }},
469 testcase{"Pos.X", func() bool { return monster.Pos(nil).MutateX(10.0) }},
470 testcase{"Pos.Y", func() bool { return monster.Pos(nil).MutateY(20.0) }},
471 testcase{"Pos.Z", func() bool { return monster.Pos(nil).MutateZ(30.0) }},
472 testcase{"Pos.Test1", func() bool { return monster.Pos(nil).MutateTest1(30.0) }},
473 testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.ColorBlue) }},
474 testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).MutateA(50) }},
475 testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).MutateB(60) }},
476 testcase{"Inventory[2]", func() bool { return monster.MutateInventory(2, 200) }},
477 }
478
479 testForMutatedValues := []testcase{
480 testcase{"Hp", func() bool { return monster.Hp() == 70 }},
481 testcase{"Mana", func() bool { return monster.Mana() == 150 }},
482 testcase{"Testbool", func() bool { return monster.Testbool() == false }},
483 testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(10.0) }},
484 testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(20.0) }},
485 testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(30.0) }},
486 testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(30.0) }},
487 testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorBlue }},
488 testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(50) }},
489 testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(60) }},
490 testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(200) }},
491 }
492
493 testInvalidEnumValues := []testcase{
494 testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.Color(20)) }},
495 testcase{"Pos.Test2", func() bool { return monster.Pos(nil).Test2() == example.Color(20) }},
496 }
497
498
499 for _, t := range testForOriginalValues {
500 if !t.testfn() {
501 fail("field '" + t.field + "' doesn't have the expected original value")
502 }
503 }
504
505
506 for _, t := range testMutability {
507 if !t.testfn() {
508 fail(FailString("field '"+t.field+"' failed mutability test", true, false))
509 }
510 }
511
512
513 for _, t := range testForMutatedValues {
514 if !t.testfn() {
515 fail("field '" + t.field + "' doesn't have the expected mutated value")
516 }
517 }
518
519
520 if reflect.DeepEqual(buf, org) {
521 fail("mutate buffer failed")
522 }
523
524
525
526 if sizePrefix {
527 monster = example.GetSizePrefixedRootAsMonster(buf, offset)
528 } else {
529 monster = example.GetRootAsMonster(buf, offset)
530 }
531
532 for _, t := range testForMutatedValues {
533 if !t.testfn() {
534 fail("field '" + t.field + "' doesn't have the expected mutated value")
535 }
536 }
537
538
539
540 for _, t := range testInvalidEnumValues {
541 if !t.testfn() {
542 fail("field '" + t.field + "' doesn't work with an invalid enum value")
543 }
544 }
545
546
547
548
549
550
551 if sizePrefix {
552 monster = example.GetSizePrefixedRootAsMonster(buf, offset)
553 } else {
554 monster = example.GetRootAsMonster(buf, offset)
555 }
556
557 monster.MutateHp(80)
558 monster.MutateTestbool(true)
559 monster.Pos(nil).MutateX(1.0)
560 monster.Pos(nil).MutateY(2.0)
561 monster.Pos(nil).MutateZ(3.0)
562 monster.Pos(nil).MutateTest1(3.0)
563 monster.Pos(nil).MutateTest2(example.ColorGreen)
564 monster.Pos(nil).Test3(nil).MutateA(5)
565 monster.Pos(nil).Test3(nil).MutateB(6)
566 monster.MutateInventory(2, 2)
567
568 for _, t := range testForOriginalValues {
569 if !t.testfn() {
570 fail("field '" + t.field + "' doesn't have the expected original value")
571 }
572 }
573
574
575 if !reflect.DeepEqual(buf, org) {
576 fail("revert changes failed")
577 }
578 }
579
580 func CheckObjectAPI(buf []byte, offset flatbuffers.UOffsetT, sizePrefix bool, fail func(string, ...interface{})) {
581 var monster *example.MonsterT
582
583 if sizePrefix {
584 monster = example.GetSizePrefixedRootAsMonster(buf, offset).UnPack()
585 } else {
586 monster = example.GetRootAsMonster(buf, offset).UnPack()
587 }
588
589 if got := monster.Hp; 80 != got {
590 fail(FailString("hp", 80, got))
591 }
592
593
594 if got := monster.Mana; 150 != got {
595 fail(FailString("mana", 150, got))
596 }
597
598 if monster.Test != nil && monster.Test.Type == example.AnyMonster {
599 monster.Test.Value.(*example.MonsterT).NanDefault = 0.0
600 }
601 if monster.Enemy != nil {
602 monster.Enemy.NanDefault = 0.0
603 }
604 monster.NanDefault = 0.0
605
606 builder := flatbuffers.NewBuilder(0)
607 builder.Finish(monster.Pack(builder))
608 monster2 := example.GetRootAsMonster(builder.FinishedBytes(), 0).UnPack()
609 if !reflect.DeepEqual(monster, monster2) {
610 fail(FailString("Pack/Unpack()", monster, monster2))
611 }
612 }
613
614
615
616 func checkFuzz(fuzzFields, fuzzObjects int, fail func(string, ...interface{})) {
617
618
619
620 boolVal := true
621 int8Val := int8(-127)
622 uint8Val := uint8(0xFF)
623 int16Val := int16(-32222)
624 uint16Val := uint16(0xFEEE)
625 int32Val := int32(overflowingInt32Val)
626 uint32Val := uint32(0xFDDDDDDD)
627 int64Val := int64(overflowingInt64Val)
628 uint64Val := uint64(0xFCCCCCCCCCCCCCCC)
629 float32Val := float32(3.14159)
630 float64Val := float64(3.14159265359)
631
632 testValuesMax := 11
633
634 builder := flatbuffers.NewBuilder(0)
635 l := NewLCG()
636
637 objects := make([]flatbuffers.UOffsetT, fuzzObjects)
638
639
640
641 for i := 0; i < fuzzObjects; i++ {
642 builder.StartObject(fuzzFields)
643
644 for f := 0; f < fuzzFields; f++ {
645 choice := l.Next() % uint32(testValuesMax)
646 switch choice {
647 case 0:
648 builder.PrependBoolSlot(int(f), boolVal, false)
649 case 1:
650 builder.PrependInt8Slot(int(f), int8Val, 0)
651 case 2:
652 builder.PrependUint8Slot(int(f), uint8Val, 0)
653 case 3:
654 builder.PrependInt16Slot(int(f), int16Val, 0)
655 case 4:
656 builder.PrependUint16Slot(int(f), uint16Val, 0)
657 case 5:
658 builder.PrependInt32Slot(int(f), int32Val, 0)
659 case 6:
660 builder.PrependUint32Slot(int(f), uint32Val, 0)
661 case 7:
662 builder.PrependInt64Slot(int(f), int64Val, 0)
663 case 8:
664 builder.PrependUint64Slot(int(f), uint64Val, 0)
665 case 9:
666 builder.PrependFloat32Slot(int(f), float32Val, 0)
667 case 10:
668 builder.PrependFloat64Slot(int(f), float64Val, 0)
669 }
670 }
671
672 off := builder.EndObject()
673
674
675
676 objects[i] = off
677 }
678
679
680 stats := map[string]int{}
681 check := func(desc string, want, got interface{}) {
682 stats[desc]++
683 if want != got {
684 fail("%s want %v got %v", desc, want, got)
685 }
686 }
687
688 l = NewLCG()
689
690
691
692
693 for i := 0; i < fuzzObjects; i++ {
694
695 table := &flatbuffers.Table{
696 Bytes: builder.Bytes,
697 Pos: flatbuffers.UOffsetT(len(builder.Bytes)) - objects[i],
698 }
699
700 for j := 0; j < fuzzFields; j++ {
701 f := flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + j) * flatbuffers.SizeVOffsetT)
702 choice := l.Next() % uint32(testValuesMax)
703
704 switch choice {
705 case 0:
706 check("bool", boolVal, table.GetBoolSlot(f, false))
707 case 1:
708 check("int8", int8Val, table.GetInt8Slot(f, 0))
709 case 2:
710 check("uint8", uint8Val, table.GetUint8Slot(f, 0))
711 case 3:
712 check("int16", int16Val, table.GetInt16Slot(f, 0))
713 case 4:
714 check("uint16", uint16Val, table.GetUint16Slot(f, 0))
715 case 5:
716 check("int32", int32Val, table.GetInt32Slot(f, 0))
717 case 6:
718 check("uint32", uint32Val, table.GetUint32Slot(f, 0))
719 case 7:
720 check("int64", int64Val, table.GetInt64Slot(f, 0))
721 case 8:
722 check("uint64", uint64Val, table.GetUint64Slot(f, 0))
723 case 9:
724 check("float32", float32Val, table.GetFloat32Slot(f, 0))
725 case 10:
726 check("float64", float64Val, table.GetFloat64Slot(f, 0))
727 }
728 }
729 }
730
731
732 if fuzzFields*fuzzObjects >= testValuesMax {
733 if len(stats) != testValuesMax {
734 fail("fuzzing failed to test all scalar types")
735 }
736 }
737
738
739 if testing.Verbose() {
740 if fuzzFields == 0 || fuzzObjects == 0 {
741 fmt.Printf("fuzz\tfields: %d\tobjects: %d\t[none]\t%d\n",
742 fuzzFields, fuzzObjects, 0)
743 } else {
744 keys := make([]string, 0, len(stats))
745 for k := range stats {
746 keys = append(keys, k)
747 }
748 sort.Strings(keys)
749 for _, k := range keys {
750 fmt.Printf("fuzz\tfields: %d\tobjects: %d\t%s\t%d\n",
751 fuzzFields, fuzzObjects, k, stats[k])
752 }
753 }
754 }
755
756 return
757 }
758
759
760 func FailString(name string, want, got interface{}) string {
761 return fmt.Sprintf("bad %s: want %#v got %#v", name, want, got)
762 }
763
764
765 func CheckByteLayout(fail func(string, ...interface{})) {
766 var b *flatbuffers.Builder
767
768 var i int
769 check := func(want []byte) {
770 i++
771 got := b.Bytes[b.Head():]
772 if !bytes.Equal(want, got) {
773 fail("case %d: want\n%v\nbut got\n%v\n", i, want, got)
774 }
775 }
776
777
778
779 b = flatbuffers.NewBuilder(0)
780 check([]byte{})
781 b.PrependBool(true)
782 check([]byte{1})
783 b.PrependInt8(-127)
784 check([]byte{129, 1})
785 b.PrependUint8(255)
786 check([]byte{255, 129, 1})
787 b.PrependInt16(-32222)
788 check([]byte{0x22, 0x82, 0, 255, 129, 1})
789 b.PrependUint16(0xFEEE)
790 check([]byte{0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
791 b.PrependInt32(-53687092)
792 check([]byte{204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
793 b.PrependUint32(0x98765432)
794 check([]byte{0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
795
796
797
798 b = flatbuffers.NewBuilder(0)
799 b.PrependUint64(0x1122334455667788)
800 check([]byte{0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11})
801
802
803
804 b = flatbuffers.NewBuilder(0)
805 check([]byte{})
806 b.StartVector(flatbuffers.SizeByte, 1, 1)
807 check([]byte{0, 0, 0})
808 b.PrependByte(1)
809 check([]byte{1, 0, 0, 0})
810 b.EndVector(1)
811 check([]byte{1, 0, 0, 0, 1, 0, 0, 0})
812
813
814
815 b = flatbuffers.NewBuilder(0)
816 b.StartVector(flatbuffers.SizeByte, 2, 1)
817 check([]byte{0, 0})
818 b.PrependByte(1)
819 check([]byte{1, 0, 0})
820 b.PrependByte(2)
821 check([]byte{2, 1, 0, 0})
822 b.EndVector(2)
823 check([]byte{2, 0, 0, 0, 2, 1, 0, 0})
824
825
826
827 b = flatbuffers.NewBuilder(12)
828 b.StartVector(flatbuffers.SizeByte, 8, 1)
829 start := []byte{}
830 check(start)
831 for i := 1; i < 12; i++ {
832 b.PrependByte(byte(i))
833 start = append([]byte{byte(i)}, start...)
834 check(start)
835 }
836 b.EndVector(8)
837 check(append([]byte{8, 0, 0, 0}, start...))
838
839
840
841 b = flatbuffers.NewBuilder(0)
842 b.StartVector(flatbuffers.SizeUint16, 1, 1)
843 check([]byte{0, 0})
844 b.PrependUint16(1)
845 check([]byte{1, 0, 0, 0})
846 b.EndVector(1)
847 check([]byte{1, 0, 0, 0, 1, 0, 0, 0})
848
849
850
851 b = flatbuffers.NewBuilder(0)
852 b.StartVector(flatbuffers.SizeUint16, 2, 1)
853 check([]byte{})
854 b.PrependUint16(0xABCD)
855 check([]byte{0xCD, 0xAB})
856 b.PrependUint16(0xDCBA)
857 check([]byte{0xBA, 0xDC, 0xCD, 0xAB})
858 b.EndVector(2)
859 check([]byte{2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB})
860
861
862
863 b = flatbuffers.NewBuilder(0)
864 b.CreateString("foo")
865 check([]byte{3, 0, 0, 0, 'f', 'o', 'o', 0})
866 b.CreateString("moop")
867 check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0,
868 3, 0, 0, 0, 'f', 'o', 'o', 0})
869
870
871
872 b = flatbuffers.NewBuilder(0)
873
874
875
876 uni_str := "\u65e5\u672c\u8a9e"
877 b.CreateString(uni_str)
878 check([]byte{9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0,
879 0, 0})
880
881
882
883 b = flatbuffers.NewBuilder(0)
884 b.CreateByteString([]byte("foo"))
885 check([]byte{3, 0, 0, 0, 'f', 'o', 'o', 0})
886 b.CreateByteString([]byte("moop"))
887 check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0,
888 3, 0, 0, 0, 'f', 'o', 'o', 0})
889
890
891 b = flatbuffers.NewBuilder(0)
892 b.StartObject(0)
893 check([]byte{})
894 b.EndObject()
895 check([]byte{4, 0, 4, 0, 4, 0, 0, 0})
896
897
898 b = flatbuffers.NewBuilder(0)
899 check([]byte{})
900 b.StartObject(1)
901 check([]byte{})
902 b.PrependBoolSlot(0, true, false)
903 b.EndObject()
904 check([]byte{
905 6, 0,
906 8, 0,
907 7, 0,
908 6, 0, 0, 0,
909 0, 0, 0,
910 1,
911 })
912
913
914 b = flatbuffers.NewBuilder(0)
915 check([]byte{})
916 b.StartObject(1)
917 check([]byte{})
918 b.PrependBoolSlot(0, false, false)
919 b.EndObject()
920 check([]byte{
921 4, 0,
922 4, 0,
923
924 4, 0, 0, 0,
925 })
926
927
928 b = flatbuffers.NewBuilder(0)
929 b.StartObject(1)
930 b.PrependInt16Slot(0, 0x789A, 0)
931 b.EndObject()
932 check([]byte{
933 6, 0,
934 8, 0,
935 6, 0,
936 6, 0, 0, 0,
937 0, 0,
938 0x9A, 0x78,
939 })
940
941
942 b = flatbuffers.NewBuilder(0)
943 b.StartObject(2)
944 b.PrependInt16Slot(0, 0x3456, 0)
945 b.PrependInt16Slot(1, 0x789A, 0)
946 b.EndObject()
947 check([]byte{
948 8, 0,
949 8, 0,
950 6, 0,
951 4, 0,
952 8, 0, 0, 0,
953 0x9A, 0x78,
954 0x56, 0x34,
955 })
956
957
958 b = flatbuffers.NewBuilder(0)
959 b.StartObject(2)
960 b.PrependInt16Slot(0, 0x3456, 0)
961 b.PrependBoolSlot(1, true, false)
962 b.EndObject()
963 check([]byte{
964 8, 0,
965 8, 0,
966 6, 0,
967 5, 0,
968 8, 0, 0, 0,
969 0,
970 1,
971 0x56, 0x34,
972 })
973
974
975 b = flatbuffers.NewBuilder(0)
976 b.StartVector(flatbuffers.SizeByte, 0, 1)
977 vecend := b.EndVector(0)
978 b.StartObject(1)
979 b.PrependUOffsetTSlot(0, vecend, 0)
980 b.EndObject()
981 check([]byte{
982 6, 0,
983 8, 0,
984 4, 0,
985 6, 0, 0, 0,
986 4, 0, 0, 0,
987 0, 0, 0, 0,
988 })
989
990
991 b = flatbuffers.NewBuilder(0)
992 b.StartVector(flatbuffers.SizeByte, 0, 1)
993 vecend = b.EndVector(0)
994 b.StartObject(2)
995 b.PrependInt16Slot(0, 55, 0)
996 b.PrependUOffsetTSlot(1, vecend, 0)
997 b.EndObject()
998 check([]byte{
999 8, 0,
1000 12, 0,
1001 10, 0,
1002 4, 0,
1003 8, 0, 0, 0,
1004 8, 0, 0, 0,
1005 0, 0, 55, 0,
1006
1007 0, 0, 0, 0,
1008 })
1009
1010
1011 b = flatbuffers.NewBuilder(0)
1012 b.StartVector(flatbuffers.SizeInt16, 2, 1)
1013 b.PrependInt16(0x1234)
1014 b.PrependInt16(0x5678)
1015 vecend = b.EndVector(2)
1016 b.StartObject(2)
1017 b.PrependUOffsetTSlot(1, vecend, 0)
1018 b.PrependInt16Slot(0, 55, 0)
1019 b.EndObject()
1020 check([]byte{
1021 8, 0,
1022 12, 0,
1023 6, 0,
1024 8, 0,
1025 8, 0, 0, 0,
1026 0, 0,
1027 55, 0,
1028 4, 0, 0, 0,
1029 2, 0, 0, 0,
1030 0x78, 0x56,
1031 0x34, 0x12,
1032 })
1033
1034
1035 b = flatbuffers.NewBuilder(0)
1036 b.StartObject(1)
1037 b.Prep(4+4+4, 0)
1038 b.PrependInt8(55)
1039 b.Pad(3)
1040 b.PrependInt16(0x1234)
1041 b.Pad(2)
1042 b.PrependInt32(0x12345678)
1043 structStart := b.Offset()
1044 b.PrependStructSlot(0, structStart, 0)
1045 b.EndObject()
1046 check([]byte{
1047 6, 0,
1048 16, 0,
1049 4, 0,
1050 6, 0, 0, 0,
1051 0x78, 0x56, 0x34, 0x12,
1052 0, 0,
1053 0x34, 0x12,
1054 0, 0, 0,
1055 55,
1056 })
1057
1058
1059 b = flatbuffers.NewBuilder(0)
1060 b.StartVector(flatbuffers.SizeInt8*2, 2, 1)
1061 b.PrependInt8(33)
1062 b.PrependInt8(44)
1063 b.PrependInt8(55)
1064 b.PrependInt8(66)
1065 vecend = b.EndVector(2)
1066 b.StartObject(1)
1067 b.PrependUOffsetTSlot(0, vecend, 0)
1068 b.EndObject()
1069 check([]byte{
1070 6, 0,
1071 8, 0,
1072 4, 0,
1073 6, 0, 0, 0,
1074 4, 0, 0, 0,
1075
1076 2, 0, 0, 0,
1077 66,
1078 55,
1079 44,
1080 33,
1081 })
1082
1083
1084 b = flatbuffers.NewBuilder(0)
1085 b.StartObject(2)
1086 b.PrependInt8Slot(0, 33, 0)
1087 b.PrependInt16Slot(1, 66, 0)
1088 off := b.EndObject()
1089 b.Finish(off)
1090
1091 check([]byte{
1092 12, 0, 0, 0,
1093
1094 8, 0,
1095 8, 0,
1096 7, 0,
1097 4, 0,
1098
1099 8, 0, 0, 0,
1100
1101 66, 0,
1102 0,
1103 33,
1104 })
1105
1106
1107 b = flatbuffers.NewBuilder(0)
1108 b.StartObject(2)
1109 b.PrependInt8Slot(0, 33, 0)
1110 b.PrependInt16Slot(1, 66, 0)
1111 off = b.EndObject()
1112 b.FinishSizePrefixed(off)
1113
1114 check([]byte{
1115 20, 0, 0, 0,
1116 12, 0, 0, 0,
1117
1118 8, 0,
1119 8, 0,
1120 7, 0,
1121 4, 0,
1122
1123 8, 0, 0, 0,
1124
1125 66, 0,
1126 0,
1127 33,
1128 })
1129
1130
1131 b = flatbuffers.NewBuilder(0)
1132 b.StartObject(2)
1133 b.PrependInt8Slot(0, 33, 0)
1134 b.PrependInt16Slot(1, 66, 0)
1135 off = b.EndObject()
1136 b.FinishWithFileIdentifier(off, []byte("TEST"))
1137
1138 check([]byte{
1139 16, 0, 0, 0,
1140 'T', 'E', 'S', 'T',
1141
1142 8, 0,
1143 8, 0,
1144 7, 0,
1145 4, 0,
1146
1147 8, 0, 0, 0,
1148
1149 66, 0,
1150 0,
1151 33,
1152 })
1153
1154
1155 b = flatbuffers.NewBuilder(0)
1156 b.StartObject(2)
1157 b.PrependInt8Slot(0, 33, 0)
1158 b.PrependInt16Slot(1, 66, 0)
1159 off = b.EndObject()
1160 b.FinishSizePrefixedWithFileIdentifier(off, []byte("TEST"))
1161
1162 check([]byte{
1163 24, 0, 0, 0,
1164 16, 0, 0, 0,
1165 'T', 'E', 'S', 'T',
1166
1167 8, 0,
1168 8, 0,
1169 7, 0,
1170 4, 0,
1171
1172 8, 0, 0, 0,
1173
1174 66, 0,
1175 0,
1176 33,
1177 })
1178
1179
1180 b = flatbuffers.NewBuilder(0)
1181 b.StartObject(2)
1182 b.PrependInt8Slot(0, 33, 0)
1183 b.PrependInt8Slot(1, 44, 0)
1184 off = b.EndObject()
1185 b.Finish(off)
1186
1187 b.StartObject(3)
1188 b.PrependInt8Slot(0, 55, 0)
1189 b.PrependInt8Slot(1, 66, 0)
1190 b.PrependInt8Slot(2, 77, 0)
1191 off = b.EndObject()
1192 b.Finish(off)
1193
1194 check([]byte{
1195 16, 0, 0, 0,
1196 0, 0,
1197
1198 10, 0,
1199 8, 0,
1200 7, 0,
1201 6, 0,
1202 5, 0,
1203 10, 0, 0, 0,
1204 0,
1205 77,
1206 66,
1207 55,
1208
1209 12, 0, 0, 0,
1210
1211 8, 0,
1212 8, 0,
1213 7, 0,
1214 6, 0,
1215 8, 0, 0, 0,
1216 0, 0,
1217 44,
1218 33,
1219 })
1220
1221
1222 b = flatbuffers.NewBuilder(0)
1223 b.StartObject(8)
1224 b.PrependBoolSlot(0, true, false)
1225 b.PrependBoolSlot(1, true, false)
1226 b.PrependBoolSlot(2, true, false)
1227 b.PrependBoolSlot(3, true, false)
1228 b.PrependBoolSlot(4, true, false)
1229 b.PrependBoolSlot(5, true, false)
1230 b.PrependBoolSlot(6, true, false)
1231 b.PrependBoolSlot(7, true, false)
1232 off = b.EndObject()
1233 b.Finish(off)
1234
1235 check([]byte{
1236 24, 0, 0, 0,
1237
1238 20, 0,
1239 12, 0,
1240 11, 0,
1241 10, 0,
1242 9, 0,
1243 8, 0,
1244 7, 0,
1245 6, 0,
1246 5, 0,
1247 4, 0,
1248 20, 0, 0, 0,
1249
1250 1,
1251 1,
1252 1,
1253 1,
1254 1,
1255 1,
1256 1,
1257 1,
1258 })
1259
1260
1261 b = flatbuffers.NewBuilder(0)
1262 b.StartObject(3)
1263 b.PrependBoolSlot(0, true, false)
1264 b.PrependBoolSlot(1, true, false)
1265 b.PrependBoolSlot(2, true, false)
1266 off = b.EndObject()
1267 b.Finish(off)
1268
1269 check([]byte{
1270 16, 0, 0, 0,
1271
1272 0, 0,
1273
1274 10, 0,
1275 8, 0,
1276 7, 0,
1277 6, 0,
1278 5, 0,
1279 10, 0, 0, 0,
1280
1281 0,
1282 1,
1283 1,
1284 1,
1285 })
1286
1287
1288 b = flatbuffers.NewBuilder(0)
1289 b.StartObject(1)
1290 b.PrependFloat32Slot(0, 1.0, 0.0)
1291 off = b.EndObject()
1292
1293 check([]byte{
1294 6, 0,
1295 8, 0,
1296 4, 0,
1297 6, 0, 0, 0,
1298
1299 0, 0, 128, 63,
1300 })
1301 }
1302
1303
1304 func CheckManualBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UOffsetT) {
1305 b := flatbuffers.NewBuilder(0)
1306 str := b.CreateString("MyMonster")
1307
1308 b.StartVector(1, 5, 1)
1309 b.PrependByte(4)
1310 b.PrependByte(3)
1311 b.PrependByte(2)
1312 b.PrependByte(1)
1313 b.PrependByte(0)
1314 inv := b.EndVector(5)
1315
1316 b.StartObject(13)
1317 b.PrependInt16Slot(2, 20, 100)
1318 mon2 := b.EndObject()
1319
1320
1321 b.StartVector(4, 2, 1)
1322
1323
1324 b.Prep(2, 4)
1325 b.Pad(1)
1326 b.PlaceInt8(20)
1327 b.PlaceInt16(10)
1328
1329
1330 b.Prep(2, 4)
1331 b.Pad(1)
1332 b.PlaceInt8(40)
1333 b.PlaceInt16(30)
1334
1335
1336 test4 := b.EndVector(2)
1337
1338 b.StartObject(13)
1339
1340
1341 b.Prep(16, 32)
1342 b.Pad(2)
1343 b.Prep(2, 4)
1344 b.Pad(1)
1345 b.PlaceByte(6)
1346 b.PlaceInt16(5)
1347 b.Pad(1)
1348 b.PlaceByte(4)
1349 b.PlaceFloat64(3.0)
1350 b.Pad(4)
1351 b.PlaceFloat32(3.0)
1352 b.PlaceFloat32(2.0)
1353 b.PlaceFloat32(1.0)
1354 vec3Loc := b.Offset()
1355
1356
1357 b.PrependStructSlot(0, vec3Loc, 0)
1358 b.PrependInt16Slot(2, 80, 100)
1359 b.PrependUOffsetTSlot(3, str, 0)
1360 b.PrependUOffsetTSlot(5, inv, 0)
1361 b.PrependByteSlot(7, 1, 0)
1362 b.PrependUOffsetTSlot(8, mon2, 0)
1363 b.PrependUOffsetTSlot(9, test4, 0)
1364 mon := b.EndObject()
1365
1366 b.Finish(mon)
1367
1368 return b.Bytes, b.Head()
1369 }
1370
1371 func CheckGetRootAsForNonRootTable(fail func(string, ...interface{})) {
1372 b := flatbuffers.NewBuilder(0)
1373 str := b.CreateString("MyStat")
1374 example.StatStart(b)
1375 example.StatAddId(b, str)
1376 example.StatAddVal(b, 12345678)
1377 example.StatAddCount(b, 12345)
1378 stat_end := example.StatEnd(b)
1379 b.Finish(stat_end)
1380
1381 stat := example.GetRootAsStat(b.Bytes, b.Head())
1382
1383 if got := stat.Id(); !bytes.Equal([]byte("MyStat"), got) {
1384 fail(FailString("stat.Id()", "MyStat", got))
1385 }
1386
1387 if got := stat.Val(); 12345678 != got {
1388 fail(FailString("stat.Val()", 12345678, got))
1389 }
1390
1391 if got := stat.Count(); 12345 != got {
1392 fail(FailString("stat.Count()", 12345, got))
1393 }
1394 }
1395
1396
1397 func CheckGeneratedBuild(sizePrefix, fileIdentifier bool, fail func(string, ...interface{})) ([]byte, flatbuffers.UOffsetT) {
1398 b := flatbuffers.NewBuilder(0)
1399 str := b.CreateString("MyMonster")
1400 test1 := b.CreateString("test1")
1401 test2 := b.CreateString("test2")
1402 fred := b.CreateString("Fred")
1403
1404 example.MonsterStartInventoryVector(b, 5)
1405 b.PrependByte(4)
1406 b.PrependByte(3)
1407 b.PrependByte(2)
1408 b.PrependByte(1)
1409 b.PrependByte(0)
1410 inv := b.EndVector(5)
1411
1412 example.MonsterStart(b)
1413 example.MonsterAddName(b, fred)
1414 mon2 := example.MonsterEnd(b)
1415
1416 example.MonsterStartTest4Vector(b, 2)
1417 example.CreateTest(b, 10, 20)
1418 example.CreateTest(b, 30, 40)
1419 test4 := b.EndVector(2)
1420
1421 example.MonsterStartTestarrayofstringVector(b, 2)
1422 b.PrependUOffsetT(test2)
1423 b.PrependUOffsetT(test1)
1424 testArrayOfString := b.EndVector(2)
1425
1426 example.MonsterStart(b)
1427
1428 pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
1429 example.MonsterAddPos(b, pos)
1430
1431 example.MonsterAddHp(b, 80)
1432 example.MonsterAddName(b, str)
1433 example.MonsterAddTestbool(b, true)
1434 example.MonsterAddInventory(b, inv)
1435 example.MonsterAddTestType(b, 1)
1436 example.MonsterAddTest(b, mon2)
1437 example.MonsterAddTest4(b, test4)
1438 example.MonsterAddTestarrayofstring(b, testArrayOfString)
1439 mon := example.MonsterEnd(b)
1440
1441 if fileIdentifier {
1442 if sizePrefix {
1443 example.FinishSizePrefixedMonsterBuffer(b, mon)
1444 } else {
1445 example.FinishMonsterBuffer(b, mon)
1446 }
1447 } else {
1448 if sizePrefix {
1449 b.FinishSizePrefixed(mon)
1450 } else {
1451 b.Finish(mon)
1452 }
1453 }
1454
1455 return b.Bytes, b.Head()
1456 }
1457
1458
1459 func CheckTableAccessors(fail func(string, ...interface{})) {
1460
1461 b := flatbuffers.NewBuilder(0)
1462 pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 4, 5, 6)
1463 b.Finish(pos)
1464 vec3Bytes := b.FinishedBytes()
1465 vec3 := &example.Vec3{}
1466 flatbuffers.GetRootAs(vec3Bytes, 0, vec3)
1467
1468 if bytes.Compare(vec3Bytes, vec3.Table().Bytes) != 0 {
1469 fail("invalid vec3 table")
1470 }
1471
1472
1473 b = flatbuffers.NewBuilder(0)
1474 str := b.CreateString("MyStat")
1475 example.StatStart(b)
1476 example.StatAddId(b, str)
1477 example.StatAddVal(b, 12345678)
1478 example.StatAddCount(b, 12345)
1479 pos = example.StatEnd(b)
1480 b.Finish(pos)
1481 statBytes := b.FinishedBytes()
1482 stat := &example.Stat{}
1483 flatbuffers.GetRootAs(statBytes, 0, stat)
1484
1485 if bytes.Compare(statBytes, stat.Table().Bytes) != 0 {
1486 fail("invalid stat table")
1487 }
1488 }
1489
1490
1491 func CheckVtableDeduplication(fail func(string, ...interface{})) {
1492 b := flatbuffers.NewBuilder(0)
1493
1494 b.StartObject(4)
1495 b.PrependByteSlot(0, 0, 0)
1496 b.PrependByteSlot(1, 11, 0)
1497 b.PrependByteSlot(2, 22, 0)
1498 b.PrependInt16Slot(3, 33, 0)
1499 obj0 := b.EndObject()
1500
1501 b.StartObject(4)
1502 b.PrependByteSlot(0, 0, 0)
1503 b.PrependByteSlot(1, 44, 0)
1504 b.PrependByteSlot(2, 55, 0)
1505 b.PrependInt16Slot(3, 66, 0)
1506 obj1 := b.EndObject()
1507
1508 b.StartObject(4)
1509 b.PrependByteSlot(0, 0, 0)
1510 b.PrependByteSlot(1, 77, 0)
1511 b.PrependByteSlot(2, 88, 0)
1512 b.PrependInt16Slot(3, 99, 0)
1513 obj2 := b.EndObject()
1514
1515 got := b.Bytes[b.Head():]
1516
1517 want := []byte{
1518 240, 255, 255, 255,
1519 99, 0,
1520 88,
1521 77,
1522 248, 255, 255, 255,
1523 66, 0,
1524 55,
1525 44,
1526 12, 0,
1527 8, 0,
1528 0, 0,
1529 7, 0,
1530 6, 0,
1531 4, 0,
1532 12, 0, 0, 0,
1533 33, 0,
1534 22,
1535 11,
1536 }
1537
1538 if !bytes.Equal(want, got) {
1539 fail("testVtableDeduplication want:\n%d %v\nbut got:\n%d %v\n",
1540 len(want), want, len(got), got)
1541 }
1542
1543 table0 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj0}
1544 table1 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj1}
1545 table2 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj2}
1546
1547 testTable := func(tab *flatbuffers.Table, a flatbuffers.VOffsetT, b, c, d byte) {
1548
1549 if got := tab.GetVOffsetTSlot(0, 0); 12 != got {
1550 fail("failed 0, 0: %d", got)
1551 }
1552
1553 if got := tab.GetVOffsetTSlot(2, 0); 8 != got {
1554 fail("failed 2, 0: %d", got)
1555 }
1556
1557 if got := tab.GetVOffsetTSlot(4, 0); a != got {
1558 fail("failed 4, 0: %d", got)
1559 }
1560 if got := tab.GetByteSlot(6, 0); b != got {
1561 fail("failed 6, 0: %d", got)
1562 }
1563 if val := tab.GetByteSlot(8, 0); c != val {
1564 fail("failed 8, 0: %d", got)
1565 }
1566 if got := tab.GetByteSlot(10, 0); d != got {
1567 fail("failed 10, 0: %d", got)
1568 }
1569 }
1570
1571 testTable(table0, 0, 11, 22, 33)
1572 testTable(table1, 0, 44, 55, 66)
1573 testTable(table2, 0, 77, 88, 99)
1574 }
1575
1576
1577
1578 func CheckNotInObjectError(fail func(string, ...interface{})) {
1579 b := flatbuffers.NewBuilder(0)
1580
1581 defer func() {
1582 r := recover()
1583 if r == nil {
1584 fail("expected panic in CheckNotInObjectError")
1585 }
1586 }()
1587 b.EndObject()
1588 }
1589
1590
1591
1592 func CheckStringIsNestedError(fail func(string, ...interface{})) {
1593 b := flatbuffers.NewBuilder(0)
1594 b.StartObject(0)
1595 defer func() {
1596 r := recover()
1597 if r == nil {
1598 fail("expected panic in CheckStringIsNestedError")
1599 }
1600 }()
1601 b.CreateString("foo")
1602 }
1603
1604 func CheckEmptiedBuilder(fail func(string, ...interface{})) {
1605 f := func(a, b string) bool {
1606 if a == b {
1607 return true
1608 }
1609
1610 builder := flatbuffers.NewBuilder(0)
1611
1612 a1 := builder.CreateSharedString(a)
1613 b1 := builder.CreateSharedString(b)
1614 builder.Reset()
1615 b2 := builder.CreateSharedString(b)
1616 a2 := builder.CreateSharedString(a)
1617
1618 return !(a1 == a2 || b1 == b2)
1619 }
1620 if err := quick.Check(f, nil); err != nil {
1621 fail("expected different offset")
1622 }
1623 }
1624
1625 func CheckSharedStrings(fail func(string, ...interface{})) {
1626 f := func(strings []string) bool {
1627 b := flatbuffers.NewBuilder(0)
1628 for _, s1 := range strings {
1629 for _, s2 := range strings {
1630 off1 := b.CreateSharedString(s1)
1631 off2 := b.CreateSharedString(s2)
1632
1633 if (s1 == s2) && (off1 != off2) {
1634 return false
1635 }
1636 if (s1 != s2) && (off1 == off2) {
1637 return false
1638 }
1639 }
1640 }
1641 return true
1642 }
1643 if err := quick.Check(f, nil); err != nil {
1644 fail("expected same offset")
1645 }
1646 }
1647
1648
1649
1650 func CheckByteStringIsNestedError(fail func(string, ...interface{})) {
1651 b := flatbuffers.NewBuilder(0)
1652 b.StartObject(0)
1653 defer func() {
1654 r := recover()
1655 if r == nil {
1656 fail("expected panic in CheckByteStringIsNestedError")
1657 }
1658 }()
1659 b.CreateByteString([]byte("foo"))
1660 }
1661
1662
1663
1664 func CheckStructIsNotInlineError(fail func(string, ...interface{})) {
1665 b := flatbuffers.NewBuilder(0)
1666 b.StartObject(0)
1667 defer func() {
1668 r := recover()
1669 if r == nil {
1670 fail("expected panic in CheckStructIsNotInlineError")
1671 }
1672 }()
1673 b.PrependStructSlot(0, 1, 0)
1674 }
1675
1676
1677
1678 func CheckFinishedBytesError(fail func(string, ...interface{})) {
1679 b := flatbuffers.NewBuilder(0)
1680
1681 defer func() {
1682 r := recover()
1683 if r == nil {
1684 fail("expected panic in CheckFinishedBytesError")
1685 }
1686 }()
1687 b.FinishedBytes()
1688 }
1689
1690
1691 func CheckEnumNames(fail func(string, ...interface{})) {
1692 {
1693 want := map[example.Any]string{
1694 example.AnyNONE: "NONE",
1695 example.AnyMonster: "Monster",
1696 example.AnyTestSimpleTableWithEnum: "TestSimpleTableWithEnum",
1697 example.AnyMyGame_Example2_Monster: "MyGame_Example2_Monster",
1698 }
1699 got := example.EnumNamesAny
1700 if !reflect.DeepEqual(got, want) {
1701 fail("enum name is not equal")
1702 }
1703 }
1704 {
1705 want := map[example.Color]string{
1706 example.ColorRed: "Red",
1707 example.ColorGreen: "Green",
1708 example.ColorBlue: "Blue",
1709 }
1710 got := example.EnumNamesColor
1711 if !reflect.DeepEqual(got, want) {
1712 fail("enum name is not equal")
1713 }
1714 }
1715 }
1716
1717
1718 func CheckEnumString(fail func(string, ...interface{})) {
1719 if got := example.AnyMonster.String(); got != "Monster" {
1720 fail("Monster.String: %q != %q", got, "Monster")
1721 }
1722 if got := fmt.Sprintf("color: %s", example.ColorGreen); got != "color: Green" {
1723 fail("color.String: %q != %q", got, "color: Green")
1724 }
1725 }
1726
1727
1728 func CheckEnumValues(fail func(string, ...interface{})) {
1729 {
1730 want := map[string]example.Any{
1731 "NONE": example.AnyNONE,
1732 "Monster": example.AnyMonster,
1733 "TestSimpleTableWithEnum": example.AnyTestSimpleTableWithEnum,
1734 "MyGame_Example2_Monster": example.AnyMyGame_Example2_Monster,
1735 }
1736 got := example.EnumValuesAny
1737 if !reflect.DeepEqual(got, want) {
1738 fail("enum name is not equal")
1739 }
1740 }
1741 {
1742 want := map[string]example.Color{
1743 "Red": example.ColorRed,
1744 "Green": example.ColorGreen,
1745 "Blue": example.ColorBlue,
1746 }
1747 got := example.EnumValuesColor
1748 if !reflect.DeepEqual(got, want) {
1749 fail("enum name is not equal")
1750 }
1751 }
1752 }
1753
1754
1755
1756 func CheckDocExample(buf []byte, off flatbuffers.UOffsetT, fail func(string, ...interface{})) {
1757 monster := example.GetRootAsMonster(buf, off)
1758 _ = monster.Hp()
1759 _ = monster.Pos(nil)
1760 for i := 0; i < monster.InventoryLength(); i++ {
1761 _ = monster.Inventory(i)
1762 }
1763
1764 builder := flatbuffers.NewBuilder(0)
1765
1766 example.MonsterStartInventoryVector(builder, 5)
1767 for i := 4; i >= 0; i-- {
1768 builder.PrependByte(byte(i))
1769 }
1770 inv := builder.EndVector(5)
1771
1772 str := builder.CreateString("MyMonster")
1773 example.MonsterStart(builder)
1774 example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, example.Color(4), 5, 6))
1775 example.MonsterAddHp(builder, 80)
1776 example.MonsterAddName(builder, str)
1777 example.MonsterAddInventory(builder, inv)
1778 example.MonsterAddTestType(builder, 1)
1779 example.MonsterAddColor(builder, example.ColorRed)
1780
1781
1782 _ = example.MonsterEnd(builder)
1783 }
1784
1785 func CheckCreateByteVector(fail func(string, ...interface{})) {
1786 raw := [30]byte{}
1787 for i := 0; i < len(raw); i++ {
1788 raw[i] = byte(i)
1789 }
1790
1791 for size := 0; size < len(raw); size++ {
1792 b1 := flatbuffers.NewBuilder(0)
1793 b2 := flatbuffers.NewBuilder(0)
1794 b1.StartVector(1, size, 1)
1795 for i := size - 1; i >= 0; i-- {
1796 b1.PrependByte(raw[i])
1797 }
1798 b1.EndVector(size)
1799 b2.CreateByteVector(raw[:size])
1800 CheckByteEquality(b1.Bytes, b2.Bytes, fail)
1801 }
1802 }
1803
1804 func CheckParentNamespace(fail func(string, ...interface{})) {
1805 var empty, nonempty []byte
1806
1807
1808 {
1809 builder := flatbuffers.NewBuilder(0)
1810
1811 example.MonsterStart(builder)
1812 m := example.MonsterEnd(builder)
1813 builder.Finish(m)
1814
1815 empty = make([]byte, len(builder.FinishedBytes()))
1816 copy(empty, builder.FinishedBytes())
1817 }
1818
1819
1820 {
1821 builder := flatbuffers.NewBuilder(0)
1822 mygame.InParentNamespaceStart(builder)
1823 pn := mygame.InParentNamespaceEnd(builder)
1824
1825 example.MonsterStart(builder)
1826 example.MonsterAddParentNamespaceTest(builder, pn)
1827 m := example.MonsterEnd(builder)
1828
1829 builder.Finish(m)
1830
1831 nonempty = make([]byte, len(builder.FinishedBytes()))
1832 copy(nonempty, builder.FinishedBytes())
1833 }
1834
1835
1836 {
1837 m := example.GetRootAsMonster(empty, 0)
1838 if m.ParentNamespaceTest(nil) != nil {
1839 fail("expected nil ParentNamespaceTest for empty field")
1840 }
1841 }
1842
1843
1844 {
1845 m := example.GetRootAsMonster(nonempty, 0)
1846 if m.ParentNamespaceTest(nil) == nil {
1847 fail("expected non-nil ParentNamespaceTest for non-empty field")
1848 }
1849 }
1850 }
1851
1852 func CheckSizePrefixedBuffer(fail func(string, ...interface{})) {
1853
1854 generated, off := CheckGeneratedBuild(true, false, fail)
1855
1856
1857 CheckReadBuffer(generated, off, true, fail)
1858 CheckMutateBuffer(generated, off, true, fail)
1859 CheckObjectAPI(generated, off, true, fail)
1860
1861
1862 generated, off = CheckGeneratedBuild(true, true, fail)
1863
1864
1865
1866 size := flatbuffers.GetSizePrefix(generated, off)
1867 expectedSize := uint32(228)
1868 if size != expectedSize {
1869 fail("mismatch between size prefix (%d) and expected size (%d)", size, expectedSize)
1870 }
1871
1872
1873 CheckReadBuffer(generated, off, true, fail)
1874 CheckMutateBuffer(generated, off, true, fail)
1875 CheckObjectAPI(generated, off, true, fail)
1876 CheckFileIdentifier(generated, off, true, fail)
1877
1878
1879 if err := os.WriteFile(outData+".sp", generated[off:], os.FileMode(0644)); err != nil {
1880 fail("failed to write file: %s", err)
1881 }
1882 }
1883
1884
1885
1886
1887 type LCG uint32
1888
1889 const InitialLCGSeed = 48271
1890
1891 func NewLCG() *LCG {
1892 n := uint32(InitialLCGSeed)
1893 l := LCG(n)
1894 return &l
1895 }
1896
1897 func (lcg *LCG) Reset() {
1898 *lcg = InitialLCGSeed
1899 }
1900
1901 func (lcg *LCG) Next() uint32 {
1902 n := uint32((uint64(*lcg) * uint64(279470273)) % uint64(4294967291))
1903 *lcg = LCG(n)
1904 return n
1905 }
1906
1907
1908 func CheckByteEquality(a, b []byte, fail func(string, ...interface{})) {
1909 if !bytes.Equal(a, b) {
1910 fail("objects are not byte-wise equal")
1911 }
1912 }
1913
1914
1915 func CheckMutateMethods(fail func(string, ...interface{})) {
1916 b := flatbuffers.NewBuilder(0)
1917 b.StartObject(15)
1918 b.PrependBoolSlot(0, true, false)
1919 b.PrependByteSlot(1, 1, 0)
1920 b.PrependUint8Slot(2, 2, 0)
1921 b.PrependUint16Slot(3, 3, 0)
1922 b.PrependUint32Slot(4, 4, 0)
1923 b.PrependUint64Slot(5, 5, 0)
1924 b.PrependInt8Slot(6, 6, 0)
1925 b.PrependInt16Slot(7, 7, 0)
1926 b.PrependInt32Slot(8, 8, 0)
1927 b.PrependInt64Slot(9, 9, 0)
1928 b.PrependFloat32Slot(10, 10, 0)
1929 b.PrependFloat64Slot(11, 11, 0)
1930
1931 b.PrependUOffsetTSlot(12, 12, 0)
1932 uoVal := b.Offset() - 12
1933
1934 b.PrependVOffsetT(13)
1935 b.Slot(13)
1936
1937 b.PrependSOffsetT(14)
1938 b.Slot(14)
1939 soVal := flatbuffers.SOffsetT(b.Offset() - 14)
1940
1941 offset := b.EndObject()
1942
1943 t := &flatbuffers.Table{
1944 Bytes: b.Bytes,
1945 Pos: flatbuffers.UOffsetT(len(b.Bytes)) - offset,
1946 }
1947
1948 calcVOffsetT := func(slot int) (vtableOffset flatbuffers.VOffsetT) {
1949 return flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + slot) * flatbuffers.SizeVOffsetT)
1950 }
1951 calcUOffsetT := func(vtableOffset flatbuffers.VOffsetT) (valueOffset flatbuffers.UOffsetT) {
1952 return t.Pos + flatbuffers.UOffsetT(t.Offset(vtableOffset))
1953 }
1954
1955 type testcase struct {
1956 field string
1957 testfn func() bool
1958 }
1959
1960 testForOriginalValues := []testcase{
1961 testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == true }},
1962 testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 1 }},
1963 testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 2) == 2 }},
1964 testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 3) == 3 }},
1965 testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 4) == 4 }},
1966 testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 5) == 5 }},
1967 testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 6) == 6 }},
1968 testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 7) == 7 }},
1969 testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 8) == 8 }},
1970 testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 9) == 9 }},
1971 testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 10) == 10 }},
1972 testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 11) == 11 }},
1973 testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == uoVal }},
1974 testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 13 }},
1975 testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == soVal }},
1976 }
1977
1978 testMutability := []testcase{
1979 testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(0), false) }},
1980 testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(1), 2) }},
1981 testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(2), 4) }},
1982 testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(3), 6) }},
1983 testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(4), 8) }},
1984 testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(5), 10) }},
1985 testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(6), 12) }},
1986 testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(7), 14) }},
1987 testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(8), 16) }},
1988 testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(9), 18) }},
1989 testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(10), 20) }},
1990 testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(11), 22) }},
1991 testcase{"UOffsetTSlot", func() bool { return t.MutateUOffsetT(calcUOffsetT(calcVOffsetT(12)), 24) }},
1992 testcase{"VOffsetTSlot", func() bool { return t.MutateVOffsetT(calcUOffsetT(calcVOffsetT(13)), 26) }},
1993 testcase{"SOffsetTSlot", func() bool { return t.MutateSOffsetT(calcUOffsetT(calcVOffsetT(14)), 28) }},
1994 }
1995
1996 testMutabilityWithoutSlot := []testcase{
1997 testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(16), false) }},
1998 testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(16), 2) }},
1999 testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(16), 2) }},
2000 testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(16), 2) }},
2001 testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(16), 2) }},
2002 testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(16), 2) }},
2003 testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(16), 2) }},
2004 testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(16), 2) }},
2005 testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(16), 2) }},
2006 testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(16), 2) }},
2007 testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(16), 2) }},
2008 testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(16), 2) }},
2009 }
2010
2011 testForMutatedValues := []testcase{
2012 testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == false }},
2013 testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 2 }},
2014 testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 1) == 4 }},
2015 testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 1) == 6 }},
2016 testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 1) == 8 }},
2017 testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 1) == 10 }},
2018 testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 1) == 12 }},
2019 testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 1) == 14 }},
2020 testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 1) == 16 }},
2021 testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 1) == 18 }},
2022 testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 1) == 20 }},
2023 testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 1) == 22 }},
2024 testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == 24 }},
2025 testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 26 }},
2026 testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == 28 }},
2027 }
2028
2029
2030 for _, t := range testForOriginalValues {
2031 if !t.testfn() {
2032 fail(t.field + "' field doesn't have the expected original value")
2033 }
2034 }
2035
2036
2037 for _, t := range testMutability {
2038 if !t.testfn() {
2039 fail(FailString(t.field+"' field failed mutability test", "passed", "failed"))
2040 }
2041 }
2042
2043
2044
2045 for _, t := range testMutabilityWithoutSlot {
2046 if t.testfn() {
2047 fail(FailString(t.field+"' field failed no slot mutability test", "failed", "passed"))
2048 }
2049 }
2050
2051
2052 for _, t := range testForMutatedValues {
2053 if !t.testfn() {
2054 fail(t.field + "' field doesn't have the expected mutated value")
2055 }
2056 }
2057 }
2058
2059
2060 func CheckOptionalScalars(fail func(string, ...interface{})) {
2061 type testCase struct {
2062 what string
2063 result, expect interface{}
2064 }
2065
2066 makeDefaultTestCases := func(s *optional_scalars.ScalarStuff) []testCase {
2067 return []testCase{
2068 {"justI8", s.JustI8(), int8(0)},
2069 {"maybeI8", s.MaybeI8(), (*int8)(nil)},
2070 {"defaultI8", s.DefaultI8(), int8(42)},
2071 {"justU8", s.JustU8(), byte(0)},
2072 {"maybeU8", s.MaybeU8(), (*byte)(nil)},
2073 {"defaultU8", s.DefaultU8(), byte(42)},
2074 {"justI16", s.JustI16(), int16(0)},
2075 {"maybeI16", s.MaybeI16(), (*int16)(nil)},
2076 {"defaultI16", s.DefaultI16(), int16(42)},
2077 {"justU16", s.JustU16(), uint16(0)},
2078 {"maybeU16", s.MaybeU16(), (*uint16)(nil)},
2079 {"defaultU16", s.DefaultU16(), uint16(42)},
2080 {"justI32", s.JustI32(), int32(0)},
2081 {"maybeI32", s.MaybeI32(), (*int32)(nil)},
2082 {"defaultI32", s.DefaultI32(), int32(42)},
2083 {"justU32", s.JustU32(), uint32(0)},
2084 {"maybeU32", s.MaybeU32(), (*uint32)(nil)},
2085 {"defaultU32", s.DefaultU32(), uint32(42)},
2086 {"justI64", s.JustI64(), int64(0)},
2087 {"maybeI64", s.MaybeI64(), (*int64)(nil)},
2088 {"defaultI64", s.DefaultI64(), int64(42)},
2089 {"justU64", s.JustU64(), uint64(0)},
2090 {"maybeU64", s.MaybeU64(), (*uint64)(nil)},
2091 {"defaultU64", s.DefaultU64(), uint64(42)},
2092 {"justF32", s.JustF32(), float32(0)},
2093 {"maybeF32", s.MaybeF32(), (*float32)(nil)},
2094 {"defaultF32", s.DefaultF32(), float32(42)},
2095 {"justF64", s.JustF64(), float64(0)},
2096 {"maybeF64", s.MaybeF64(), (*float64)(nil)},
2097 {"defaultF64", s.DefaultF64(), float64(42)},
2098 {"justBool", s.JustBool(), false},
2099 {"maybeBool", s.MaybeBool(), (*bool)(nil)},
2100 {"defaultBool", s.DefaultBool(), true},
2101 {"justEnum", s.JustEnum(), optional_scalars.OptionalByte(0)},
2102 {"maybeEnum", s.MaybeEnum(), (*optional_scalars.OptionalByte)(nil)},
2103 {"defaultEnum", s.DefaultEnum(), optional_scalars.OptionalByteOne},
2104 }
2105 }
2106
2107 makeAssignedTestCases := func(s *optional_scalars.ScalarStuff) []testCase {
2108 return []testCase{
2109 {"justI8", s.JustI8(), int8(5)},
2110 {"maybeI8", s.MaybeI8(), int8(5)},
2111 {"defaultI8", s.DefaultI8(), int8(5)},
2112 {"justU8", s.JustU8(), byte(6)},
2113 {"maybeU8", s.MaybeU8(), byte(6)},
2114 {"defaultU8", s.DefaultU8(), byte(6)},
2115 {"justI16", s.JustI16(), int16(7)},
2116 {"maybeI16", s.MaybeI16(), int16(7)},
2117 {"defaultI16", s.DefaultI16(), int16(7)},
2118 {"justU16", s.JustU16(), uint16(8)},
2119 {"maybeU16", s.MaybeU16(), uint16(8)},
2120 {"defaultU16", s.DefaultU16(), uint16(8)},
2121 {"justI32", s.JustI32(), int32(9)},
2122 {"maybeI32", s.MaybeI32(), int32(9)},
2123 {"defaultI32", s.DefaultI32(), int32(9)},
2124 {"justU32", s.JustU32(), uint32(10)},
2125 {"maybeU32", s.MaybeU32(), uint32(10)},
2126 {"defaultU32", s.DefaultU32(), uint32(10)},
2127 {"justI64", s.JustI64(), int64(11)},
2128 {"maybeI64", s.MaybeI64(), int64(11)},
2129 {"defaultI64", s.DefaultI64(), int64(11)},
2130 {"justU64", s.JustU64(), uint64(12)},
2131 {"maybeU64", s.MaybeU64(), uint64(12)},
2132 {"defaultU64", s.DefaultU64(), uint64(12)},
2133 {"justF32", s.JustF32(), float32(13)},
2134 {"maybeF32", s.MaybeF32(), float32(13)},
2135 {"defaultF32", s.DefaultF32(), float32(13)},
2136 {"justF64", s.JustF64(), float64(14)},
2137 {"maybeF64", s.MaybeF64(), float64(14)},
2138 {"defaultF64", s.DefaultF64(), float64(14)},
2139 {"justBool", s.JustBool(), true},
2140 {"maybeBool", s.MaybeBool(), true},
2141 {"defaultBool", s.DefaultBool(), false},
2142 {"justEnum", s.JustEnum(), optional_scalars.OptionalByteTwo},
2143 {"maybeEnum", s.MaybeEnum(), optional_scalars.OptionalByteTwo},
2144 {"defaultEnum", s.DefaultEnum(), optional_scalars.OptionalByteTwo},
2145 }
2146 }
2147
2148 resolvePointer := func(v interface{}) interface{} {
2149 switch v := v.(type) {
2150 case *int8:
2151 return *v
2152 case *byte:
2153 return *v
2154 case *int16:
2155 return *v
2156 case *uint16:
2157 return *v
2158 case *int32:
2159 return *v
2160 case *uint32:
2161 return *v
2162 case *int64:
2163 return *v
2164 case *uint64:
2165 return *v
2166 case *float32:
2167 return *v
2168 case *float64:
2169 return *v
2170 case *bool:
2171 return *v
2172 case *optional_scalars.OptionalByte:
2173 return *v
2174 default:
2175 return v
2176 }
2177 }
2178
2179 buildAssignedTable := func(b *flatbuffers.Builder) *optional_scalars.ScalarStuff {
2180 optional_scalars.ScalarStuffStart(b)
2181 optional_scalars.ScalarStuffAddJustI8(b, int8(5))
2182 optional_scalars.ScalarStuffAddMaybeI8(b, int8(5))
2183 optional_scalars.ScalarStuffAddDefaultI8(b, int8(5))
2184 optional_scalars.ScalarStuffAddJustU8(b, byte(6))
2185 optional_scalars.ScalarStuffAddMaybeU8(b, byte(6))
2186 optional_scalars.ScalarStuffAddDefaultU8(b, byte(6))
2187 optional_scalars.ScalarStuffAddJustI16(b, int16(7))
2188 optional_scalars.ScalarStuffAddMaybeI16(b, int16(7))
2189 optional_scalars.ScalarStuffAddDefaultI16(b, int16(7))
2190 optional_scalars.ScalarStuffAddJustU16(b, uint16(8))
2191 optional_scalars.ScalarStuffAddMaybeU16(b, uint16(8))
2192 optional_scalars.ScalarStuffAddDefaultU16(b, uint16(8))
2193 optional_scalars.ScalarStuffAddJustI32(b, int32(9))
2194 optional_scalars.ScalarStuffAddMaybeI32(b, int32(9))
2195 optional_scalars.ScalarStuffAddDefaultI32(b, int32(9))
2196 optional_scalars.ScalarStuffAddJustU32(b, uint32(10))
2197 optional_scalars.ScalarStuffAddMaybeU32(b, uint32(10))
2198 optional_scalars.ScalarStuffAddDefaultU32(b, uint32(10))
2199 optional_scalars.ScalarStuffAddJustI64(b, int64(11))
2200 optional_scalars.ScalarStuffAddMaybeI64(b, int64(11))
2201 optional_scalars.ScalarStuffAddDefaultI64(b, int64(11))
2202 optional_scalars.ScalarStuffAddJustU64(b, uint64(12))
2203 optional_scalars.ScalarStuffAddMaybeU64(b, uint64(12))
2204 optional_scalars.ScalarStuffAddDefaultU64(b, uint64(12))
2205 optional_scalars.ScalarStuffAddJustF32(b, float32(13))
2206 optional_scalars.ScalarStuffAddMaybeF32(b, float32(13))
2207 optional_scalars.ScalarStuffAddDefaultF32(b, float32(13))
2208 optional_scalars.ScalarStuffAddJustF64(b, float64(14))
2209 optional_scalars.ScalarStuffAddMaybeF64(b, float64(14))
2210 optional_scalars.ScalarStuffAddDefaultF64(b, float64(14))
2211 optional_scalars.ScalarStuffAddJustBool(b, true)
2212 optional_scalars.ScalarStuffAddMaybeBool(b, true)
2213 optional_scalars.ScalarStuffAddDefaultBool(b, false)
2214 optional_scalars.ScalarStuffAddJustEnum(b, optional_scalars.OptionalByteTwo)
2215 optional_scalars.ScalarStuffAddMaybeEnum(b, optional_scalars.OptionalByteTwo)
2216 optional_scalars.ScalarStuffAddDefaultEnum(b, optional_scalars.OptionalByteTwo)
2217 b.Finish(optional_scalars.ScalarStuffEnd(b))
2218 return optional_scalars.GetRootAsScalarStuff(b.FinishedBytes(), 0)
2219 }
2220
2221
2222
2223 fbb := flatbuffers.NewBuilder(1)
2224 optional_scalars.ScalarStuffStart(fbb)
2225 fbb.Finish(optional_scalars.ScalarStuffEnd(fbb))
2226 ss := optional_scalars.GetRootAsScalarStuff(fbb.FinishedBytes(), 0)
2227 for _, tc := range makeDefaultTestCases(ss) {
2228 if tc.result != tc.expect {
2229 fail(FailString("Default ScalarStuff: "+tc.what, tc.expect, tc.result))
2230 }
2231 }
2232
2233
2234 fbb.Reset()
2235 ss = buildAssignedTable(fbb)
2236 for _, tc := range makeAssignedTestCases(ss) {
2237 if resolvePointer(tc.result) != tc.expect {
2238 fail(FailString("Assigned ScalarStuff: "+tc.what, tc.expect, tc.result))
2239 }
2240 }
2241
2242
2243 fbb.Reset()
2244 i8 := int8(5)
2245 u8 := byte(6)
2246 i16 := int16(7)
2247 u16 := uint16(8)
2248 i32 := int32(9)
2249 u32 := uint32(10)
2250 i64 := int64(11)
2251 u64 := uint64(12)
2252 f32 := float32(13)
2253 f64 := float64(14)
2254 b := true
2255 enum := optional_scalars.OptionalByteTwo
2256 obj := optional_scalars.ScalarStuffT{
2257 JustI8: 5,
2258 MaybeI8: &i8,
2259 DefaultI8: 5,
2260 JustU8: 6,
2261 MaybeU8: &u8,
2262 DefaultU8: 6,
2263 JustI16: 7,
2264 MaybeI16: &i16,
2265 DefaultI16: 7,
2266 JustU16: 8,
2267 MaybeU16: &u16,
2268 DefaultU16: 8,
2269 JustI32: 9,
2270 MaybeI32: &i32,
2271 DefaultI32: 9,
2272 JustU32: 10,
2273 MaybeU32: &u32,
2274 DefaultU32: 10,
2275 JustI64: 11,
2276 MaybeI64: &i64,
2277 DefaultI64: 11,
2278 JustU64: 12,
2279 MaybeU64: &u64,
2280 DefaultU64: 12,
2281 JustF32: 13,
2282 MaybeF32: &f32,
2283 DefaultF32: 13,
2284 JustF64: 14,
2285 MaybeF64: &f64,
2286 DefaultF64: 14,
2287 JustBool: true,
2288 MaybeBool: &b,
2289 DefaultBool: false,
2290 JustEnum: optional_scalars.OptionalByteTwo,
2291 MaybeEnum: &enum,
2292 DefaultEnum: optional_scalars.OptionalByteTwo,
2293 }
2294 fbb.Finish(obj.Pack(fbb))
2295 ss = optional_scalars.GetRootAsScalarStuff(fbb.FinishedBytes(), 0)
2296 for _, tc := range makeAssignedTestCases(ss) {
2297 if resolvePointer(tc.result) != tc.expect {
2298 fail(FailString("Native Object ScalarStuff: "+tc.what, tc.expect, tc.result))
2299 }
2300 }
2301
2302
2303 fbb.Reset()
2304 ss = buildAssignedTable(fbb)
2305 ss.UnPackTo(&obj)
2306 expectEq := func(what string, a, b interface{}) {
2307 if resolvePointer(a) != b {
2308 fail(FailString("Native Object Unpack ScalarStuff: "+what, b, a))
2309 }
2310 }
2311 expectEq("justI8", obj.JustI8, int8(5))
2312 expectEq("maybeI8", obj.MaybeI8, int8(5))
2313 expectEq("defaultI8", obj.DefaultI8, int8(5))
2314 expectEq("justU8", obj.JustU8, byte(6))
2315 expectEq("maybeU8", obj.MaybeU8, byte(6))
2316 expectEq("defaultU8", obj.DefaultU8, byte(6))
2317 expectEq("justI16", obj.JustI16, int16(7))
2318 expectEq("maybeI16", obj.MaybeI16, int16(7))
2319 expectEq("defaultI16", obj.DefaultI16, int16(7))
2320 expectEq("justU16", obj.JustU16, uint16(8))
2321 expectEq("maybeU16", obj.MaybeU16, uint16(8))
2322 expectEq("defaultU16", obj.DefaultU16, uint16(8))
2323 expectEq("justI32", obj.JustI32, int32(9))
2324 expectEq("maybeI32", obj.MaybeI32, int32(9))
2325 expectEq("defaultI32", obj.DefaultI32, int32(9))
2326 expectEq("justU32", obj.JustU32, uint32(10))
2327 expectEq("maybeU32", obj.MaybeU32, uint32(10))
2328 expectEq("defaultU32", obj.DefaultU32, uint32(10))
2329 expectEq("justI64", obj.JustI64, int64(11))
2330 expectEq("maybeI64", obj.MaybeI64, int64(11))
2331 expectEq("defaultI64", obj.DefaultI64, int64(11))
2332 expectEq("justU64", obj.JustU64, uint64(12))
2333 expectEq("maybeU64", obj.MaybeU64, uint64(12))
2334 expectEq("defaultU64", obj.DefaultU64, uint64(12))
2335 expectEq("justF32", obj.JustF32, float32(13))
2336 expectEq("maybeF32", obj.MaybeF32, float32(13))
2337 expectEq("defaultF32", obj.DefaultF32, float32(13))
2338 expectEq("justF64", obj.JustF64, float64(14))
2339 expectEq("maybeF64", obj.MaybeF64, float64(14))
2340 expectEq("defaultF64", obj.DefaultF64, float64(14))
2341 expectEq("justBool", obj.JustBool, true)
2342 expectEq("maybeBool", obj.MaybeBool, true)
2343 expectEq("defaultBool", obj.DefaultBool, false)
2344 expectEq("justEnum", obj.JustEnum, optional_scalars.OptionalByteTwo)
2345 expectEq("maybeEnum", obj.MaybeEnum, optional_scalars.OptionalByteTwo)
2346 expectEq("defaultEnum", obj.DefaultEnum, optional_scalars.OptionalByteTwo)
2347 }
2348
2349 func CheckByKey(fail func(string, ...interface{})) {
2350 expectEq := func(what string, a, b interface{}) {
2351 if a != b {
2352 fail(FailString("Lookup by key: "+what, b, a))
2353 }
2354 }
2355
2356 b := flatbuffers.NewBuilder(0)
2357 name := b.CreateString("Boss")
2358
2359 slime := &example.MonsterT{Name: "Slime"}
2360 pig := &example.MonsterT{Name: "Pig"}
2361 slimeBoss := &example.MonsterT{Name: "SlimeBoss"}
2362 mushroom := &example.MonsterT{Name: "Mushroom"}
2363 ironPig := &example.MonsterT{Name: "Iron Pig"}
2364
2365 monsterOffsets := make([]flatbuffers.UOffsetT, 5)
2366 monsterOffsets[0] = slime.Pack(b)
2367 monsterOffsets[1] = pig.Pack(b)
2368 monsterOffsets[2] = slimeBoss.Pack(b)
2369 monsterOffsets[3] = mushroom.Pack(b)
2370 monsterOffsets[4] = ironPig.Pack(b)
2371 testarrayoftables := b.CreateVectorOfSortedTables(monsterOffsets, example.MonsterKeyCompare)
2372
2373 str := &example.StatT{Id: "Strength", Count: 42}
2374 luk := &example.StatT{Id: "Luck", Count: 51}
2375 hp := &example.StatT{Id: "Health", Count: 12}
2376
2377 mp := &example.StatT{Id: "Mana"}
2378
2379 statOffsets := make([]flatbuffers.UOffsetT, 4)
2380 statOffsets[0] = str.Pack(b)
2381 statOffsets[1] = luk.Pack(b)
2382 statOffsets[2] = hp.Pack(b)
2383 statOffsets[3] = mp.Pack(b)
2384 scalarKeySortedTablesOffset := b.CreateVectorOfSortedTables(statOffsets, example.StatKeyCompare)
2385
2386 example.MonsterStart(b)
2387 example.MonsterAddName(b, name)
2388 example.MonsterAddTestarrayoftables(b, testarrayoftables)
2389 example.MonsterAddScalarKeySortedTables(b, scalarKeySortedTablesOffset)
2390 moff := example.MonsterEnd(b)
2391 b.Finish(moff)
2392
2393 monster := example.GetRootAsMonster(b.Bytes, b.Head())
2394 slimeMon := &example.Monster{}
2395 monster.TestarrayoftablesByKey(slimeMon, slime.Name)
2396 mushroomMon := &example.Monster{}
2397 monster.TestarrayoftablesByKey(mushroomMon, mushroom.Name)
2398 slimeBossMon := &example.Monster{}
2399 monster.TestarrayoftablesByKey(slimeBossMon, slimeBoss.Name)
2400
2401 strStat := &example.Stat{}
2402 monster.ScalarKeySortedTablesByKey(strStat, str.Count)
2403 lukStat := &example.Stat{}
2404 monster.ScalarKeySortedTablesByKey(lukStat, luk.Count)
2405 mpStat := &example.Stat{}
2406 monster.ScalarKeySortedTablesByKey(mpStat, mp.Count)
2407
2408 expectEq("Boss name", string(monster.Name()), "Boss")
2409 expectEq("Slime name", string(slimeMon.Name()), slime.Name)
2410 expectEq("Mushroom name", string(mushroomMon.Name()), mushroom.Name)
2411 expectEq("SlimeBoss name", string(slimeBossMon.Name()), slimeBoss.Name)
2412 expectEq("Strength Id", string(strStat.Id()), str.Id)
2413 expectEq("Strength Count", strStat.Count(), str.Count)
2414 expectEq("Luck Id", string(lukStat.Id()), luk.Id)
2415 expectEq("Luck Count", lukStat.Count(), luk.Count)
2416 expectEq("Mana Id", string(mpStat.Id()), mp.Id)
2417
2418 expectEq("Mana Count", mpStat.Count(), uint16(0))
2419 }
2420
2421
2422
2423
2424
2425
2426 func BenchmarkVtableDeduplication(b *testing.B) {
2427 prePop := 10
2428 builder := flatbuffers.NewBuilder(0)
2429
2430
2431 for i := 0; i < prePop; i++ {
2432 builder.StartObject(i)
2433 for j := 0; j < i; j++ {
2434 builder.PrependInt16Slot(j, int16(j), 0)
2435 }
2436 builder.EndObject()
2437 }
2438
2439
2440 b.ResetTimer()
2441 for i := 0; i < b.N; i++ {
2442 lim := prePop
2443
2444 builder.StartObject(lim)
2445 for j := 0; j < lim; j++ {
2446 builder.PrependInt16Slot(j, int16(j), 0)
2447 }
2448 builder.EndObject()
2449 }
2450 }
2451
2452
2453
2454 func BenchmarkParseGold(b *testing.B) {
2455 buf, offset := CheckGeneratedBuild(false, false, b.Fatalf)
2456 monster := example.GetRootAsMonster(buf, offset)
2457
2458
2459 reuse_pos := example.Vec3{}
2460 reuse_test3 := example.Test{}
2461 reuse_table2 := flatbuffers.Table{}
2462 reuse_monster2 := example.Monster{}
2463 reuse_test4_0 := example.Test{}
2464 reuse_test4_1 := example.Test{}
2465
2466 b.SetBytes(int64(len(buf[offset:])))
2467 b.ReportAllocs()
2468 b.ResetTimer()
2469 for i := 0; i < b.N; i++ {
2470 monster.Hp()
2471 monster.Mana()
2472 name := monster.Name()
2473 _ = name[0]
2474 _ = name[len(name)-1]
2475
2476 monster.Pos(&reuse_pos)
2477 reuse_pos.X()
2478 reuse_pos.Y()
2479 reuse_pos.Z()
2480 reuse_pos.Test1()
2481 reuse_pos.Test2()
2482 reuse_pos.Test3(&reuse_test3)
2483 reuse_test3.A()
2484 reuse_test3.B()
2485 monster.TestType()
2486 monster.Test(&reuse_table2)
2487 reuse_monster2.Init(reuse_table2.Bytes, reuse_table2.Pos)
2488 name2 := reuse_monster2.Name()
2489 _ = name2[0]
2490 _ = name2[len(name2)-1]
2491 monster.InventoryLength()
2492 l := monster.InventoryLength()
2493 for i := 0; i < l; i++ {
2494 monster.Inventory(i)
2495 }
2496 monster.Test4Length()
2497 monster.Test4(&reuse_test4_0, 0)
2498 monster.Test4(&reuse_test4_1, 1)
2499
2500 reuse_test4_0.A()
2501 reuse_test4_0.B()
2502 reuse_test4_1.A()
2503 reuse_test4_1.B()
2504
2505 monster.TestarrayofstringLength()
2506 str0 := monster.Testarrayofstring(0)
2507 _ = str0[0]
2508 _ = str0[len(str0)-1]
2509 str1 := monster.Testarrayofstring(1)
2510 _ = str1[0]
2511 _ = str1[len(str1)-1]
2512 }
2513 }
2514
2515
2516 func BenchmarkBuildGold(b *testing.B) {
2517 buf, offset := CheckGeneratedBuild(false, false, b.Fatalf)
2518 bytes_length := int64(len(buf[offset:]))
2519
2520 reuse_str := "MyMonster"
2521 reuse_test1 := "test1"
2522 reuse_test2 := "test2"
2523 reuse_fred := "Fred"
2524
2525 b.SetBytes(bytes_length)
2526 bldr := flatbuffers.NewBuilder(0)
2527 b.ResetTimer()
2528 b.ReportAllocs()
2529 for i := 0; i < b.N; i++ {
2530 bldr.Reset()
2531
2532 str := bldr.CreateString(reuse_str)
2533 test1 := bldr.CreateString(reuse_test1)
2534 test2 := bldr.CreateString(reuse_test2)
2535 fred := bldr.CreateString(reuse_fred)
2536
2537 example.MonsterStartInventoryVector(bldr, 5)
2538 bldr.PrependByte(4)
2539 bldr.PrependByte(3)
2540 bldr.PrependByte(2)
2541 bldr.PrependByte(1)
2542 bldr.PrependByte(0)
2543 inv := bldr.EndVector(5)
2544
2545 example.MonsterStart(bldr)
2546 example.MonsterAddName(bldr, fred)
2547 mon2 := example.MonsterEnd(bldr)
2548
2549 example.MonsterStartTest4Vector(bldr, 2)
2550 example.CreateTest(bldr, 10, 20)
2551 example.CreateTest(bldr, 30, 40)
2552 test4 := bldr.EndVector(2)
2553
2554 example.MonsterStartTestarrayofstringVector(bldr, 2)
2555 bldr.PrependUOffsetT(test2)
2556 bldr.PrependUOffsetT(test1)
2557 testArrayOfString := bldr.EndVector(2)
2558
2559 example.MonsterStart(bldr)
2560
2561 pos := example.CreateVec3(bldr, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
2562 example.MonsterAddPos(bldr, pos)
2563
2564 example.MonsterAddHp(bldr, 80)
2565 example.MonsterAddName(bldr, str)
2566 example.MonsterAddInventory(bldr, inv)
2567 example.MonsterAddTestType(bldr, 1)
2568 example.MonsterAddTest(bldr, mon2)
2569 example.MonsterAddTest4(bldr, test4)
2570 example.MonsterAddTestarrayofstring(bldr, testArrayOfString)
2571 mon := example.MonsterEnd(bldr)
2572
2573 bldr.Finish(mon)
2574 }
2575 }
2576
View as plain text