Merge branch 'master' of github.com:google/flatbuffers
This commit is contained in:
commit
00694d271e
|
@ -288,7 +288,7 @@ public:
|
|||
}
|
||||
|
||||
VectorIterator operator++(int) {
|
||||
VectorIterator temp(data_);
|
||||
VectorIterator temp(data_,0);
|
||||
data_ += IndirectHelper<T>::element_stride;
|
||||
return temp;
|
||||
}
|
||||
|
@ -876,7 +876,7 @@ FLATBUFFERS_FINAL_CLASS
|
|||
/// @param[in] str A const pointer to a `String` struct to add to the buffer.
|
||||
/// @return Returns the offset in the buffer where the string starts
|
||||
Offset<String> CreateString(const String *str) {
|
||||
return CreateString(str->c_str(), str->Length());
|
||||
return str ? CreateString(str->c_str(), str->Length()) : 0;
|
||||
}
|
||||
|
||||
/// @brief Store a string in the buffer, which can contain any binary data.
|
||||
|
@ -1216,6 +1216,9 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
size_t _max_tables = 1000000)
|
||||
: buf_(buf), end_(buf + buf_len), depth_(0), max_depth_(_max_depth),
|
||||
num_tables_(0), max_tables_(_max_tables)
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
, upper_bound_(buf)
|
||||
#endif
|
||||
{}
|
||||
|
||||
// Central location where any verification failures register.
|
||||
|
@ -1223,11 +1226,20 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
#ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
|
||||
assert(ok);
|
||||
#endif
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
if (!ok)
|
||||
upper_bound_ = buf_;
|
||||
#endif
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Verify any range within the buffer.
|
||||
bool Verify(const void *elem, size_t elem_len) const {
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
auto upper_bound = reinterpret_cast<const uint8_t *>(elem) + elem_len;
|
||||
if (upper_bound_ < upper_bound)
|
||||
upper_bound_ = upper_bound;
|
||||
#endif
|
||||
return Check(elem_len <= (size_t) (end_ - buf_) &&
|
||||
elem >= buf_ &&
|
||||
elem <= end_ - elem_len);
|
||||
|
@ -1302,11 +1314,20 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
}
|
||||
|
||||
// Verify this whole buffer, starting with root type T.
|
||||
template<typename T> bool VerifyBuffer() {
|
||||
template<typename T> bool VerifyBuffer(const char *identifier) {
|
||||
if (identifier && (size_t(end_ - buf_) < 2 * sizeof(flatbuffers::uoffset_t) ||
|
||||
!BufferHasIdentifier(buf_, identifier))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Call T::Verify, which must be in the generated code for this type.
|
||||
return Verify<uoffset_t>(buf_) &&
|
||||
reinterpret_cast<const T *>(buf_ + ReadScalar<uoffset_t>(buf_))->
|
||||
Verify(*this);
|
||||
Verify(*this)
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
&& GetComputedSize()
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
// Called at the start of a table to increase counters measuring data
|
||||
|
@ -1325,6 +1346,16 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
// Returns the message size in bytes
|
||||
size_t GetComputedSize() const {
|
||||
uintptr_t size = upper_bound_ - buf_;
|
||||
// Align the size to uoffset_t
|
||||
size = (size - 1 + sizeof(uoffset_t)) & -uintptr_t(sizeof(uoffset_t));
|
||||
return (buf_ + size > end_) ? 0 : size;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
const uint8_t *buf_;
|
||||
const uint8_t *end_;
|
||||
|
@ -1332,6 +1363,9 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
size_t max_depth_;
|
||||
size_t num_tables_;
|
||||
size_t max_tables_;
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
mutable const uint8_t *upper_bound_;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Convenient way to bundle a buffer and its length, to pass it around
|
||||
|
|
|
@ -337,7 +337,8 @@ struct IDLOptions {
|
|||
bool generate_all;
|
||||
bool skip_unexpected_fields_in_json;
|
||||
bool generate_name_strings;
|
||||
|
||||
bool escape_proto_identifiers;
|
||||
|
||||
// Possible options for the more general generator below.
|
||||
enum Language { kJava, kCSharp, kGo, kMAX };
|
||||
|
||||
|
@ -356,6 +357,7 @@ struct IDLOptions {
|
|||
generate_all(false),
|
||||
skip_unexpected_fields_in_json(false),
|
||||
generate_name_strings(false),
|
||||
escape_proto_identifiers(false),
|
||||
lang(IDLOptions::kJava) {}
|
||||
};
|
||||
|
||||
|
|
|
@ -478,12 +478,12 @@ inline flatbuffers::Offset<Schema> CreateSchema(flatbuffers::FlatBufferBuilder &
|
|||
|
||||
inline const reflection::Schema *GetSchema(const void *buf) { return flatbuffers::GetRoot<reflection::Schema>(buf); }
|
||||
|
||||
inline bool VerifySchemaBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<reflection::Schema>(); }
|
||||
|
||||
inline const char *SchemaIdentifier() { return "BFBS"; }
|
||||
|
||||
inline bool SchemaBufferHasIdentifier(const void *buf) { return flatbuffers::BufferHasIdentifier(buf, SchemaIdentifier()); }
|
||||
|
||||
inline bool VerifySchemaBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier()); }
|
||||
|
||||
inline const char *SchemaExtension() { return "bfbs"; }
|
||||
|
||||
inline void FinishSchemaBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<reflection::Schema> root) { fbb.Finish(root, SchemaIdentifier()); }
|
||||
|
|
|
@ -135,15 +135,15 @@ struct MonsterBuilder {
|
|||
};
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const Vec3 *pos = 0,
|
||||
int16_t mana = 150,
|
||||
int16_t hp = 100,
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory = 0,
|
||||
Color color = Color_Blue,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Weapon>>> weapons = 0,
|
||||
Equipment equipped_type = Equipment_NONE,
|
||||
flatbuffers::Offset<void> equipped = 0) {
|
||||
const Vec3 *pos = 0,
|
||||
int16_t mana = 150,
|
||||
int16_t hp = 100,
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory = 0,
|
||||
Color color = Color_Blue,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Weapon>>> weapons = 0,
|
||||
Equipment equipped_type = Equipment_NONE,
|
||||
flatbuffers::Offset<void> equipped = 0) {
|
||||
MonsterBuilder builder_(_fbb);
|
||||
builder_.add_equipped(equipped);
|
||||
builder_.add_weapons(weapons);
|
||||
|
@ -157,6 +157,19 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
|
|||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const Vec3 *pos = 0,
|
||||
int16_t mana = 150,
|
||||
int16_t hp = 100,
|
||||
const char *name = nullptr,
|
||||
const std::vector<uint8_t> *inventory = nullptr,
|
||||
Color color = Color_Blue,
|
||||
const std::vector<flatbuffers::Offset<Weapon>> *weapons = nullptr,
|
||||
Equipment equipped_type = Equipment_NONE,
|
||||
flatbuffers::Offset<void> equipped = 0) {
|
||||
return CreateMonster(_fbb, pos, mana, hp, name ? 0 : _fbb.CreateString(name), inventory ? 0 : _fbb.CreateVector<uint8_t>(*inventory), color, weapons ? 0 : _fbb.CreateVector<flatbuffers::Offset<Weapon>>(*weapons), equipped_type, equipped);
|
||||
}
|
||||
|
||||
struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
enum {
|
||||
VT_NAME = 4,
|
||||
|
@ -189,14 +202,20 @@ struct WeaponBuilder {
|
|||
};
|
||||
|
||||
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||
int16_t damage = 0) {
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||
int16_t damage = 0) {
|
||||
WeaponBuilder builder_(_fbb);
|
||||
builder_.add_name(name);
|
||||
builder_.add_damage(damage);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const char *name = nullptr,
|
||||
int16_t damage = 0) {
|
||||
return CreateWeapon(_fbb, name ? 0 : _fbb.CreateString(name), damage);
|
||||
}
|
||||
|
||||
inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *union_obj, Equipment type) {
|
||||
switch (type) {
|
||||
case Equipment_NONE: return true;
|
||||
|
@ -209,7 +228,7 @@ inline const MyGame::Sample::Monster *GetMonster(const void *buf) { return flatb
|
|||
|
||||
inline Monster *GetMutableMonster(void *buf) { return flatbuffers::GetMutableRoot<Monster>(buf); }
|
||||
|
||||
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<MyGame::Sample::Monster>(); }
|
||||
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<MyGame::Sample::Monster>(nullptr); }
|
||||
|
||||
inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Sample::Monster> root) { fbb.Finish(root); }
|
||||
|
||||
|
|
|
@ -120,8 +120,9 @@ static void Error(const std::string &err, bool usage, bool show_exe_name) {
|
|||
" --no-includes Don\'t generate include statements for included\n"
|
||||
" schemas the generated file depends on (C++).\n"
|
||||
" --gen-mutable Generate accessors that can mutate buffers in-place.\n"
|
||||
" --gen-onefile Generate single output file for C#\n"
|
||||
" --gen-onefile Generate single output file for C#.\n"
|
||||
" --gen-name-strings Generate type name functions for C++.\n"
|
||||
" --escape-proto-ids Disable appending '_' in namespaces names.\n"
|
||||
" --raw-binary Allow binaries without file_indentifier to be read.\n"
|
||||
" This may crash flatc given a mismatched schema.\n"
|
||||
" --proto Input is a .proto, translate to .fbs.\n"
|
||||
|
@ -194,6 +195,8 @@ int main(int argc, const char *argv[]) {
|
|||
binary_files_from = filenames.size();
|
||||
} else if(arg == "--proto") {
|
||||
opts.proto_mode = true;
|
||||
} else if(arg == "--escape-proto-ids") {
|
||||
opts.escape_proto_identifiers = true;
|
||||
} else if(arg == "--schema") {
|
||||
schema_binary = true;
|
||||
} else if(arg == "-M") {
|
||||
|
|
|
@ -39,7 +39,8 @@ class CppGenerator : public BaseGenerator {
|
|||
public:
|
||||
CppGenerator(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name)
|
||||
: BaseGenerator(parser, path, file_name, "", "::"){};
|
||||
: BaseGenerator(parser, path, file_name, "", "::"),
|
||||
cur_name_space_(nullptr){};
|
||||
// Iterate through all definitions we haven't generate code for (enums,
|
||||
// structs,
|
||||
// and tables) and output them to a single file.
|
||||
|
@ -157,14 +158,6 @@ class CppGenerator : public BaseGenerator {
|
|||
code += name + ">(buf); }\n\n";
|
||||
}
|
||||
|
||||
// The root verifier:
|
||||
code += "inline bool Verify";
|
||||
code += name;
|
||||
code +=
|
||||
"Buffer(flatbuffers::Verifier &verifier) { "
|
||||
"return verifier.VerifyBuffer<";
|
||||
code += cpp_qualified_name + ">(); }\n\n";
|
||||
|
||||
if (parser_.file_identifier_.length()) {
|
||||
// Return the identifier
|
||||
code += "inline const char *" + name;
|
||||
|
@ -178,6 +171,20 @@ class CppGenerator : public BaseGenerator {
|
|||
code += name + "Identifier()); }\n\n";
|
||||
}
|
||||
|
||||
// The root verifier:
|
||||
code += "inline bool Verify";
|
||||
code += name;
|
||||
code +=
|
||||
"Buffer(flatbuffers::Verifier &verifier) { "
|
||||
"return verifier.VerifyBuffer<";
|
||||
code += cpp_qualified_name + ">(";
|
||||
if (parser_.file_identifier_.length())
|
||||
code += name + "Identifier()";
|
||||
else
|
||||
code += "nullptr";
|
||||
code += "); }\n\n";
|
||||
|
||||
|
||||
if (parser_.file_extension_.length()) {
|
||||
// Return the extension
|
||||
code += "inline const char *" + name;
|
||||
|
@ -206,7 +213,7 @@ class CppGenerator : public BaseGenerator {
|
|||
|
||||
private:
|
||||
// This tracks the current namespace so we can insert namespace declarations.
|
||||
const Namespace *cur_name_space_ = nullptr;
|
||||
const Namespace *cur_name_space_;
|
||||
|
||||
const Namespace *CurrentNameSpace() { return cur_name_space_; }
|
||||
|
||||
|
@ -457,6 +464,30 @@ class CppGenerator : public BaseGenerator {
|
|||
: field.value.constant;
|
||||
}
|
||||
|
||||
void GenSimpleParam(std::string &code, FieldDef &field) {
|
||||
code += ",\n " + GenTypeWire(field.value.type, " ", true);
|
||||
code += field.name + " = ";
|
||||
if (field.value.type.enum_def && IsScalar(field.value.type.base_type)) {
|
||||
auto ev = field.value.type.enum_def->ReverseLookup(
|
||||
static_cast<int>(StringToInt(field.value.constant.c_str())),
|
||||
false);
|
||||
if (ev) {
|
||||
code += WrapInNameSpace(
|
||||
field.value.type.enum_def->defined_namespace,
|
||||
GetEnumVal(*field.value.type.enum_def, *ev, parser_.opts));
|
||||
}
|
||||
else {
|
||||
code += GenUnderlyingCast(field, true, field.value.constant);
|
||||
}
|
||||
}
|
||||
else if (field.value.type.base_type == BASE_TYPE_BOOL) {
|
||||
code += field.value.constant == "0" ? "false" : "true";
|
||||
}
|
||||
else {
|
||||
code += GenDefaultConstant(field);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate an accessor struct, builder structs & function for a table.
|
||||
void GenTable(StructDef &struct_def, std::string *code_ptr) {
|
||||
std::string &code = *code_ptr;
|
||||
|
@ -679,6 +710,7 @@ class CppGenerator : public BaseGenerator {
|
|||
|
||||
// Generate a convenient CreateX function that uses the above builder
|
||||
// to create a table in one go.
|
||||
bool gen_vector_pars = false;
|
||||
code += "inline flatbuffers::Offset<" + struct_def.name + "> Create";
|
||||
code += struct_def.name;
|
||||
code += "(flatbuffers::FlatBufferBuilder &_fbb";
|
||||
|
@ -686,24 +718,11 @@ class CppGenerator : public BaseGenerator {
|
|||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (!field.deprecated) {
|
||||
code += ",\n " + GenTypeWire(field.value.type, " ", true);
|
||||
code += field.name + " = ";
|
||||
if (field.value.type.enum_def && IsScalar(field.value.type.base_type)) {
|
||||
auto ev = field.value.type.enum_def->ReverseLookup(
|
||||
static_cast<int>(StringToInt(field.value.constant.c_str())),
|
||||
false);
|
||||
if (ev) {
|
||||
code += WrapInNameSpace(
|
||||
field.value.type.enum_def->defined_namespace,
|
||||
GetEnumVal(*field.value.type.enum_def, *ev, parser_.opts));
|
||||
} else {
|
||||
code += GenUnderlyingCast(field, true, field.value.constant);
|
||||
}
|
||||
} else if (field.value.type.base_type == BASE_TYPE_BOOL) {
|
||||
code += field.value.constant == "0" ? "false" : "true";
|
||||
} else {
|
||||
code += GenDefaultConstant(field);
|
||||
if (field.value.type.base_type == BASE_TYPE_STRING ||
|
||||
field.value.type.base_type == BASE_TYPE_VECTOR) {
|
||||
gen_vector_pars = true;
|
||||
}
|
||||
GenSimpleParam(code, field);
|
||||
}
|
||||
}
|
||||
code += ") {\n " + struct_def.name + "Builder builder_(_fbb);\n";
|
||||
|
@ -719,6 +738,50 @@ class CppGenerator : public BaseGenerator {
|
|||
}
|
||||
}
|
||||
code += " return builder_.Finish();\n}\n\n";
|
||||
|
||||
//Generate a CreateX function with vector types as parameters
|
||||
if (gen_vector_pars) {
|
||||
code += "inline flatbuffers::Offset<" + struct_def.name + "> Create";
|
||||
code += struct_def.name;
|
||||
code += "(flatbuffers::FlatBufferBuilder &_fbb";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (!field.deprecated) {
|
||||
if (field.value.type.base_type == BASE_TYPE_STRING) {
|
||||
code += ",\n const char *";
|
||||
code += field.name + " = nullptr";
|
||||
}
|
||||
else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
|
||||
code += ",\n const std::vector<";
|
||||
code += GenTypeWire(field.value.type.VectorType(), "", false);
|
||||
code += "> *" + field.name + " = nullptr";
|
||||
} else {
|
||||
GenSimpleParam(code, field);
|
||||
}
|
||||
}
|
||||
}
|
||||
code += ") {\n ";
|
||||
code += "return Create";
|
||||
code += struct_def.name;
|
||||
code += "(_fbb";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (!field.deprecated) {
|
||||
if (field.value.type.base_type == BASE_TYPE_STRING) {
|
||||
code += ", " + field.name + " ? 0 : ";
|
||||
code += "_fbb.CreateString(" + field.name + ")";
|
||||
} else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
|
||||
code += ", " + field.name + " ? 0 : ";
|
||||
code += "_fbb.CreateVector<";
|
||||
code += GenTypeWire(field.value.type.VectorType(), "", false);
|
||||
code += ">(*" + field.name + ")";
|
||||
} else code += ", " + field.name;
|
||||
}
|
||||
}
|
||||
code += ");\n}\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
static void GenPadding(const FieldDef &field, std::string &code,
|
||||
|
|
|
@ -53,12 +53,14 @@ static void GenNameSpace(const Namespace &name_space, std::string *_schema,
|
|||
|
||||
// Generate a flatbuffer schema from the Parser's internal representation.
|
||||
std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
|
||||
// Proto namespaces may clash with table names, so we have to prefix all:
|
||||
for (auto it = parser.namespaces_.begin(); it != parser.namespaces_.end();
|
||||
++it) {
|
||||
for (auto comp = (*it)->components.begin(); comp != (*it)->components.end();
|
||||
++comp) {
|
||||
(*comp) = "_" + (*comp);
|
||||
// Proto namespaces may clash with table names, so we have to prefix all:
|
||||
if (!parser.opts.escape_proto_identifiers) {
|
||||
for (auto it = parser.namespaces_.begin(); it != parser.namespaces_.end();
|
||||
++it) {
|
||||
for (auto comp = (*it)->components.begin(); comp != (*it)->components.end();
|
||||
++comp) {
|
||||
(*comp) = "_" + (*comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -193,8 +193,9 @@ class GeneralGenerator : public BaseGenerator {
|
|||
public:
|
||||
GeneralGenerator(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name)
|
||||
: BaseGenerator(parser, path, file_name, "", "."){
|
||||
assert(parser_.opts.lang <= IDLOptions::kMAX);
|
||||
: BaseGenerator(parser, path, file_name, "", "."),
|
||||
lang_(language_parameters[parser_.opts.lang]) {
|
||||
assert(parser_.opts.lang <= IDLOptions::kMAX);
|
||||
};
|
||||
bool generate() {
|
||||
std::string one_file_code;
|
||||
|
@ -544,7 +545,7 @@ void GenEnum(EnumDef &enum_def, std::string *code_ptr) {
|
|||
// "too sparse". Change at will.
|
||||
static const int kMaxSparseness = 5;
|
||||
if (range / static_cast<int64_t>(enum_def.vals.vec.size()) < kMaxSparseness) {
|
||||
code += "\n private static";
|
||||
code += "\n public static";
|
||||
code += lang_.const_decl;
|
||||
code += lang_.string_type;
|
||||
code += "[] names = { ";
|
||||
|
@ -567,7 +568,10 @@ void GenEnum(EnumDef &enum_def, std::string *code_ptr) {
|
|||
}
|
||||
|
||||
// Close the class
|
||||
code += "};\n\n";
|
||||
code += "}";
|
||||
// Java does not need the closing semi-colon on class definitions.
|
||||
code += (lang_.language != IDLOptions::kJava) ? ";" : "";
|
||||
code += "\n\n";
|
||||
}
|
||||
|
||||
// Returns the function name that is able to read a value of the given type.
|
||||
|
@ -1125,9 +1129,12 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
|||
code += "); }\n";
|
||||
}
|
||||
}
|
||||
code += "};\n\n";
|
||||
code += "}";
|
||||
// Java does not need the closing semi-colon on class definitions.
|
||||
code += (lang_.language != IDLOptions::kJava) ? ";" : "";
|
||||
code += "\n\n";
|
||||
}
|
||||
const LanguageParameters & lang_ = language_parameters[parser_.opts.lang];
|
||||
const LanguageParameters & lang_;
|
||||
};
|
||||
} // namespace general
|
||||
|
||||
|
|
|
@ -423,6 +423,12 @@ CheckedError Parser::Next() {
|
|||
return NoError();
|
||||
} else if (isdigit(static_cast<unsigned char>(c)) || c == '-') {
|
||||
const char *start = cursor_ - 1;
|
||||
if (c == '-' && *cursor_ == '0' && (cursor_[1] == 'x' || cursor_[1] == 'X')) {
|
||||
++start;
|
||||
++cursor_;
|
||||
attribute_.append(&c, &c + 1);
|
||||
c = '0';
|
||||
}
|
||||
if (c == '0' && (*cursor_ == 'x' || *cursor_ == 'X')) {
|
||||
cursor_++;
|
||||
while (isxdigit(static_cast<unsigned char>(*cursor_))) cursor_++;
|
||||
|
|
|
@ -162,7 +162,7 @@ struct TestSimpleTableWithEnumBuilder {
|
|||
};
|
||||
|
||||
inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
Color color = Color_Green) {
|
||||
Color color = Color_Green) {
|
||||
TestSimpleTableWithEnumBuilder builder_(_fbb);
|
||||
builder_.add_color(color);
|
||||
return builder_.Finish();
|
||||
|
@ -205,9 +205,9 @@ struct StatBuilder {
|
|||
};
|
||||
|
||||
inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<flatbuffers::String> id = 0,
|
||||
int64_t val = 0,
|
||||
uint16_t count = 0) {
|
||||
flatbuffers::Offset<flatbuffers::String> id = 0,
|
||||
int64_t val = 0,
|
||||
uint16_t count = 0) {
|
||||
StatBuilder builder_(_fbb);
|
||||
builder_.add_val(val);
|
||||
builder_.add_id(id);
|
||||
|
@ -215,6 +215,13 @@ inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb
|
|||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const char *id = nullptr,
|
||||
int64_t val = 0,
|
||||
uint16_t count = 0) {
|
||||
return CreateStat(_fbb, id ? 0 : _fbb.CreateString(id), val, count);
|
||||
}
|
||||
|
||||
/// an example documentation comment: monster object
|
||||
struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
enum {
|
||||
|
@ -397,34 +404,34 @@ struct MonsterBuilder {
|
|||
};
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const Vec3 *pos = 0,
|
||||
int16_t mana = 150,
|
||||
int16_t hp = 100,
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory = 0,
|
||||
Color color = Color_Blue,
|
||||
Any test_type = Any_NONE,
|
||||
flatbuffers::Offset<void> test = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<const Test *>> test4 = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Monster>>> testarrayoftables = 0,
|
||||
flatbuffers::Offset<Monster> enemy = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testnestedflatbuffer = 0,
|
||||
flatbuffers::Offset<Stat> testempty = 0,
|
||||
bool testbool = false,
|
||||
int32_t testhashs32_fnv1 = 0,
|
||||
uint32_t testhashu32_fnv1 = 0,
|
||||
int64_t testhashs64_fnv1 = 0,
|
||||
uint64_t testhashu64_fnv1 = 0,
|
||||
int32_t testhashs32_fnv1a = 0,
|
||||
uint32_t testhashu32_fnv1a = 0,
|
||||
int64_t testhashs64_fnv1a = 0,
|
||||
uint64_t testhashu64_fnv1a = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testarrayofbools = 0,
|
||||
float testf = 3.14159f,
|
||||
float testf2 = 3.0f,
|
||||
float testf3 = 0.0f,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2 = 0) {
|
||||
const Vec3 *pos = 0,
|
||||
int16_t mana = 150,
|
||||
int16_t hp = 100,
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory = 0,
|
||||
Color color = Color_Blue,
|
||||
Any test_type = Any_NONE,
|
||||
flatbuffers::Offset<void> test = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<const Test *>> test4 = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Monster>>> testarrayoftables = 0,
|
||||
flatbuffers::Offset<Monster> enemy = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testnestedflatbuffer = 0,
|
||||
flatbuffers::Offset<Stat> testempty = 0,
|
||||
bool testbool = false,
|
||||
int32_t testhashs32_fnv1 = 0,
|
||||
uint32_t testhashu32_fnv1 = 0,
|
||||
int64_t testhashs64_fnv1 = 0,
|
||||
uint64_t testhashu64_fnv1 = 0,
|
||||
int32_t testhashs32_fnv1a = 0,
|
||||
uint32_t testhashu32_fnv1a = 0,
|
||||
int64_t testhashs64_fnv1a = 0,
|
||||
uint64_t testhashu64_fnv1a = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testarrayofbools = 0,
|
||||
float testf = 3.14159f,
|
||||
float testf2 = 3.0f,
|
||||
float testf3 = 0.0f,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2 = 0) {
|
||||
MonsterBuilder builder_(_fbb);
|
||||
builder_.add_testhashu64_fnv1a(testhashu64_fnv1a);
|
||||
builder_.add_testhashs64_fnv1a(testhashs64_fnv1a);
|
||||
|
@ -457,6 +464,38 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
|
|||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const Vec3 *pos = 0,
|
||||
int16_t mana = 150,
|
||||
int16_t hp = 100,
|
||||
const char *name = nullptr,
|
||||
const std::vector<uint8_t> *inventory = nullptr,
|
||||
Color color = Color_Blue,
|
||||
Any test_type = Any_NONE,
|
||||
flatbuffers::Offset<void> test = 0,
|
||||
const std::vector<const Test *> *test4 = nullptr,
|
||||
const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring = nullptr,
|
||||
const std::vector<flatbuffers::Offset<Monster>> *testarrayoftables = nullptr,
|
||||
flatbuffers::Offset<Monster> enemy = 0,
|
||||
const std::vector<uint8_t> *testnestedflatbuffer = nullptr,
|
||||
flatbuffers::Offset<Stat> testempty = 0,
|
||||
bool testbool = false,
|
||||
int32_t testhashs32_fnv1 = 0,
|
||||
uint32_t testhashu32_fnv1 = 0,
|
||||
int64_t testhashs64_fnv1 = 0,
|
||||
uint64_t testhashu64_fnv1 = 0,
|
||||
int32_t testhashs32_fnv1a = 0,
|
||||
uint32_t testhashu32_fnv1a = 0,
|
||||
int64_t testhashs64_fnv1a = 0,
|
||||
uint64_t testhashu64_fnv1a = 0,
|
||||
const std::vector<uint8_t> *testarrayofbools = nullptr,
|
||||
float testf = 3.14159f,
|
||||
float testf2 = 3.0f,
|
||||
float testf3 = 0.0f,
|
||||
const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring2 = nullptr) {
|
||||
return CreateMonster(_fbb, pos, mana, hp, name ? 0 : _fbb.CreateString(name), inventory ? 0 : _fbb.CreateVector<uint8_t>(*inventory), color, test_type, test, test4 ? 0 : _fbb.CreateVector<const Test *>(*test4), testarrayofstring ? 0 : _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring), testarrayoftables ? 0 : _fbb.CreateVector<flatbuffers::Offset<Monster>>(*testarrayoftables), enemy, testnestedflatbuffer ? 0 : _fbb.CreateVector<uint8_t>(*testnestedflatbuffer), testempty, testbool, testhashs32_fnv1, testhashu32_fnv1, testhashs64_fnv1, testhashu64_fnv1, testhashs32_fnv1a, testhashu32_fnv1a, testhashs64_fnv1a, testhashu64_fnv1a, testarrayofbools ? 0 : _fbb.CreateVector<uint8_t>(*testarrayofbools), testf, testf2, testf3, testarrayofstring2 ? 0 : _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring2));
|
||||
}
|
||||
|
||||
inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *union_obj, Any type) {
|
||||
switch (type) {
|
||||
case Any_NONE: return true;
|
||||
|
@ -471,12 +510,12 @@ inline const MyGame::Example::Monster *GetMonster(const void *buf) { return flat
|
|||
|
||||
inline Monster *GetMutableMonster(void *buf) { return flatbuffers::GetMutableRoot<Monster>(buf); }
|
||||
|
||||
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<MyGame::Example::Monster>(); }
|
||||
|
||||
inline const char *MonsterIdentifier() { return "MONS"; }
|
||||
|
||||
inline bool MonsterBufferHasIdentifier(const void *buf) { return flatbuffers::BufferHasIdentifier(buf, MonsterIdentifier()); }
|
||||
|
||||
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<MyGame::Example::Monster>(MonsterIdentifier()); }
|
||||
|
||||
inline const char *MonsterExtension() { return "mon"; }
|
||||
|
||||
inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Example::Monster> root) { fbb.Finish(root, MonsterIdentifier()); }
|
||||
|
|
|
@ -69,7 +69,7 @@ struct TableInNestedNSBuilder {
|
|||
};
|
||||
|
||||
inline flatbuffers::Offset<TableInNestedNS> CreateTableInNestedNS(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
int32_t foo = 0) {
|
||||
int32_t foo = 0) {
|
||||
TableInNestedNSBuilder builder_(_fbb);
|
||||
builder_.add_foo(foo);
|
||||
return builder_.Finish();
|
||||
|
|
|
@ -60,9 +60,9 @@ struct TableInFirstNSBuilder {
|
|||
};
|
||||
|
||||
inline flatbuffers::Offset<TableInFirstNS> CreateTableInFirstNS(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table = 0,
|
||||
NamespaceA::NamespaceB::EnumInNestedNS foo_enum = NamespaceA::NamespaceB::EnumInNestedNS_A,
|
||||
const NamespaceA::NamespaceB::StructInNestedNS *foo_struct = 0) {
|
||||
flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table = 0,
|
||||
NamespaceA::NamespaceB::EnumInNestedNS foo_enum = NamespaceA::NamespaceB::EnumInNestedNS_A,
|
||||
const NamespaceA::NamespaceB::StructInNestedNS *foo_struct = 0) {
|
||||
TableInFirstNSBuilder builder_(_fbb);
|
||||
builder_.add_foo_struct(foo_struct);
|
||||
builder_.add_foo_table(foo_table);
|
||||
|
@ -107,8 +107,8 @@ struct TableInCBuilder {
|
|||
};
|
||||
|
||||
inline flatbuffers::Offset<TableInC> CreateTableInC(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<NamespaceA::TableInFirstNS> refer_to_a1 = 0,
|
||||
flatbuffers::Offset<NamespaceA::SecondTableInA> refer_to_a2 = 0) {
|
||||
flatbuffers::Offset<NamespaceA::TableInFirstNS> refer_to_a1 = 0,
|
||||
flatbuffers::Offset<NamespaceA::SecondTableInA> refer_to_a2 = 0) {
|
||||
TableInCBuilder builder_(_fbb);
|
||||
builder_.add_refer_to_a2(refer_to_a2);
|
||||
builder_.add_refer_to_a1(refer_to_a1);
|
||||
|
@ -146,7 +146,7 @@ struct SecondTableInABuilder {
|
|||
};
|
||||
|
||||
inline flatbuffers::Offset<SecondTableInA> CreateSecondTableInA(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<NamespaceC::TableInC> refer_to_c = 0) {
|
||||
flatbuffers::Offset<NamespaceC::TableInC> refer_to_c = 0) {
|
||||
SecondTableInABuilder builder_(_fbb);
|
||||
builder_.add_refer_to_c(refer_to_c);
|
||||
return builder_.Finish();
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#define FLATBUFFERS_DEBUG_VERIFICATION_FAILURE 1
|
||||
#define FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
|
@ -160,6 +161,23 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length) {
|
|||
flatbuffers::Verifier verifier(flatbuf, length);
|
||||
TEST_EQ(VerifyMonsterBuffer(verifier), true);
|
||||
|
||||
std::vector<uint8_t> test_buff;
|
||||
test_buff.resize(length * 2);
|
||||
std::memcpy(&test_buff[0], flatbuf , length);
|
||||
std::memcpy(&test_buff[length], flatbuf , length);
|
||||
|
||||
flatbuffers::Verifier verifierl(&test_buff[0], length - 1);
|
||||
TEST_EQ(VerifyMonsterBuffer(verifierl), false);
|
||||
TEST_EQ(verifierl.GetComputedSize(), 0);
|
||||
|
||||
flatbuffers::Verifier verifier1(&test_buff[0], length);
|
||||
TEST_EQ(VerifyMonsterBuffer(verifier1), true);
|
||||
TEST_EQ(verifier1.GetComputedSize(), length);
|
||||
|
||||
flatbuffers::Verifier verifier2(&test_buff[length], length);
|
||||
TEST_EQ(VerifyMonsterBuffer(verifier2), true);
|
||||
TEST_EQ(verifier2.GetComputedSize(), length);
|
||||
|
||||
TEST_EQ(strcmp(MonsterIdentifier(), "MONS"), 0);
|
||||
TEST_EQ(MonsterBufferHasIdentifier(flatbuf), true);
|
||||
TEST_EQ(strcmp(MonsterExtension(), "mon"), 0);
|
||||
|
@ -814,14 +832,14 @@ void ErrorTest() {
|
|||
TestError("table X { Y:byte; } root_type X; { Y:1, Y:2 }", "more than once");
|
||||
}
|
||||
|
||||
float TestValue(const char *json) {
|
||||
template<typename T> T TestValue(const char *json, const char *type_name) {
|
||||
flatbuffers::Parser parser;
|
||||
|
||||
// Simple schema.
|
||||
TEST_EQ(parser.Parse("table X { Y:float; } root_type X;"), true);
|
||||
TEST_EQ(parser.Parse(std::string("table X { Y:" + std::string(type_name) + "; } root_type X;").c_str()), true);
|
||||
|
||||
TEST_EQ(parser.Parse(json), true);
|
||||
auto root = flatbuffers::GetRoot<float>(parser.builder_.GetBufferPointer());
|
||||
auto root = flatbuffers::GetRoot<T>(parser.builder_.GetBufferPointer());
|
||||
// root will point to the table, which is a 32bit vtable offset followed
|
||||
// by a float:
|
||||
TEST_EQ(sizeof(flatbuffers::soffset_t), 4); // Test assumes 32bit offsets
|
||||
|
@ -833,10 +851,13 @@ bool FloatCompare(float a, float b) { return fabs(a - b) < 0.001; }
|
|||
// Additional parser testing not covered elsewhere.
|
||||
void ValueTest() {
|
||||
// Test scientific notation numbers.
|
||||
TEST_EQ(FloatCompare(TestValue("{ Y:0.0314159e+2 }"), 3.14159), true);
|
||||
TEST_EQ(FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }","float"), (float)3.14159), true);
|
||||
|
||||
// Test conversion functions.
|
||||
TEST_EQ(FloatCompare(TestValue("{ Y:cos(rad(180)) }"), -1), true);
|
||||
TEST_EQ(FloatCompare(TestValue<float>("{ Y:cos(rad(180)) }","float"), -1), true);
|
||||
|
||||
// Test negative hex constant.
|
||||
TEST_EQ(TestValue<int>("{ Y:-0x80 }","int") == -128, true);
|
||||
}
|
||||
|
||||
void EnumStringsTest() {
|
||||
|
|
Loading…
Reference in New Issue