Add a wrapper around flatbuffers::TypeTable
So I can implement it on top of a Schema too.
Change-Id: I56502593e302c186cf48d3e2b42233a48202176d
diff --git a/aos/flatbuffer_utils.cc b/aos/flatbuffer_utils.cc
index 1060fa8..b0615df 100644
--- a/aos/flatbuffer_utils.cc
+++ b/aos/flatbuffer_utils.cc
@@ -1 +1,147 @@
#include "aos/flatbuffer_utils.h"
+
+#include "flatbuffers/minireflect.h"
+#include "glog/logging.h"
+
+namespace aos {
+
+bool FlatbufferType::IsSequence() const {
+ if (type_table_) {
+ return type_table_->st != flatbuffers::ST_ENUM;
+ }
+ LOG(FATAL) << "Unimplemented";
+}
+
+bool FlatbufferType::IsEnum() const {
+ if (type_table_) {
+ return type_table_->st == flatbuffers::ST_ENUM;
+ }
+ LOG(FATAL) << "Unimplemented";
+}
+
+bool FlatbufferType::FieldIsSequence(int index) const {
+ DCHECK(IsSequence());
+ if (type_table_) {
+ DCHECK_LT(static_cast<size_t>(index), type_table_->num_elems);
+ const flatbuffers::TypeCode &type_code = type_table_->type_codes[index];
+ if (type_code.base_type != flatbuffers::ET_SEQUENCE) {
+ return false;
+ }
+ DCHECK(FieldType(index).IsSequence());
+ return true;
+ }
+ LOG(FATAL) << "Unimplemented";
+}
+
+bool FlatbufferType::FieldIsEnum(int index) const {
+ DCHECK(IsSequence());
+ if (type_table_) {
+ DCHECK_LT(static_cast<size_t>(index), type_table_->num_elems);
+ const flatbuffers::TypeCode &type_code = type_table_->type_codes[index];
+ if (type_code.base_type == flatbuffers::ET_SEQUENCE) {
+ return false;
+ }
+ if (type_code.sequence_ref == -1) {
+ // Not an enum.
+ return false;
+ }
+ DCHECK(FieldType(index).IsEnum());
+ return true;
+ }
+ LOG(FATAL) << "Unimplemented";
+}
+
+std::optional<int64_t> FlatbufferType::EnumValue(std::string_view name) const {
+ DCHECK(IsEnum());
+ if (type_table_) {
+ for (size_t i = 0; i < type_table_->num_elems; ++i) {
+ if (name == type_table_->names[i]) {
+ if (type_table_->values) {
+ return type_table_->values[i];
+ } else {
+ return i;
+ }
+ }
+ }
+ return std::nullopt;
+ }
+ LOG(FATAL) << "Unimplemented";
+}
+
+bool FlatbufferType::FieldIsRepeating(int index) const {
+ DCHECK(IsSequence());
+ if (type_table_) {
+ DCHECK_LT(static_cast<size_t>(index), type_table_->num_elems);
+ const flatbuffers::TypeCode &type_code = type_table_->type_codes[index];
+ return type_code.is_repeating;
+ }
+ LOG(FATAL) << "Unimplemented";
+}
+
+int FlatbufferType::FieldIndex(std::string_view field_name) const {
+ DCHECK(IsSequence());
+ if (type_table_) {
+ for (size_t i = 0; i < type_table_->num_elems; ++i) {
+ if (field_name == std::string_view(type_table_->names[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ LOG(FATAL) << "Unimplemented";
+}
+
+std::string_view FlatbufferType::FieldName(int index) const {
+ DCHECK(IsSequence());
+ if (type_table_) {
+ DCHECK_LT(static_cast<size_t>(index), type_table_->num_elems);
+ return type_table_->names[index];
+ }
+ LOG(FATAL) << "Unimplemented";
+}
+
+flatbuffers::ElementaryType FlatbufferType::FieldElementaryType(
+ int index) const {
+ DCHECK(IsSequence());
+ if (type_table_) {
+ DCHECK_LT(static_cast<size_t>(index), type_table_->num_elems);
+ const flatbuffers::TypeCode &type_code = type_table_->type_codes[index];
+ return static_cast<flatbuffers::ElementaryType>(type_code.base_type);
+ }
+ LOG(FATAL) << "Unimplemented";
+}
+
+size_t FlatbufferType::FieldInlineSize(int index) const {
+ DCHECK(IsSequence());
+ if (type_table_) {
+ return flatbuffers::InlineSize(FieldElementaryType(index), type_table_);
+ }
+ LOG(FATAL) << "Unimplemented";
+}
+
+int FlatbufferType::NumberFields() const {
+ DCHECK(IsSequence());
+ if (type_table_) {
+ return type_table_->num_elems;
+ }
+ LOG(FATAL) << "Unimplemented";
+}
+
+FlatbufferType FlatbufferType::FieldType(int index) const {
+ DCHECK(IsSequence());
+ if (type_table_) {
+ DCHECK_LT(static_cast<size_t>(index), type_table_->num_elems);
+ const flatbuffers::TypeCode &type_code = type_table_->type_codes[index];
+ CHECK_GE(type_code.sequence_ref, 0);
+ // type_refs can be shorter than num_elems, but not longer, so this is still
+ // a valid sanity check.
+ DCHECK_LT(static_cast<size_t>(type_code.sequence_ref),
+ type_table_->num_elems);
+ const flatbuffers::TypeFunction type_function =
+ type_table_->type_refs[type_code.sequence_ref];
+ return FlatbufferType(type_function());
+ }
+ LOG(FATAL) << "Unimplemented";
+}
+
+} // namespace aos