mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-26 21:32:18 +00:00
Added support for mini-reflection tables.
Change-Id: I83453d074685fa57bbf1c7c87b1d9392ce972085 Tested: on Linux.
This commit is contained in:
@@ -34,6 +34,7 @@ set(FlatBuffers_Library_SRCS
|
|||||||
include/flatbuffers/stl_emulation.h
|
include/flatbuffers/stl_emulation.h
|
||||||
include/flatbuffers/flexbuffers.h
|
include/flatbuffers/flexbuffers.h
|
||||||
include/flatbuffers/registry.h
|
include/flatbuffers/registry.h
|
||||||
|
include/flatbuffers/minireflect.h
|
||||||
src/code_generators.cpp
|
src/code_generators.cpp
|
||||||
src/idl_parser.cpp
|
src/idl_parser.cpp
|
||||||
src/idl_gen_text.cpp
|
src/idl_gen_text.cpp
|
||||||
@@ -200,6 +201,7 @@ function(compile_flatbuffers_schema_to_cpp SRC_FBS)
|
|||||||
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable
|
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable
|
||||||
--gen-object-api -o "${SRC_FBS_DIR}"
|
--gen-object-api -o "${SRC_FBS_DIR}"
|
||||||
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
|
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
|
||||||
|
--reflect-names
|
||||||
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
||||||
DEPENDS flatc)
|
DEPENDS flatc)
|
||||||
|
|||||||
@@ -125,5 +125,8 @@ Additional options:
|
|||||||
|
|
||||||
- `--keep-prefix` : Keep original prefix of schema include statement.
|
- `--keep-prefix` : Keep original prefix of schema include statement.
|
||||||
|
|
||||||
|
- `--reflect-types` : Add minimal type reflection to code generation.
|
||||||
|
- `--reflect-names` : Add minimal type/name reflection.
|
||||||
|
|
||||||
NOTE: short-form options for generators are deprecated, use the long form
|
NOTE: short-form options for generators are deprecated, use the long form
|
||||||
whenever possible.
|
whenever possible.
|
||||||
|
|||||||
@@ -231,6 +231,30 @@ schema, as well as a lot of helper functions.
|
|||||||
And example of usage, for the time being, can be found in
|
And example of usage, for the time being, can be found in
|
||||||
`test.cpp/ReflectionTest()`.
|
`test.cpp/ReflectionTest()`.
|
||||||
|
|
||||||
|
## Mini Reflection
|
||||||
|
|
||||||
|
A more limited form of reflection is available for direct inclusion in
|
||||||
|
generated code, which doesn't any (binary) schema access at all. It was designed
|
||||||
|
to keep the overhead of reflection as low as possible (on the order of 2-6
|
||||||
|
bytes per field added to your executable), but doesn't contain all the
|
||||||
|
information the (binary) schema contains.
|
||||||
|
|
||||||
|
You add this information to your generated code by specifying `--reflect-types`
|
||||||
|
(or instead `--reflect-names` if you also want field / enum names).
|
||||||
|
|
||||||
|
You can now use this information, for example to print a FlatBuffer to text:
|
||||||
|
|
||||||
|
auto s = flatbuffers::FlatBufferToString(flatbuf, MonsterTypeTable());
|
||||||
|
|
||||||
|
`MonsterTypeTable()` is declared in the generated code for each type. The
|
||||||
|
string produced is very similar to the JSON produced by the `Parser` based
|
||||||
|
text generator.
|
||||||
|
|
||||||
|
You'll need `flatbuffers/minireflect.h` for this functionality. In there is also
|
||||||
|
a convenient visitor/iterator so you can write your own output / functionality
|
||||||
|
based on the mini reflection tables without having to know the FlatBuffers or
|
||||||
|
reflection encoding.
|
||||||
|
|
||||||
## Storing maps / dictionaries in a FlatBuffer
|
## Storing maps / dictionaries in a FlatBuffer
|
||||||
|
|
||||||
FlatBuffers doesn't support maps natively, but there is support to
|
FlatBuffers doesn't support maps natively, but there is support to
|
||||||
|
|||||||
@@ -2066,6 +2066,73 @@ inline int LookupEnum(const char **names, const char *name) {
|
|||||||
#error Unknown compiler, please define structure alignment macros
|
#error Unknown compiler, please define structure alignment macros
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Minimal reflection via code generation.
|
||||||
|
// Besides full-fat reflection (see reflection.h) and parsing/printing by
|
||||||
|
// loading schemas (see idl.h), we can also have code generation for mimimal
|
||||||
|
// reflection data which allows pretty-printing and other uses without needing
|
||||||
|
// a schema or a parser.
|
||||||
|
// Generate code with --reflect-types (types only) or --reflect-names (names
|
||||||
|
// also) to enable.
|
||||||
|
// See minireflect.h for utilities using this functionality.
|
||||||
|
|
||||||
|
// These types are organized slightly differently as the ones in idl.h.
|
||||||
|
enum SequenceType { ST_TABLE, ST_STRUCT, ST_UNION, ST_ENUM };
|
||||||
|
|
||||||
|
// Scalars have the same order as in idl.h
|
||||||
|
#define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \
|
||||||
|
ET(ET_UTYPE) \
|
||||||
|
ET(ET_BOOL) \
|
||||||
|
ET(ET_CHAR) \
|
||||||
|
ET(ET_UCHAR) \
|
||||||
|
ET(ET_SHORT) \
|
||||||
|
ET(ET_USHORT) \
|
||||||
|
ET(ET_INT) \
|
||||||
|
ET(ET_UINT) \
|
||||||
|
ET(ET_LONG) \
|
||||||
|
ET(ET_ULONG) \
|
||||||
|
ET(ET_FLOAT) \
|
||||||
|
ET(ET_DOUBLE) \
|
||||||
|
ET(ET_STRING) \
|
||||||
|
ET(ET_SEQUENCE) // See SequenceType.
|
||||||
|
|
||||||
|
enum ElementaryType {
|
||||||
|
#define FLATBUFFERS_ET(E) E,
|
||||||
|
FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
|
||||||
|
#undef FLATBUFFERS_ET
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const char **ElementaryTypeNames() {
|
||||||
|
static const char *names[] = {
|
||||||
|
#define FLATBUFFERS_ET(E) #E,
|
||||||
|
FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
|
||||||
|
#undef FLATBUFFERS_ET
|
||||||
|
};
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic type info cost just 16bits per field!
|
||||||
|
struct TypeCode {
|
||||||
|
uint16_t base_type : 4; // ElementaryType
|
||||||
|
uint16_t is_vector : 1;
|
||||||
|
int16_t sequence_ref : 11; // Index into type_refs below, or -1 for none.
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(TypeCode) == 2, "TypeCode");
|
||||||
|
|
||||||
|
struct TypeTable;
|
||||||
|
|
||||||
|
// Signature of the static method present in each type.
|
||||||
|
typedef TypeTable *(*TypeFunction)();
|
||||||
|
|
||||||
|
struct TypeTable {
|
||||||
|
SequenceType st;
|
||||||
|
size_t num_elems; // of each of the arrays below.
|
||||||
|
const TypeCode *type_codes;
|
||||||
|
const TypeFunction *type_refs;
|
||||||
|
const int32_t *values; // Only set for non-consecutive enum/union or structs.
|
||||||
|
const char **names; // Only set if compiled with --reflect-names.
|
||||||
|
};
|
||||||
|
|
||||||
// String which identifies the current version of FlatBuffers.
|
// String which identifies the current version of FlatBuffers.
|
||||||
// flatbuffer_version_string is used by Google developers to identify which
|
// flatbuffer_version_string is used by Google developers to identify which
|
||||||
// applications uploaded to Google Play are using this library. This allows
|
// applications uploaded to Google Play are using this library. This allows
|
||||||
|
|||||||
@@ -396,6 +396,10 @@ struct IDLOptions {
|
|||||||
|
|
||||||
Language lang;
|
Language lang;
|
||||||
|
|
||||||
|
enum MiniReflect { kNone, kTypes, kTypesAndNames };
|
||||||
|
|
||||||
|
MiniReflect mini_reflect;
|
||||||
|
|
||||||
// The corresponding language bit will be set if a language is included
|
// The corresponding language bit will be set if a language is included
|
||||||
// for code generation.
|
// for code generation.
|
||||||
unsigned long lang_to_generate;
|
unsigned long lang_to_generate;
|
||||||
@@ -426,6 +430,7 @@ struct IDLOptions {
|
|||||||
reexport_ts_modules(true),
|
reexport_ts_modules(true),
|
||||||
protobuf_ascii_alike(false),
|
protobuf_ascii_alike(false),
|
||||||
lang(IDLOptions::kJava),
|
lang(IDLOptions::kJava),
|
||||||
|
mini_reflect(IDLOptions::kNone),
|
||||||
lang_to_generate(0) {}
|
lang_to_generate(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
352
include/flatbuffers/minireflect.h
Normal file
352
include/flatbuffers/minireflect.h
Normal file
@@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_MINIREFLECT_H_
|
||||||
|
#define FLATBUFFERS_MINIREFLECT_H_
|
||||||
|
|
||||||
|
#include "flatbuffers/flatbuffers.h"
|
||||||
|
#include "flatbuffers/util.h"
|
||||||
|
|
||||||
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
// Utilities that can be used with the "mini reflection" tables present
|
||||||
|
// in generated code with --reflect-types (only types) or --reflect-names
|
||||||
|
// (also names).
|
||||||
|
// This allows basic reflection functionality such as pretty-printing
|
||||||
|
// that does not require the use of the schema parser or loading of binary
|
||||||
|
// schema files at runtime (reflection.h).
|
||||||
|
|
||||||
|
// For any of the functions below that take `const TypeTable *`, you pass
|
||||||
|
// `FooTypeTable()` if the type of the root is `Foo`.
|
||||||
|
|
||||||
|
// First, a generic iterator that can be used by multiple algorithms.
|
||||||
|
|
||||||
|
struct IterationVisitor {
|
||||||
|
// These mark the scope of a table or struct.
|
||||||
|
virtual void StartSequence() {}
|
||||||
|
virtual void EndSequence() {}
|
||||||
|
// Called for each field regardless of wether it is present or not.
|
||||||
|
// If not present, val == nullptr. set_idx is the index of all set fields.
|
||||||
|
virtual void Field(size_t /*field_idx*/, size_t /*set_idx*/,
|
||||||
|
ElementaryType /*type*/, bool /*is_vector*/,
|
||||||
|
const TypeTable * /*type_table*/, const char * /*name*/,
|
||||||
|
const uint8_t * /*val*/) {}
|
||||||
|
// Called for a value that is actually present, after a field, or as part
|
||||||
|
// of a vector.
|
||||||
|
virtual void UType(uint8_t, const char *) {}
|
||||||
|
virtual void Bool(bool) {}
|
||||||
|
virtual void Char(int8_t, const char *) {}
|
||||||
|
virtual void UChar(uint8_t, const char *) {}
|
||||||
|
virtual void Short(int16_t, const char *) {}
|
||||||
|
virtual void UShort(uint16_t, const char *) {}
|
||||||
|
virtual void Int(int32_t, const char *) {}
|
||||||
|
virtual void UInt(uint32_t, const char *) {}
|
||||||
|
virtual void Long(int64_t) {}
|
||||||
|
virtual void ULong(uint64_t) {}
|
||||||
|
virtual void Float(float) {}
|
||||||
|
virtual void Double(double) {}
|
||||||
|
virtual void String(const String *) {}
|
||||||
|
virtual void Unknown(const uint8_t *) {} // From a future version.
|
||||||
|
// These mark the scope of a vector.
|
||||||
|
virtual void StartVector() {}
|
||||||
|
virtual void EndVector() {}
|
||||||
|
virtual void Element(size_t /*i*/, ElementaryType /*type*/,
|
||||||
|
const TypeTable * /*type_table*/,
|
||||||
|
const uint8_t * /*val*/)
|
||||||
|
{}
|
||||||
|
virtual ~IterationVisitor() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
|
||||||
|
switch (type) {
|
||||||
|
case ET_UTYPE:
|
||||||
|
case ET_BOOL:
|
||||||
|
case ET_CHAR:
|
||||||
|
case ET_UCHAR:
|
||||||
|
return 1;
|
||||||
|
case ET_SHORT:
|
||||||
|
case ET_USHORT:
|
||||||
|
return 2;
|
||||||
|
case ET_INT:
|
||||||
|
case ET_UINT:
|
||||||
|
case ET_FLOAT:
|
||||||
|
case ET_STRING:
|
||||||
|
return 4;
|
||||||
|
case ET_LONG:
|
||||||
|
case ET_ULONG:
|
||||||
|
case ET_DOUBLE:
|
||||||
|
return 8;
|
||||||
|
case ET_SEQUENCE:
|
||||||
|
switch (type_table->st) {
|
||||||
|
case ST_TABLE:
|
||||||
|
case ST_UNION:
|
||||||
|
return 4;
|
||||||
|
case ST_STRUCT:
|
||||||
|
return type_table->values[type_table->num_elems];
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t LookupEnum(int32_t enum_val, const int32_t *values,
|
||||||
|
size_t num_values) {
|
||||||
|
if (!values) return enum_val;
|
||||||
|
for (size_t i = 0; i < num_values; i++) {
|
||||||
|
if (enum_val == values[i]) return static_cast<int32_t>(i);
|
||||||
|
}
|
||||||
|
return -1; // Unknown enum value.
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> const char *EnumName(T tval, const TypeTable *type_table) {
|
||||||
|
if (!type_table || !type_table->names) return nullptr;
|
||||||
|
auto i = LookupEnum(static_cast<int32_t>(tval), type_table->values,
|
||||||
|
type_table->num_elems);
|
||||||
|
if (i >= 0 && i < static_cast<int32_t>(type_table->num_elems)) {
|
||||||
|
return type_table->names[i];
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
||||||
|
IterationVisitor *visitor);
|
||||||
|
|
||||||
|
inline void IterateValue(ElementaryType type, const uint8_t *val,
|
||||||
|
const TypeTable *type_table,
|
||||||
|
const uint8_t *prev_val,
|
||||||
|
soffset_t vector_index,
|
||||||
|
IterationVisitor *visitor) {
|
||||||
|
switch (type) {
|
||||||
|
case ET_UTYPE: {
|
||||||
|
auto tval = *reinterpret_cast<const uint8_t *>(val);
|
||||||
|
visitor->UType(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_BOOL: {
|
||||||
|
visitor->Bool(*reinterpret_cast<const uint8_t *>(val) != 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_CHAR: {
|
||||||
|
auto tval = *reinterpret_cast<const int8_t *>(val);
|
||||||
|
visitor->Char(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_UCHAR: {
|
||||||
|
auto tval = *reinterpret_cast<const uint8_t *>(val);
|
||||||
|
visitor->UChar(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_SHORT: {
|
||||||
|
auto tval = *reinterpret_cast<const int16_t *>(val);
|
||||||
|
visitor->Short(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_USHORT: {
|
||||||
|
auto tval = *reinterpret_cast<const uint16_t *>(val);
|
||||||
|
visitor->UShort(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_INT: {
|
||||||
|
auto tval = *reinterpret_cast<const int32_t *>(val);
|
||||||
|
visitor->Int(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_UINT: {
|
||||||
|
auto tval = *reinterpret_cast<const uint32_t *>(val);
|
||||||
|
visitor->UInt(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_LONG: {
|
||||||
|
visitor->Long(*reinterpret_cast<const int64_t *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_ULONG: {
|
||||||
|
visitor->ULong(*reinterpret_cast<const uint64_t *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_FLOAT: {
|
||||||
|
visitor->Float(*reinterpret_cast<const float *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_DOUBLE: {
|
||||||
|
visitor->Double(*reinterpret_cast<const double *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_STRING: {
|
||||||
|
val += ReadScalar<uoffset_t>(val);
|
||||||
|
visitor->String(reinterpret_cast<const String *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_SEQUENCE: {
|
||||||
|
switch (type_table->st) {
|
||||||
|
case ST_TABLE:
|
||||||
|
val += ReadScalar<uoffset_t>(val);
|
||||||
|
IterateObject(val, type_table, visitor);
|
||||||
|
break;
|
||||||
|
case ST_STRUCT:
|
||||||
|
IterateObject(val, type_table, visitor);
|
||||||
|
break;
|
||||||
|
case ST_UNION: {
|
||||||
|
val += ReadScalar<uoffset_t>(val);
|
||||||
|
assert(prev_val);
|
||||||
|
auto union_type = *prev_val; // Always a uint8_t.
|
||||||
|
if (vector_index >= 0) {
|
||||||
|
auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val);
|
||||||
|
union_type = type_vec->Get(static_cast<uoffset_t>(vector_index));
|
||||||
|
}
|
||||||
|
auto type_code_idx = LookupEnum(union_type, type_table->values,
|
||||||
|
type_table->num_elems);
|
||||||
|
if (type_code_idx >= 0 && type_code_idx <
|
||||||
|
static_cast<int32_t>(type_table->num_elems)) {
|
||||||
|
auto type_code = type_table->type_codes[type_code_idx];
|
||||||
|
switch (type_code.base_type) {
|
||||||
|
case ET_SEQUENCE: {
|
||||||
|
auto ref = type_table->type_refs[type_code.sequence_ref]();
|
||||||
|
IterateObject(val, ref, visitor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_STRING:
|
||||||
|
visitor->String(reinterpret_cast<const String *>(val));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
visitor->Unknown(val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
visitor->Unknown(val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ST_ENUM:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
visitor->Unknown(val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
||||||
|
IterationVisitor *visitor) {
|
||||||
|
visitor->StartSequence();
|
||||||
|
const uint8_t *prev_val = nullptr;
|
||||||
|
size_t set_idx = 0;
|
||||||
|
for (size_t i = 0; i < type_table->num_elems; i++) {
|
||||||
|
auto type_code = type_table->type_codes[i];
|
||||||
|
auto type = static_cast<ElementaryType>(type_code.base_type);
|
||||||
|
auto is_vector = type_code.is_vector != 0;
|
||||||
|
auto ref_idx = type_code.sequence_ref;
|
||||||
|
const TypeTable *ref = nullptr;
|
||||||
|
if (ref_idx >= 0) {
|
||||||
|
ref = type_table->type_refs[ref_idx]();
|
||||||
|
}
|
||||||
|
auto name = type_table->names ? type_table->names[i] : nullptr;
|
||||||
|
const uint8_t *val = nullptr;
|
||||||
|
if (type_table->st == ST_TABLE) {
|
||||||
|
val = reinterpret_cast<const Table *>(obj)->GetAddressOf(
|
||||||
|
FieldIndexToOffset(static_cast<voffset_t>(i)));
|
||||||
|
} else {
|
||||||
|
val = obj + type_table->values[i];
|
||||||
|
}
|
||||||
|
visitor->Field(i, set_idx, type, is_vector, ref, name, val);
|
||||||
|
if (val) {
|
||||||
|
set_idx++;
|
||||||
|
if (is_vector) {
|
||||||
|
val += ReadScalar<uoffset_t>(val);
|
||||||
|
auto vec = reinterpret_cast<const Vector<uint8_t> *>(val);
|
||||||
|
visitor->StartVector();
|
||||||
|
auto elem_ptr = vec->Data();
|
||||||
|
for (size_t j = 0; j < vec->size(); j++) {
|
||||||
|
visitor->Element(j, type, ref, elem_ptr);
|
||||||
|
IterateValue(type, elem_ptr, ref, prev_val, static_cast<soffset_t>(j),
|
||||||
|
visitor);
|
||||||
|
elem_ptr += InlineSize(type, ref);
|
||||||
|
}
|
||||||
|
visitor->EndVector();
|
||||||
|
} else {
|
||||||
|
IterateValue(type, val, ref, prev_val, -1, visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev_val = val;
|
||||||
|
}
|
||||||
|
visitor->EndSequence();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void IterateFlatBuffer(const uint8_t *buffer,
|
||||||
|
const TypeTable *type_table,
|
||||||
|
IterationVisitor *callback) {
|
||||||
|
IterateObject(GetRoot<uint8_t>(buffer), type_table, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outputting a Flatbuffer to a string. Tries to conform as close to JSON /
|
||||||
|
// the output generated by idl_gen_text.cpp.
|
||||||
|
|
||||||
|
struct ToStringVisitor : public IterationVisitor {
|
||||||
|
std::string s;
|
||||||
|
void StartSequence() { s += "{ "; }
|
||||||
|
void EndSequence() { s += " }"; }
|
||||||
|
void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/,
|
||||||
|
bool /*is_vector*/, const TypeTable * /*type_table*/,
|
||||||
|
const char *name, const uint8_t *val) {
|
||||||
|
if (!val) return;
|
||||||
|
if (set_idx) s += ", ";
|
||||||
|
if (name) { s += name; s += ": "; }
|
||||||
|
}
|
||||||
|
template<typename T> void Named(T x, const char *name) {
|
||||||
|
if (name) s+= name;
|
||||||
|
else s+= NumToString(x);
|
||||||
|
}
|
||||||
|
void UType(uint8_t x, const char *name) { Named(x, name); }
|
||||||
|
void Bool(bool x) { s+= x ? "true" : "false"; }
|
||||||
|
void Char(int8_t x, const char *name) { Named(x, name); }
|
||||||
|
void UChar(uint8_t x, const char *name) { Named(x, name); }
|
||||||
|
void Short(int16_t x, const char *name) { Named(x, name); }
|
||||||
|
void UShort(uint16_t x, const char *name) { Named(x, name); }
|
||||||
|
void Int(int32_t x, const char *name) { Named(x, name); }
|
||||||
|
void UInt(uint32_t x, const char *name) { Named(x, name); }
|
||||||
|
void Long(int64_t x) { s+= NumToString(x); }
|
||||||
|
void ULong(uint64_t x) { s+= NumToString(x); }
|
||||||
|
void Float(float x) { s+= NumToString(x); }
|
||||||
|
void Double(double x) { s+= NumToString(x); }
|
||||||
|
void String(const struct String *str) {
|
||||||
|
EscapeString(str->c_str(), str->size(), &s, true);
|
||||||
|
}
|
||||||
|
void Unknown(const uint8_t *) { s += "(?)"; }
|
||||||
|
void StartVector() { s += "[ "; }
|
||||||
|
void EndVector() { s += " ]"; }
|
||||||
|
void Element(size_t i, ElementaryType /*type*/,
|
||||||
|
const TypeTable * /*type_table*/, const uint8_t * /*val*/) {
|
||||||
|
if (i) s += ", ";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::string FlatBufferToString(const uint8_t *buffer,
|
||||||
|
const TypeTable *type_table) {
|
||||||
|
ToStringVisitor tostring_visitor;
|
||||||
|
IterateFlatBuffer(buffer, type_table, &tostring_visitor);
|
||||||
|
return tostring_visitor.s;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
#endif // FLATBUFFERS_MINIREFLECT_H_
|
||||||
@@ -605,6 +605,120 @@ inline void EquipmentUnion::Reset() {
|
|||||||
type = Equipment_NONE;
|
type = Equipment_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *Vec3TypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *MonsterTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *WeaponTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *ColorTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
ColorTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"Red",
|
||||||
|
"Green",
|
||||||
|
"Blue"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *EquipmentTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, -1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 0 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
WeaponTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"NONE",
|
||||||
|
"Weapon"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_UNION, 2, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *Vec3TypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 }
|
||||||
|
};
|
||||||
|
static const int32_t values[] = { 0, 4, 8, 12 };
|
||||||
|
static const char *names[] = {
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"z"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_STRUCT, 3, type_codes, nullptr, values, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *MonsterTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||||
|
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_STRING, 0, -1 },
|
||||||
|
{ flatbuffers::ET_BOOL, 0, -1 },
|
||||||
|
{ flatbuffers::ET_UCHAR, 1, -1 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 1, 2 },
|
||||||
|
{ flatbuffers::ET_UTYPE, 0, 3 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 3 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
Vec3TypeTable,
|
||||||
|
ColorTypeTable,
|
||||||
|
WeaponTypeTable,
|
||||||
|
EquipmentTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"pos",
|
||||||
|
"mana",
|
||||||
|
"hp",
|
||||||
|
"name",
|
||||||
|
"friendly",
|
||||||
|
"inventory",
|
||||||
|
"color",
|
||||||
|
"weapons",
|
||||||
|
"equipped_type",
|
||||||
|
"equipped"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 10, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *WeaponTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_STRING, 0, -1 },
|
||||||
|
{ flatbuffers::ET_SHORT, 0, -1 }
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"name",
|
||||||
|
"damage"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 2, type_codes, nullptr, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
inline const MyGame::Sample::Monster *GetMonster(const void *buf) {
|
inline const MyGame::Sample::Monster *GetMonster(const void *buf) {
|
||||||
return flatbuffers::GetRoot<MyGame::Sample::Monster>(buf);
|
return flatbuffers::GetRoot<MyGame::Sample::Monster>(buf);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ std::string FlatCompiler::GetUsageString(const char* program_name) const {
|
|||||||
" --keep-prefix Keep original prefix of schema include statement.\n"
|
" --keep-prefix Keep original prefix of schema include statement.\n"
|
||||||
" --no-fb-import Don't include flatbuffers import statement for TypeScript.\n"
|
" --no-fb-import Don't include flatbuffers import statement for TypeScript.\n"
|
||||||
" --no-ts-reexport Don't re-export imported dependencies for TypeScript.\n"
|
" --no-ts-reexport Don't re-export imported dependencies for TypeScript.\n"
|
||||||
|
" --reflect-types Add minimal type reflection to code generation.\n"
|
||||||
|
" --reflect-names Add minimal type/name reflection.\n"
|
||||||
"FILEs may be schemas (must end in .fbs), or JSON files (conforming to preceding\n"
|
"FILEs may be schemas (must end in .fbs), or JSON files (conforming to preceding\n"
|
||||||
"schema). FILEs after the -- must be binary flatbuffer format files.\n"
|
"schema). FILEs after the -- must be binary flatbuffer format files.\n"
|
||||||
"Output files are named using the base file name of the input,\n"
|
"Output files are named using the base file name of the input,\n"
|
||||||
@@ -243,6 +245,10 @@ int FlatCompiler::Compile(int argc, const char** argv) {
|
|||||||
opts.skip_flatbuffers_import = true;
|
opts.skip_flatbuffers_import = true;
|
||||||
} else if(arg == "--no-ts-reexport") {
|
} else if(arg == "--no-ts-reexport") {
|
||||||
opts.reexport_ts_modules = false;
|
opts.reexport_ts_modules = false;
|
||||||
|
} else if(arg == "--reflect-types") {
|
||||||
|
opts.mini_reflect = IDLOptions::kTypes;
|
||||||
|
} else if(arg == "--reflect-names") {
|
||||||
|
opts.mini_reflect = IDLOptions::kTypesAndNames;
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < params_.num_generators; ++i) {
|
for (size_t i = 0; i < params_.num_generators; ++i) {
|
||||||
if (arg == params_.generators[i].generator_opt_long ||
|
if (arg == params_.generators[i].generator_opt_long ||
|
||||||
|
|||||||
@@ -169,6 +169,37 @@ class CppGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate code for mini reflection.
|
||||||
|
if (parser_.opts.mini_reflect != IDLOptions::kNone) {
|
||||||
|
// To break cyclic dependencies, first pre-declare all tables/structs.
|
||||||
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
|
const auto &struct_def = **it;
|
||||||
|
if (!struct_def.generated) {
|
||||||
|
SetNameSpace(struct_def.defined_namespace);
|
||||||
|
GenMiniReflectPre(&struct_def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Then the unions/enums that may refer to them.
|
||||||
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
|
++it) {
|
||||||
|
const auto &enum_def = **it;
|
||||||
|
if (!enum_def.generated) {
|
||||||
|
SetNameSpace(enum_def.defined_namespace);
|
||||||
|
GenMiniReflect(nullptr, &enum_def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Then the full tables/structs.
|
||||||
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
|
const auto &struct_def = **it;
|
||||||
|
if (!struct_def.generated) {
|
||||||
|
SetNameSpace(struct_def.defined_namespace);
|
||||||
|
GenMiniReflect(&struct_def, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Generate convenient global helper functions:
|
// Generate convenient global helper functions:
|
||||||
if (parser_.root_struct_def_) {
|
if (parser_.root_struct_def_) {
|
||||||
auto &struct_def = *parser_.root_struct_def_;
|
auto &struct_def = *parser_.root_struct_def_;
|
||||||
@@ -559,6 +590,140 @@ class CppGenerator : public BaseGenerator {
|
|||||||
(inclass ? " = nullptr" : "") + ") const";
|
(inclass ? " = nullptr" : "") + ") const";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenMiniReflectPre(const StructDef *struct_def) {
|
||||||
|
code_.SetValue("NAME", struct_def->name);
|
||||||
|
code_ += "flatbuffers::TypeTable *{{NAME}}TypeTable();";
|
||||||
|
code_ += "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenMiniReflect(const StructDef *struct_def,
|
||||||
|
const EnumDef *enum_def) {
|
||||||
|
code_.SetValue("NAME", struct_def ? struct_def->name : enum_def->name);
|
||||||
|
code_.SetValue("SEQ_TYPE", struct_def
|
||||||
|
? (struct_def->fixed ? "ST_STRUCT" : "ST_TABLE")
|
||||||
|
: (enum_def->is_union ? "ST_UNION" : "ST_ENUM"));
|
||||||
|
auto num_fields = struct_def
|
||||||
|
? struct_def->fields.vec.size()
|
||||||
|
: enum_def->vals.vec.size();
|
||||||
|
code_.SetValue("NUM_FIELDS", NumToString(num_fields));
|
||||||
|
std::vector<std::string> names;
|
||||||
|
std::vector<Type> types;
|
||||||
|
bool consecutive_enum_from_zero = true;
|
||||||
|
if (struct_def) {
|
||||||
|
for (auto it = struct_def->fields.vec.begin();
|
||||||
|
it != struct_def->fields.vec.end(); ++it) {
|
||||||
|
const auto &field = **it;
|
||||||
|
names.push_back(field.name);
|
||||||
|
types.push_back(field.value.type);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (auto it = enum_def->vals.vec.begin(); it != enum_def->vals.vec.end();
|
||||||
|
++it) {
|
||||||
|
const auto &ev = **it;
|
||||||
|
names.push_back(ev.name);
|
||||||
|
types.push_back(enum_def->is_union ? ev.union_type
|
||||||
|
: Type(enum_def->underlying_type));
|
||||||
|
if (static_cast<int64_t>(it - enum_def->vals.vec.begin()) != ev.value) {
|
||||||
|
consecutive_enum_from_zero = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string ts;
|
||||||
|
std::vector<std::string> type_refs;
|
||||||
|
for (auto it = types.begin(); it != types.end(); ++it) {
|
||||||
|
auto &type = *it;
|
||||||
|
if (!ts.empty()) ts += ",\n ";
|
||||||
|
auto is_vector = type.base_type == BASE_TYPE_VECTOR;
|
||||||
|
auto bt = is_vector ? type.element : type.base_type;
|
||||||
|
auto et = IsScalar(bt) || bt == BASE_TYPE_STRING
|
||||||
|
? bt - BASE_TYPE_UTYPE + ET_UTYPE
|
||||||
|
: ET_SEQUENCE;
|
||||||
|
int ref_idx = -1;
|
||||||
|
std::string ref_name = type.struct_def
|
||||||
|
? WrapInNameSpace(*type.struct_def)
|
||||||
|
: type.enum_def
|
||||||
|
? WrapInNameSpace(*type.enum_def)
|
||||||
|
: "";
|
||||||
|
if (!ref_name.empty()) {
|
||||||
|
auto rit = type_refs.begin();
|
||||||
|
for (; rit != type_refs.end(); ++rit) {
|
||||||
|
if (*rit == ref_name) {
|
||||||
|
ref_idx = static_cast<int>(rit - type_refs.begin());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rit == type_refs.end()) {
|
||||||
|
ref_idx = static_cast<int>(type_refs.size());
|
||||||
|
type_refs.push_back(ref_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ts += "{ flatbuffers::" + std::string(ElementaryTypeNames()[et]) + ", " +
|
||||||
|
NumToString(is_vector) + ", " + NumToString(ref_idx) + " }";
|
||||||
|
}
|
||||||
|
std::string rs;
|
||||||
|
for (auto it = type_refs.begin(); it != type_refs.end(); ++it) {
|
||||||
|
if (!rs.empty()) rs += ",\n ";
|
||||||
|
rs += *it + "TypeTable";
|
||||||
|
}
|
||||||
|
std::string ns;
|
||||||
|
for (auto it = names.begin(); it != names.end(); ++it) {
|
||||||
|
if (!ns.empty()) ns += ",\n ";
|
||||||
|
ns += "\"" + *it + "\"";
|
||||||
|
}
|
||||||
|
std::string vs;
|
||||||
|
if (enum_def && !consecutive_enum_from_zero) {
|
||||||
|
for (auto it = enum_def->vals.vec.begin(); it != enum_def->vals.vec.end();
|
||||||
|
++it) {
|
||||||
|
const auto &ev = **it;
|
||||||
|
if (!vs.empty()) vs += ", ";
|
||||||
|
vs += NumToString(ev.value);
|
||||||
|
}
|
||||||
|
} else if (struct_def && struct_def->fixed) {
|
||||||
|
for (auto it = struct_def->fields.vec.begin();
|
||||||
|
it != struct_def->fields.vec.end(); ++it) {
|
||||||
|
const auto &field = **it;
|
||||||
|
vs += NumToString(field.value.offset);
|
||||||
|
vs += ", ";
|
||||||
|
}
|
||||||
|
vs += NumToString(struct_def->bytesize);
|
||||||
|
}
|
||||||
|
code_.SetValue("TYPES", ts);
|
||||||
|
code_.SetValue("REFS", rs);
|
||||||
|
code_.SetValue("NAMES", ns);
|
||||||
|
code_.SetValue("VALUES", vs);
|
||||||
|
code_ += "flatbuffers::TypeTable *{{NAME}}TypeTable() {";
|
||||||
|
if (num_fields) {
|
||||||
|
code_ += " static flatbuffers::TypeCode type_codes[] = {";
|
||||||
|
code_ += " {{TYPES}}";
|
||||||
|
code_ += " };";
|
||||||
|
}
|
||||||
|
if (!type_refs.empty()) {
|
||||||
|
code_ += " static flatbuffers::TypeFunction type_refs[] = {";
|
||||||
|
code_ += " {{REFS}}";
|
||||||
|
code_ += " };";
|
||||||
|
}
|
||||||
|
if (!vs.empty()) {
|
||||||
|
code_ += " static const int32_t values[] = { {{VALUES}} };";
|
||||||
|
}
|
||||||
|
auto has_names = num_fields &&
|
||||||
|
parser_.opts.mini_reflect == IDLOptions::kTypesAndNames;
|
||||||
|
if (has_names) {
|
||||||
|
code_ += " static const char *names[] = {";
|
||||||
|
code_ += " {{NAMES}}";
|
||||||
|
code_ += " };";
|
||||||
|
}
|
||||||
|
code_ += " static flatbuffers::TypeTable tt = {";
|
||||||
|
code_ += std::string(" flatbuffers::{{SEQ_TYPE}}, {{NUM_FIELDS}}, ") +
|
||||||
|
(num_fields ? "type_codes, " : "nullptr, ") +
|
||||||
|
(!type_refs.empty() ? "type_refs, ": "nullptr, " ) +
|
||||||
|
(!vs.empty() ? "values, " : "nullptr, ") +
|
||||||
|
(has_names ? "names" : "nullptr");
|
||||||
|
code_ += " };";
|
||||||
|
code_ += " return &tt;";
|
||||||
|
code_ += "}";
|
||||||
|
code_ += "";
|
||||||
|
}
|
||||||
|
|
||||||
// Generate an enum declaration,
|
// Generate an enum declaration,
|
||||||
// an enum string lookup table,
|
// an enum string lookup table,
|
||||||
// and an enum array of values
|
// and an enum array of values
|
||||||
|
|||||||
@@ -15,9 +15,9 @@
|
|||||||
set buildtype=Release
|
set buildtype=Release
|
||||||
if "%1"=="-b" set buildtype=%2
|
if "%1"=="-b" set buildtype=%2
|
||||||
|
|
||||||
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
|
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --reflect-names --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
|
||||||
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --ts --php --gen-mutable --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --ts --php --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
||||||
..\%buildtype%\flatc.exe --cpp --js --ts --php --gen-mutable --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
|
..\%buildtype%\flatc.exe --cpp --js --ts --php --gen-mutable --reflect-names --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
|
||||||
..\%buildtype%\flatc.exe -b --schema --bfbs-comments -I include_test monster_test.fbs
|
..\%buildtype%\flatc.exe -b --schema --bfbs-comments -I include_test monster_test.fbs
|
||||||
..\%buildtype%\flatc.exe --jsonschema --schema -I include_test monster_test.fbs
|
..\%buildtype%\flatc.exe --jsonschema --schema -I include_test monster_test.fbs
|
||||||
cd ../samples
|
cd ../samples
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
../flatc --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
|
../flatc --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --reflect-names --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
|
||||||
../flatc --cpp --java --csharp --go --binary --python --js --ts --php --gen-mutable --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
../flatc --cpp --java --csharp --go --binary --python --js --ts --php --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
||||||
../flatc --cpp --js --ts --php --gen-mutable --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
|
../flatc --cpp --js --ts --php --gen-mutable --reflect-names --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
|
||||||
../flatc -b --schema --bfbs-comments -I include_test monster_test.fbs
|
../flatc -b --schema --bfbs-comments -I include_test monster_test.fbs
|
||||||
../flatc --jsonschema --schema -I include_test monster_test.fbs
|
../flatc --jsonschema --schema -I include_test monster_test.fbs
|
||||||
cd ../samples
|
cd ../samples
|
||||||
../flatc --cpp --gen-mutable --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
|
../flatc --cpp --gen-mutable --reflect-names --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
|
||||||
cd ../reflection
|
cd ../reflection
|
||||||
|
|||||||
Binary file not shown.
@@ -1899,6 +1899,318 @@ inline void AnyUnion::Reset() {
|
|||||||
type = Any_NONE;
|
type = Any_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Example
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *InParentNamespaceTypeTable();
|
||||||
|
|
||||||
|
namespace Example2 {
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *MonsterTypeTable();
|
||||||
|
|
||||||
|
} // namespace Example2
|
||||||
|
|
||||||
|
namespace Example {
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *TestTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *Vec3TypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *AbilityTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *StatTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *MonsterTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *TypeAliasesTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *ColorTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
ColorTypeTable
|
||||||
|
};
|
||||||
|
static const int32_t values[] = { 1, 2, 8 };
|
||||||
|
static const char *names[] = {
|
||||||
|
"Red",
|
||||||
|
"Green",
|
||||||
|
"Blue"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_ENUM, 3, type_codes, type_refs, values, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *AnyTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, -1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 2 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
MonsterTypeTable,
|
||||||
|
TestSimpleTableWithEnumTypeTable,
|
||||||
|
MyGame::Example2::MonsterTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"NONE",
|
||||||
|
"Monster",
|
||||||
|
"TestSimpleTableWithEnum",
|
||||||
|
"MyGame_Example2_Monster"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Example
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *InParentNamespaceTypeTable() {
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Example2 {
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *MonsterTypeTable() {
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Example2
|
||||||
|
|
||||||
|
namespace Example {
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *TestTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, -1 }
|
||||||
|
};
|
||||||
|
static const int32_t values[] = { 0, 2, 4 };
|
||||||
|
static const char *names[] = {
|
||||||
|
"a",
|
||||||
|
"b"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
ColorTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"color"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *Vec3TypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_DOUBLE, 0, -1 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 1 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
ColorTypeTable,
|
||||||
|
TestTypeTable
|
||||||
|
};
|
||||||
|
static const int32_t values[] = { 0, 4, 8, 16, 24, 26, 32 };
|
||||||
|
static const char *names[] = {
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"z",
|
||||||
|
"test1",
|
||||||
|
"test2",
|
||||||
|
"test3"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_STRUCT, 6, type_codes, type_refs, values, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *AbilityTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_UINT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_UINT, 0, -1 }
|
||||||
|
};
|
||||||
|
static const int32_t values[] = { 0, 4, 8 };
|
||||||
|
static const char *names[] = {
|
||||||
|
"id",
|
||||||
|
"distance"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *StatTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_STRING, 0, -1 },
|
||||||
|
{ flatbuffers::ET_LONG, 0, -1 },
|
||||||
|
{ flatbuffers::ET_USHORT, 0, -1 }
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"id",
|
||||||
|
"val",
|
||||||
|
"count"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 3, type_codes, nullptr, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *MonsterTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||||
|
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_STRING, 0, -1 },
|
||||||
|
{ flatbuffers::ET_BOOL, 0, -1 },
|
||||||
|
{ flatbuffers::ET_UCHAR, 1, -1 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 1 },
|
||||||
|
{ flatbuffers::ET_UTYPE, 0, 2 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 2 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 1, 3 },
|
||||||
|
{ flatbuffers::ET_STRING, 1, -1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 1, 4 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 4 },
|
||||||
|
{ flatbuffers::ET_UCHAR, 1, -1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 5 },
|
||||||
|
{ flatbuffers::ET_BOOL, 0, -1 },
|
||||||
|
{ flatbuffers::ET_INT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_UINT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_LONG, 0, -1 },
|
||||||
|
{ flatbuffers::ET_ULONG, 0, -1 },
|
||||||
|
{ flatbuffers::ET_INT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_UINT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_LONG, 0, -1 },
|
||||||
|
{ flatbuffers::ET_ULONG, 0, -1 },
|
||||||
|
{ flatbuffers::ET_BOOL, 1, -1 },
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_STRING, 1, -1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 1, 6 },
|
||||||
|
{ flatbuffers::ET_UCHAR, 1, -1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 1, 3 },
|
||||||
|
{ flatbuffers::ET_LONG, 1, -1 },
|
||||||
|
{ flatbuffers::ET_DOUBLE, 1, -1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 7 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
Vec3TypeTable,
|
||||||
|
ColorTypeTable,
|
||||||
|
AnyTypeTable,
|
||||||
|
TestTypeTable,
|
||||||
|
MonsterTypeTable,
|
||||||
|
StatTypeTable,
|
||||||
|
AbilityTypeTable,
|
||||||
|
MyGame::InParentNamespaceTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"pos",
|
||||||
|
"mana",
|
||||||
|
"hp",
|
||||||
|
"name",
|
||||||
|
"friendly",
|
||||||
|
"inventory",
|
||||||
|
"color",
|
||||||
|
"test_type",
|
||||||
|
"test",
|
||||||
|
"test4",
|
||||||
|
"testarrayofstring",
|
||||||
|
"testarrayoftables",
|
||||||
|
"enemy",
|
||||||
|
"testnestedflatbuffer",
|
||||||
|
"testempty",
|
||||||
|
"testbool",
|
||||||
|
"testhashs32_fnv1",
|
||||||
|
"testhashu32_fnv1",
|
||||||
|
"testhashs64_fnv1",
|
||||||
|
"testhashu64_fnv1",
|
||||||
|
"testhashs32_fnv1a",
|
||||||
|
"testhashu32_fnv1a",
|
||||||
|
"testhashs64_fnv1a",
|
||||||
|
"testhashu64_fnv1a",
|
||||||
|
"testarrayofbools",
|
||||||
|
"testf",
|
||||||
|
"testf2",
|
||||||
|
"testf3",
|
||||||
|
"testarrayofstring2",
|
||||||
|
"testarrayofsortedstruct",
|
||||||
|
"flex",
|
||||||
|
"test5",
|
||||||
|
"vector_of_longs",
|
||||||
|
"vector_of_doubles",
|
||||||
|
"parent_namespace_test"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 35, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *TypeAliasesTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_CHAR, 0, -1 },
|
||||||
|
{ flatbuffers::ET_UCHAR, 0, -1 },
|
||||||
|
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_USHORT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_INT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_UINT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_LONG, 0, -1 },
|
||||||
|
{ flatbuffers::ET_ULONG, 0, -1 },
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_DOUBLE, 0, -1 },
|
||||||
|
{ flatbuffers::ET_CHAR, 1, -1 },
|
||||||
|
{ flatbuffers::ET_DOUBLE, 1, -1 }
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"i8",
|
||||||
|
"u8",
|
||||||
|
"i16",
|
||||||
|
"u16",
|
||||||
|
"i32",
|
||||||
|
"u32",
|
||||||
|
"i64",
|
||||||
|
"u64",
|
||||||
|
"f32",
|
||||||
|
"f64",
|
||||||
|
"v8",
|
||||||
|
"vf64"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 12, type_codes, nullptr, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
inline const MyGame::Example::Monster *GetMonster(const void *buf) {
|
inline const MyGame::Example::Monster *GetMonster(const void *buf) {
|
||||||
return flatbuffers::GetRoot<MyGame::Example::Monster>(buf);
|
return flatbuffers::GetRoot<MyGame::Example::Monster>(buf);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,6 +119,59 @@ inline flatbuffers::Offset<TableInNestedNS> CreateTableInNestedNS(
|
|||||||
return builder_.Finish();
|
return builder_.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *TableInNestedNSTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *StructInNestedNSTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *EnumInNestedNSTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
EnumInNestedNSTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"A",
|
||||||
|
"B",
|
||||||
|
"C"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *TableInNestedNSTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_INT, 0, -1 }
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"foo"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *StructInNestedNSTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_INT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_INT, 0, -1 }
|
||||||
|
};
|
||||||
|
static const int32_t values[] = { 0, 4, 8 };
|
||||||
|
static const char *names[] = {
|
||||||
|
"a",
|
||||||
|
"b"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace NamespaceB
|
} // namespace NamespaceB
|
||||||
} // namespace NamespaceA
|
} // namespace NamespaceA
|
||||||
|
|
||||||
|
|||||||
@@ -212,6 +212,85 @@ namespace NamespaceC {
|
|||||||
|
|
||||||
namespace NamespaceA {
|
namespace NamespaceA {
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *TableInFirstNSTypeTable();
|
||||||
|
|
||||||
|
} // namespace NamespaceA
|
||||||
|
|
||||||
|
namespace NamespaceC {
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *TableInCTypeTable();
|
||||||
|
|
||||||
|
} // namespace NamespaceC
|
||||||
|
|
||||||
|
namespace NamespaceA {
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *SecondTableInATypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *TableInFirstNSTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 2 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
NamespaceA::NamespaceB::TableInNestedNSTypeTable,
|
||||||
|
NamespaceA::NamespaceB::EnumInNestedNSTypeTable,
|
||||||
|
NamespaceA::NamespaceB::StructInNestedNSTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"foo_table",
|
||||||
|
"foo_enum",
|
||||||
|
"foo_struct"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 3, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace NamespaceA
|
||||||
|
|
||||||
|
namespace NamespaceC {
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *TableInCTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 1 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
NamespaceA::TableInFirstNSTypeTable,
|
||||||
|
NamespaceA::SecondTableInATypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"refer_to_a1",
|
||||||
|
"refer_to_a2"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 2, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace NamespaceC
|
||||||
|
|
||||||
|
namespace NamespaceA {
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *SecondTableInATypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 0 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
NamespaceC::TableInCTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"refer_to_c"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace NamespaceA
|
} // namespace NamespaceA
|
||||||
|
|
||||||
#endif // FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
|
#endif // FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "flatbuffers/idl.h"
|
#include "flatbuffers/idl.h"
|
||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
#include "flatbuffers/registry.h"
|
#include "flatbuffers/registry.h"
|
||||||
|
#include "flatbuffers/minireflect.h"
|
||||||
|
|
||||||
#include "monster_test_generated.h"
|
#include "monster_test_generated.h"
|
||||||
#include "namespace_test/namespace_test1_generated.h"
|
#include "namespace_test/namespace_test1_generated.h"
|
||||||
@@ -46,8 +47,9 @@ int testing_fails = 0;
|
|||||||
|
|
||||||
void TestFail(const char *expval, const char *val, const char *exp,
|
void TestFail(const char *expval, const char *val, const char *exp,
|
||||||
const char *file, int line) {
|
const char *file, int line) {
|
||||||
TEST_OUTPUT_LINE("TEST FAILED: %s:%d, %s (%s) != %s", file, line,
|
TEST_OUTPUT_LINE("VALUE: \"%s\"", expval);
|
||||||
exp, expval, val);
|
TEST_OUTPUT_LINE("EXPECTED: \"%s\"", val);
|
||||||
|
TEST_OUTPUT_LINE("TEST FAILED: %s:%d, %s", file, line, exp);
|
||||||
assert(0);
|
assert(0);
|
||||||
testing_fails++;
|
testing_fails++;
|
||||||
}
|
}
|
||||||
@@ -561,11 +563,7 @@ void ParseAndGenerateTextTest() {
|
|||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_EQ(result, true);
|
||||||
|
TEST_EQ_STR(jsongen.c_str(), jsonfile.c_str());
|
||||||
if (jsongen != jsonfile) {
|
|
||||||
TEST_OUTPUT_LINE("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str());
|
|
||||||
TEST_NOTNULL(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can also do the above using the convenient Registry that knows about
|
// We can also do the above using the convenient Registry that knows about
|
||||||
// a set of file_identifiers mapped to schemas.
|
// a set of file_identifiers mapped to schemas.
|
||||||
@@ -772,6 +770,34 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) {
|
|||||||
fbb.GetBufferPointer(), fbb.GetSize()), true);
|
fbb.GetBufferPointer(), fbb.GetSize()), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
|
||||||
|
auto s = flatbuffers::FlatBufferToString(flatbuf, MonsterTypeTable());
|
||||||
|
TEST_EQ_STR(s.c_str(),
|
||||||
|
"{ "
|
||||||
|
"pos: { x: 1.0, y: 2.0, z: 3.0, test1: 0.0, test2: Red, test3: "
|
||||||
|
"{ a: 10, b: 20 } }, "
|
||||||
|
"hp: 80, "
|
||||||
|
"name: \"MyMonster\", "
|
||||||
|
"inventory: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], "
|
||||||
|
"test_type: Monster, "
|
||||||
|
"test: { name: \"Fred\" }, "
|
||||||
|
"test4: [ { a: 10, b: 20 }, { a: 30, b: 40 } ], "
|
||||||
|
"testarrayofstring: [ \"bob\", \"fred\", \"bob\", \"fred\" ], "
|
||||||
|
"testarrayoftables: [ { hp: 1000, name: \"Barney\" }, { name: \"Fred\" }, "
|
||||||
|
"{ name: \"Wilma\" } ], "
|
||||||
|
// TODO(wvo): should really print this nested buffer correctly.
|
||||||
|
"testnestedflatbuffer: [ 20, 0, 0, 0, 77, 79, 78, 83, 12, 0, 12, 0, 0, 0, "
|
||||||
|
"4, 0, 6, 0, 8, 0, 12, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 78, "
|
||||||
|
"101, 115, 116, 101, 100, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0 ], "
|
||||||
|
"testarrayofstring2: [ \"jane\", \"mary\" ], "
|
||||||
|
"testarrayofsortedstruct: [ { id: 1, distance: 10 }, "
|
||||||
|
"{ id: 2, distance: 20 }, { id: 3, distance: 30 }, "
|
||||||
|
"{ id: 4, distance: 40 } ], "
|
||||||
|
"flex: [ 210, 4, 5, 2 ], "
|
||||||
|
"test5: [ { a: 10, b: 20 }, { a: 30, b: 40 } ] "
|
||||||
|
"}");
|
||||||
|
}
|
||||||
|
|
||||||
// Parse a .proto schema, output as .fbs
|
// Parse a .proto schema, output as .fbs
|
||||||
void ParseProtoTest() {
|
void ParseProtoTest() {
|
||||||
// load the .proto and the golden file from disk
|
// load the .proto and the golden file from disk
|
||||||
@@ -800,11 +826,7 @@ void ParseProtoTest() {
|
|||||||
// Ensure generated file is parsable.
|
// Ensure generated file is parsable.
|
||||||
flatbuffers::Parser parser2;
|
flatbuffers::Parser parser2;
|
||||||
TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
|
TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
|
||||||
|
TEST_EQ_STR(fbs.c_str(), goldenfile.c_str());
|
||||||
if (fbs != goldenfile) {
|
|
||||||
TEST_OUTPUT_LINE("%s----------------\n%s", fbs.c_str(), goldenfile.c_str());
|
|
||||||
TEST_NOTNULL(NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> void CompareTableFieldValue(flatbuffers::Table *table,
|
template<typename T> void CompareTableFieldValue(flatbuffers::Table *table,
|
||||||
@@ -1248,10 +1270,9 @@ void UnicodeTest() {
|
|||||||
parser.opts.indent_step = -1;
|
parser.opts.indent_step = -1;
|
||||||
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_EQ(result, true);
|
||||||
TEST_EQ(jsongen,
|
TEST_EQ_STR(jsongen.c_str(),
|
||||||
std::string(
|
|
||||||
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
||||||
"\\u5225\\u30B5\\u30A4\\u30C8\\u20AC\\u0080\\uD83D\\uDE0E\"}"));
|
"\\u5225\\u30B5\\u30A4\\u30C8\\u20AC\\u0080\\uD83D\\uDE0E\"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnicodeTestAllowNonUTF8() {
|
void UnicodeTestAllowNonUTF8() {
|
||||||
@@ -1265,10 +1286,9 @@ void UnicodeTestAllowNonUTF8() {
|
|||||||
parser.opts.indent_step = -1;
|
parser.opts.indent_step = -1;
|
||||||
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_EQ(result, true);
|
||||||
TEST_EQ(jsongen,
|
TEST_EQ_STR(jsongen.c_str(),
|
||||||
std::string(
|
|
||||||
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
||||||
"\\u5225\\u30B5\\u30A4\\u30C8\\u0001\\x80\\u0080\\uD83D\\uDE0E\"}"));
|
"\\u5225\\u30B5\\u30A4\\u30C8\\u0001\\x80\\u0080\\uD83D\\uDE0E\"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnicodeTestGenerateTextFailsOnNonUTF8() {
|
void UnicodeTestGenerateTextFailsOnNonUTF8() {
|
||||||
@@ -1300,7 +1320,7 @@ void UnicodeSurrogatesTest() {
|
|||||||
parser.builder_.GetBufferPointer());
|
parser.builder_.GetBufferPointer());
|
||||||
auto string = root->GetPointer<flatbuffers::String *>(
|
auto string = root->GetPointer<flatbuffers::String *>(
|
||||||
flatbuffers::FieldIndexToOffset(0));
|
flatbuffers::FieldIndexToOffset(0));
|
||||||
TEST_EQ(strcmp(string->c_str(), "\xF0\x9F\x92\xA9"), 0);
|
TEST_EQ_STR(string->c_str(), "\xF0\x9F\x92\xA9");
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnicodeInvalidSurrogatesTest() {
|
void UnicodeInvalidSurrogatesTest() {
|
||||||
@@ -1437,7 +1457,7 @@ void UnknownFieldsTest() {
|
|||||||
parser.opts.indent_step = -1;
|
parser.opts.indent_step = -1;
|
||||||
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_EQ(result, true);
|
||||||
TEST_EQ(jsongen == "{str: \"test\",i: 10}", true);
|
TEST_EQ_STR(jsongen.c_str(), "{str: \"test\",i: 10}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParseUnionTest() {
|
void ParseUnionTest() {
|
||||||
@@ -1548,6 +1568,14 @@ void UnionVectorTest() {
|
|||||||
auto repacked_movie = GetMovie(fbb.GetBufferPointer());
|
auto repacked_movie = GetMovie(fbb.GetBufferPointer());
|
||||||
|
|
||||||
TestMovie(repacked_movie);
|
TestMovie(repacked_movie);
|
||||||
|
|
||||||
|
auto s = flatbuffers::FlatBufferToString(fbb.GetBufferPointer(),
|
||||||
|
MovieTypeTable());
|
||||||
|
TEST_EQ_STR(s.c_str(),
|
||||||
|
"{ main_character_type: Rapunzel, main_character: { hair_length: 6 }, "
|
||||||
|
"characters_type: [ Belle, MuLan, BookFan, Other, Unused ], "
|
||||||
|
"characters: [ { books_read: 7 }, { sword_attack_damage: 5 }, "
|
||||||
|
"{ books_read: 2 }, \"Other\", \"Unused\" ] }");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConformTest() {
|
void ConformTest() {
|
||||||
@@ -1774,6 +1802,8 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
|
|
||||||
ObjectFlatBuffersTest(flatbuf.data());
|
ObjectFlatBuffersTest(flatbuf.data());
|
||||||
|
|
||||||
|
MiniReflectFlatBuffersTest(flatbuf.data());
|
||||||
|
|
||||||
SizePrefixedTest();
|
SizePrefixedTest();
|
||||||
|
|
||||||
#ifndef FLATBUFFERS_NO_FILE_TESTS
|
#ifndef FLATBUFFERS_NO_FILE_TESTS
|
||||||
|
|||||||
@@ -600,6 +600,107 @@ inline void CharacterUnion::Reset() {
|
|||||||
type = Character_NONE;
|
type = Character_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *AttackerTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *RapunzelTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *BookReaderTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *MovieTypeTable();
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *CharacterTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, -1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 2 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 2 },
|
||||||
|
{ flatbuffers::ET_STRING, 0, -1 },
|
||||||
|
{ flatbuffers::ET_STRING, 0, -1 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
AttackerTypeTable,
|
||||||
|
RapunzelTypeTable,
|
||||||
|
BookReaderTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"NONE",
|
||||||
|
"MuLan",
|
||||||
|
"Rapunzel",
|
||||||
|
"Belle",
|
||||||
|
"BookFan",
|
||||||
|
"Other",
|
||||||
|
"Unused"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_UNION, 7, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *AttackerTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_INT, 0, -1 }
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"sword_attack_damage"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *RapunzelTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_INT, 0, -1 }
|
||||||
|
};
|
||||||
|
static const int32_t values[] = { 0, 4 };
|
||||||
|
static const char *names[] = {
|
||||||
|
"hair_length"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_STRUCT, 1, type_codes, nullptr, values, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *BookReaderTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_INT, 0, -1 }
|
||||||
|
};
|
||||||
|
static const int32_t values[] = { 0, 4 };
|
||||||
|
static const char *names[] = {
|
||||||
|
"books_read"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_STRUCT, 1, type_codes, nullptr, values, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::TypeTable *MovieTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_UTYPE, 0, 0 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||||
|
{ flatbuffers::ET_UTYPE, 1, 0 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 1, 0 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
CharacterTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"main_character_type",
|
||||||
|
"main_character",
|
||||||
|
"characters_type",
|
||||||
|
"characters"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 4, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
inline const Movie *GetMovie(const void *buf) {
|
inline const Movie *GetMovie(const void *buf) {
|
||||||
return flatbuffers::GetRoot<Movie>(buf);
|
return flatbuffers::GetRoot<Movie>(buf);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user