From 84033ae035208930fa8ccf2b1926be83cab90758 Mon Sep 17 00:00:00 2001 From: Zarian Waheed Date: Wed, 21 Dec 2016 17:48:21 -0800 Subject: [PATCH] Added helper methods to access struct through reflection. (#4120) * Added helper methods to access struct through reflection. Also added unit test for it. * Added a TODO comment to check for the is_struct flag. --- include/flatbuffers/reflection.h | 16 ++++++++++++++++ tests/test.cpp | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/flatbuffers/reflection.h b/include/flatbuffers/reflection.h index 632acda..6d8608a 100644 --- a/include/flatbuffers/reflection.h +++ b/include/flatbuffers/reflection.h @@ -105,6 +105,22 @@ inline Table *GetFieldT(const Table &table, return table.GetPointer(field.offset()); } +// Get a field, if you know it's a struct. +inline const Struct *GetFieldStruct(const Table &table, + const reflection::Field &field) { + // TODO: This does NOT check if the field is a table or struct, but we'd need + // access to the schema to check the is_struct flag. + assert(field.type()->base_type() == reflection::Obj); + return table.GetStruct(field.offset()); +} + +// Get a structure's field, if you know it's a struct. +inline const Struct *GetFieldStruct(const Struct &structure, + const reflection::Field &field) { + assert(field.type()->base_type() == reflection::Obj); + return structure.GetStruct(field.offset()); +} + // Raw helper functions used below: get any value in memory as a 64bit int, a // double or a string. // All scalars get static_cast to an int64_t, strings use strtoull, every other diff --git a/tests/test.cpp b/tests/test.cpp index 4f44952..01d23e0 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -511,6 +511,20 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) { auto hp_string = flatbuffers::GetAnyFieldS(root, hp_field, &schema); TEST_EQ_STR(hp_string.c_str(), "80"); + // Get struct field through reflection + auto pos_struct = flatbuffers::GetFieldStruct(root, *pos_field_ptr); + TEST_NOTNULL(pos_struct); + TEST_EQ(flatbuffers::GetAnyFieldF( + *pos_struct, *pos_table_ptr->fields()->LookupByKey("z")), 3.0f); + + auto test3_field = pos_table_ptr->fields()->LookupByKey("test3"); + auto test3_struct = flatbuffers::GetFieldStruct(*pos_struct, *test3_field); + TEST_NOTNULL(test3_struct); + auto test3_object = schema.objects()->Get(test3_field->type()->index()); + + TEST_EQ(flatbuffers::GetAnyFieldF( + *test3_struct, *test3_object->fields()->LookupByKey("a")), 10); + // We can also modify it. flatbuffers::SetField(&root, hp_field, 200); hp = flatbuffers::GetFieldI(root, hp_field); -- 2.7.4