| 663 | } |
| 664 | |
| 665 | void ReflectionTest(uint8_t *flatbuf, size_t length) { |
| 666 | // Load a binary schema. |
| 667 | std::string bfbsfile; |
| 668 | TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.bfbs").c_str(), |
| 669 | true, &bfbsfile), |
| 670 | true); |
| 671 | |
| 672 | // Verify it, just in case: |
| 673 | flatbuffers::Verifier verifier( |
| 674 | reinterpret_cast<const uint8_t *>(bfbsfile.c_str()), bfbsfile.length()); |
| 675 | TEST_EQ(reflection::VerifySchemaBuffer(verifier), true); |
| 676 | |
| 677 | // Make sure the schema is what we expect it to be. |
| 678 | auto &schema = *reflection::GetSchema(bfbsfile.c_str()); |
| 679 | auto root_table = schema.root_table(); |
| 680 | TEST_EQ_STR(root_table->name()->c_str(), "MyGame.Example.Monster"); |
| 681 | auto fields = root_table->fields(); |
| 682 | auto hp_field_ptr = fields->LookupByKey("hp"); |
| 683 | TEST_NOTNULL(hp_field_ptr); |
| 684 | auto &hp_field = *hp_field_ptr; |
| 685 | TEST_EQ_STR(hp_field.name()->c_str(), "hp"); |
| 686 | TEST_EQ(hp_field.id(), 2); |
| 687 | TEST_EQ(hp_field.type()->base_type(), reflection::Short); |
| 688 | auto friendly_field_ptr = fields->LookupByKey("friendly"); |
| 689 | TEST_NOTNULL(friendly_field_ptr); |
| 690 | TEST_NOTNULL(friendly_field_ptr->attributes()); |
| 691 | TEST_NOTNULL(friendly_field_ptr->attributes()->LookupByKey("priority")); |
| 692 | |
| 693 | // Make sure the table index is what we expect it to be. |
| 694 | auto pos_field_ptr = fields->LookupByKey("pos"); |
| 695 | TEST_NOTNULL(pos_field_ptr); |
| 696 | TEST_EQ(pos_field_ptr->type()->base_type(), reflection::Obj); |
| 697 | auto pos_table_ptr = schema.objects()->Get(pos_field_ptr->type()->index()); |
| 698 | TEST_NOTNULL(pos_table_ptr); |
| 699 | TEST_EQ_STR(pos_table_ptr->name()->c_str(), "MyGame.Example.Vec3"); |
| 700 | |
| 701 | // Now use it to dynamically access a buffer. |
| 702 | auto &root = *flatbuffers::GetAnyRoot(flatbuf); |
| 703 | |
| 704 | // Verify the buffer first using reflection based verification |
| 705 | TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(), flatbuf, length), |
| 706 | true); |
| 707 | |
| 708 | auto hp = flatbuffers::GetFieldI<uint16_t>(root, hp_field); |
| 709 | TEST_EQ(hp, 80); |
| 710 | |
| 711 | // Rather than needing to know the type, we can also get the value of |
| 712 | // any field as an int64_t/double/string, regardless of what it actually is. |
| 713 | auto hp_int64 = flatbuffers::GetAnyFieldI(root, hp_field); |
| 714 | TEST_EQ(hp_int64, 80); |
| 715 | auto hp_double = flatbuffers::GetAnyFieldF(root, hp_field); |
| 716 | TEST_EQ(hp_double, 80.0); |
| 717 | auto hp_string = flatbuffers::GetAnyFieldS(root, hp_field, &schema); |
| 718 | TEST_EQ_STR(hp_string.c_str(), "80"); |
| 719 | |
| 720 | // Get struct field through reflection |
| 721 | auto pos_struct = flatbuffers::GetFieldStruct(root, *pos_field_ptr); |
| 722 | TEST_NOTNULL(pos_struct); |
no test coverage detected