172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen/* 272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * Copyright 2017 Google Inc. All rights reserved. 372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * 472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * Licensed under the Apache License, Version 2.0 (the "License"); 572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * you may not use this file except in compliance with the License. 672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * You may obtain a copy of the License at 772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * 872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * http://www.apache.org/licenses/LICENSE-2.0 972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * 1072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * Unless required by applicable law or agreed to in writing, software 1172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * distributed under the License is distributed on an "AS IS" BASIS, 1272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * See the License for the specific language governing permissions and 1472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen * limitations under the License. 1572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen */ 1672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 1772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen#ifndef FLATBUFFERS_MINIREFLECT_H_ 1872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen#define FLATBUFFERS_MINIREFLECT_H_ 1972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 2072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen#include "flatbuffers/flatbuffers.h" 2172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen#include "flatbuffers/util.h" 2272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 2372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssennamespace flatbuffers { 2472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 2572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen// Utilities that can be used with the "mini reflection" tables present 2672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen// in generated code with --reflect-types (only types) or --reflect-names 2772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen// (also names). 2872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen// This allows basic reflection functionality such as pretty-printing 2972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen// that does not require the use of the schema parser or loading of binary 3072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen// schema files at runtime (reflection.h). 3172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 3272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen// For any of the functions below that take `const TypeTable *`, you pass 3372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen// `FooTypeTable()` if the type of the root is `Foo`. 3472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 3572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen// First, a generic iterator that can be used by multiple algorithms. 3672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 3772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssenstruct IterationVisitor { 3872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen // These mark the scope of a table or struct. 3972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void StartSequence() {} 4072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void EndSequence() {} 4172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen // Called for each field regardless of wether it is present or not. 4272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen // If not present, val == nullptr. set_idx is the index of all set fields. 4372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void Field(size_t /*field_idx*/, size_t /*set_idx*/, 4472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen ElementaryType /*type*/, bool /*is_vector*/, 4572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const TypeTable * /*type_table*/, const char * /*name*/, 4672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const uint8_t * /*val*/) {} 4772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen // Called for a value that is actually present, after a field, or as part 4872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen // of a vector. 4972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void UType(uint8_t, const char *) {} 5072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void Bool(bool) {} 5172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void Char(int8_t, const char *) {} 5272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void UChar(uint8_t, const char *) {} 5372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void Short(int16_t, const char *) {} 5472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void UShort(uint16_t, const char *) {} 5572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void Int(int32_t, const char *) {} 5672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void UInt(uint32_t, const char *) {} 5772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void Long(int64_t) {} 5872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void ULong(uint64_t) {} 5972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void Float(float) {} 6072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void Double(double) {} 6172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void String(const String *) {} 6272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void Unknown(const uint8_t *) {} // From a future version. 6372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen // These mark the scope of a vector. 6472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void StartVector() {} 6572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void EndVector() {} 6672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual void Element(size_t /*i*/, ElementaryType /*type*/, 6772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const TypeTable * /*type_table*/, 6872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const uint8_t * /*val*/) 6972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen {} 7072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen virtual ~IterationVisitor() {} 7172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen}; 7272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 7372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmersseninline size_t InlineSize(ElementaryType type, const TypeTable *type_table) { 7472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen switch (type) { 7572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_UTYPE: 7672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_BOOL: 7772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_CHAR: 7872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_UCHAR: 7972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen return 1; 8072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_SHORT: 8172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_USHORT: 8272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen return 2; 8372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_INT: 8472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_UINT: 8572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_FLOAT: 8672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_STRING: 8772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen return 4; 8872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_LONG: 8972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_ULONG: 9072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_DOUBLE: 9172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen return 8; 9272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_SEQUENCE: 9372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen switch (type_table->st) { 9472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ST_TABLE: 9572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ST_UNION: 9672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen return 4; 9772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ST_STRUCT: 9872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen return type_table->values[type_table->num_elems]; 9972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen default: 10072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen assert(false); 10172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen return 1; 10272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 10372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen default: 10472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen assert(false); 10572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen return 1; 10672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 10772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen} 10872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 10972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmersseninline int32_t LookupEnum(int32_t enum_val, const int32_t *values, 11072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen size_t num_values) { 11172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (!values) return enum_val; 11272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen for (size_t i = 0; i < num_values; i++) { 11372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (enum_val == values[i]) return static_cast<int32_t>(i); 11472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 11572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen return -1; // Unknown enum value. 11672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen} 11772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 11872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssentemplate<typename T> const char *EnumName(T tval, const TypeTable *type_table) { 11972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (!type_table || !type_table->names) return nullptr; 12072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto i = LookupEnum(static_cast<int32_t>(tval), type_table->values, 12172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen type_table->num_elems); 12272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (i >= 0 && i < static_cast<int32_t>(type_table->num_elems)) { 12372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen return type_table->names[i]; 12472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 12572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen return nullptr; 12672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen} 12772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 12872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssenvoid IterateObject(const uint8_t *obj, const TypeTable *type_table, 12972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen IterationVisitor *visitor); 13072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 13172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmersseninline void IterateValue(ElementaryType type, const uint8_t *val, 13272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const TypeTable *type_table, 13372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const uint8_t *prev_val, 13472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen soffset_t vector_index, 13572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen IterationVisitor *visitor) { 13672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen switch (type) { 13772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_UTYPE: { 13872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto tval = *reinterpret_cast<const uint8_t *>(val); 13972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->UType(tval, EnumName(tval, type_table)); 14072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 14172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 14272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_BOOL: { 14372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->Bool(*reinterpret_cast<const uint8_t *>(val) != 0); 14472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 14572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 14672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_CHAR: { 14772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto tval = *reinterpret_cast<const int8_t *>(val); 14872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->Char(tval, EnumName(tval, type_table)); 14972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 15072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 15172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_UCHAR: { 15272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto tval = *reinterpret_cast<const uint8_t *>(val); 15372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->UChar(tval, EnumName(tval, type_table)); 15472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 15572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 15672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_SHORT: { 15772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto tval = *reinterpret_cast<const int16_t *>(val); 15872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->Short(tval, EnumName(tval, type_table)); 15972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 16072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 16172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_USHORT: { 16272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto tval = *reinterpret_cast<const uint16_t *>(val); 16372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->UShort(tval, EnumName(tval, type_table)); 16472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 16572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 16672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_INT: { 16772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto tval = *reinterpret_cast<const int32_t *>(val); 16872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->Int(tval, EnumName(tval, type_table)); 16972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 17072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 17172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_UINT: { 17272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto tval = *reinterpret_cast<const uint32_t *>(val); 17372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->UInt(tval, EnumName(tval, type_table)); 17472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 17572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 17672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_LONG: { 17772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->Long(*reinterpret_cast<const int64_t *>(val)); 17872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 17972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 18072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_ULONG: { 18172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->ULong(*reinterpret_cast<const uint64_t *>(val)); 18272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 18372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 18472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_FLOAT: { 18572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->Float(*reinterpret_cast<const float *>(val)); 18672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 18772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 18872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_DOUBLE: { 18972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->Double(*reinterpret_cast<const double *>(val)); 19072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 19172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 19272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_STRING: { 19372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen val += ReadScalar<uoffset_t>(val); 19472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->String(reinterpret_cast<const String *>(val)); 19572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 19672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 19772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_SEQUENCE: { 19872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen switch (type_table->st) { 19972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ST_TABLE: 20072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen val += ReadScalar<uoffset_t>(val); 20172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen IterateObject(val, type_table, visitor); 20272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 20372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ST_STRUCT: 20472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen IterateObject(val, type_table, visitor); 20572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 20672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ST_UNION: { 20772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen val += ReadScalar<uoffset_t>(val); 20872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen assert(prev_val); 20972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto union_type = *prev_val; // Always a uint8_t. 21072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (vector_index >= 0) { 21172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val); 21272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen union_type = type_vec->Get(static_cast<uoffset_t>(vector_index)); 21372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 21472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto type_code_idx = LookupEnum(union_type, type_table->values, 21572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen type_table->num_elems); 21672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (type_code_idx >= 0 && type_code_idx < 21772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen static_cast<int32_t>(type_table->num_elems)) { 21872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto type_code = type_table->type_codes[type_code_idx]; 21972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen switch (type_code.base_type) { 22072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_SEQUENCE: { 22172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto ref = type_table->type_refs[type_code.sequence_ref](); 22272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen IterateObject(val, ref, visitor); 22372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 22472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 22572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ET_STRING: 22672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->String(reinterpret_cast<const String *>(val)); 22772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 22872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen default: 22972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->Unknown(val); 23072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 23172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } else { 23272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->Unknown(val); 23372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 23472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 23572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 23672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen case ST_ENUM: 23772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen assert(false); 23872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 23972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 24072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 24172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 24272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen default: { 24372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->Unknown(val); 24472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen break; 24572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 24672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 24772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen} 24872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 24972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmersseninline void IterateObject(const uint8_t *obj, const TypeTable *type_table, 25072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen IterationVisitor *visitor) { 25172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->StartSequence(); 25272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const uint8_t *prev_val = nullptr; 25372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen size_t set_idx = 0; 25472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen for (size_t i = 0; i < type_table->num_elems; i++) { 25572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto type_code = type_table->type_codes[i]; 25672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto type = static_cast<ElementaryType>(type_code.base_type); 25772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto is_vector = type_code.is_vector != 0; 25872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto ref_idx = type_code.sequence_ref; 25972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const TypeTable *ref = nullptr; 26072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (ref_idx >= 0) { 26172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen ref = type_table->type_refs[ref_idx](); 26272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 26372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto name = type_table->names ? type_table->names[i] : nullptr; 26472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const uint8_t *val = nullptr; 26572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (type_table->st == ST_TABLE) { 26672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen val = reinterpret_cast<const Table *>(obj)->GetAddressOf( 26772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen FieldIndexToOffset(static_cast<voffset_t>(i))); 26872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } else { 26972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen val = obj + type_table->values[i]; 27072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 27172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->Field(i, set_idx, type, is_vector, ref, name, val); 27272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (val) { 27372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen set_idx++; 27472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (is_vector) { 27572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen val += ReadScalar<uoffset_t>(val); 27672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto vec = reinterpret_cast<const Vector<uint8_t> *>(val); 27772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->StartVector(); 27872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen auto elem_ptr = vec->Data(); 27972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen for (size_t j = 0; j < vec->size(); j++) { 28072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->Element(j, type, ref, elem_ptr); 28172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen IterateValue(type, elem_ptr, ref, prev_val, static_cast<soffset_t>(j), 28272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor); 28372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen elem_ptr += InlineSize(type, ref); 28472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 28572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->EndVector(); 28672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } else { 28772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen IterateValue(type, val, ref, prev_val, -1, visitor); 28872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 28972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 29072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen prev_val = val; 29172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 29272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen visitor->EndSequence(); 29372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen} 29472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 29572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmersseninline void IterateFlatBuffer(const uint8_t *buffer, 29672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const TypeTable *type_table, 29772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen IterationVisitor *callback) { 29872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen IterateObject(GetRoot<uint8_t>(buffer), type_table, callback); 29972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen} 30072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 30172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen// Outputting a Flatbuffer to a string. Tries to conform as close to JSON / 30272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen// the output generated by idl_gen_text.cpp. 30372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 30472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssenstruct ToStringVisitor : public IterationVisitor { 30572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen std::string s; 30672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void StartSequence() { s += "{ "; } 30772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void EndSequence() { s += " }"; } 30872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/, 30972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen bool /*is_vector*/, const TypeTable * /*type_table*/, 31072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const char *name, const uint8_t *val) { 31172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (!val) return; 31272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (set_idx) s += ", "; 31372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (name) { s += name; s += ": "; } 31472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 31572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen template<typename T> void Named(T x, const char *name) { 31672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (name) s+= name; 31772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen else s+= NumToString(x); 31872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 31972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void UType(uint8_t x, const char *name) { Named(x, name); } 32072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void Bool(bool x) { s+= x ? "true" : "false"; } 32172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void Char(int8_t x, const char *name) { Named(x, name); } 32272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void UChar(uint8_t x, const char *name) { Named(x, name); } 32372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void Short(int16_t x, const char *name) { Named(x, name); } 32472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void UShort(uint16_t x, const char *name) { Named(x, name); } 32572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void Int(int32_t x, const char *name) { Named(x, name); } 32672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void UInt(uint32_t x, const char *name) { Named(x, name); } 32772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void Long(int64_t x) { s+= NumToString(x); } 32872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void ULong(uint64_t x) { s+= NumToString(x); } 32972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void Float(float x) { s+= NumToString(x); } 33072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void Double(double x) { s+= NumToString(x); } 33172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void String(const struct String *str) { 33272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen EscapeString(str->c_str(), str->size(), &s, true); 33372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 33472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void Unknown(const uint8_t *) { s += "(?)"; } 33572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void StartVector() { s += "[ "; } 33672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void EndVector() { s += " ]"; } 33772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen void Element(size_t i, ElementaryType /*type*/, 33872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const TypeTable * /*type_table*/, const uint8_t * /*val*/) { 33972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen if (i) s += ", "; 34072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen } 34172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen}; 34272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 34372a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmersseninline std::string FlatBufferToString(const uint8_t *buffer, 34472a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen const TypeTable *type_table) { 34572a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen ToStringVisitor tostring_visitor; 34672a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen IterateFlatBuffer(buffer, type_table, &tostring_visitor); 34772a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen return tostring_visitor.s; 34872a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen} 34972a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 35072a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen} // namespace flatbuffers 35172a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen 35272a99abfb7db64dc49720b28b41f382b5ec7cde0Wouter van Oortmerssen#endif // FLATBUFFERS_MINIREFLECT_H_ 353