diff --git a/CONTRIBUTING b/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING rename to CONTRIBUTING.md diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index 6755ec279..01ab6db04 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -288,7 +288,7 @@ public: } VectorIterator operator++(int) { - VectorIterator temp(data_); + VectorIterator temp(data_,0); data_ += IndirectHelper::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 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(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 bool VerifyBuffer() { + template 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(buf_) && reinterpret_cast(buf_ + ReadScalar(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 diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index b22bc08a1..dddfab25c 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -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) {} }; diff --git a/include/flatbuffers/reflection_generated.h b/include/flatbuffers/reflection_generated.h index da1124939..eb981857b 100644 --- a/include/flatbuffers/reflection_generated.h +++ b/include/flatbuffers/reflection_generated.h @@ -478,12 +478,12 @@ inline flatbuffers::Offset CreateSchema(flatbuffers::FlatBufferBuilder & inline const reflection::Schema *GetSchema(const void *buf) { return flatbuffers::GetRoot(buf); } -inline bool VerifySchemaBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer(); } - 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(SchemaIdentifier()); } + inline const char *SchemaExtension() { return "bfbs"; } inline void FinishSchemaBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset root) { fbb.Finish(root, SchemaIdentifier()); } diff --git a/samples/monster_generated.h b/samples/monster_generated.h index 1a16126a5..62a23ad82 100644 --- a/samples/monster_generated.h +++ b/samples/monster_generated.h @@ -135,15 +135,15 @@ struct MonsterBuilder { }; inline flatbuffers::Offset CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, - const Vec3 *pos = 0, - int16_t mana = 150, - int16_t hp = 100, - flatbuffers::Offset name = 0, - flatbuffers::Offset> inventory = 0, - Color color = Color_Blue, - flatbuffers::Offset>> weapons = 0, - Equipment equipped_type = Equipment_NONE, - flatbuffers::Offset equipped = 0) { + const Vec3 *pos = 0, + int16_t mana = 150, + int16_t hp = 100, + flatbuffers::Offset name = 0, + flatbuffers::Offset> inventory = 0, + Color color = Color_Blue, + flatbuffers::Offset>> weapons = 0, + Equipment equipped_type = Equipment_NONE, + flatbuffers::Offset equipped = 0) { MonsterBuilder builder_(_fbb); builder_.add_equipped(equipped); builder_.add_weapons(weapons); @@ -157,6 +157,19 @@ inline flatbuffers::Offset CreateMonster(flatbuffers::FlatBufferBuilder return builder_.Finish(); } +inline flatbuffers::Offset CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, + const Vec3 *pos = 0, + int16_t mana = 150, + int16_t hp = 100, + const char *name = nullptr, + const std::vector *inventory = nullptr, + Color color = Color_Blue, + const std::vector> *weapons = nullptr, + Equipment equipped_type = Equipment_NONE, + flatbuffers::Offset equipped = 0) { + return CreateMonster(_fbb, pos, mana, hp, name ? 0 : _fbb.CreateString(name), inventory ? 0 : _fbb.CreateVector(*inventory), color, weapons ? 0 : _fbb.CreateVector>(*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 CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset name = 0, - int16_t damage = 0) { + flatbuffers::Offset name = 0, + int16_t damage = 0) { WeaponBuilder builder_(_fbb); builder_.add_name(name); builder_.add_damage(damage); return builder_.Finish(); } +inline flatbuffers::Offset 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(buf); } -inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer(); } +inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer(nullptr); } inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset root) { fbb.Finish(root); } diff --git a/src/flatc.cpp b/src/flatc.cpp index c7ba29e86..d410718e3 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -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") { diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index c690240d6..e12e8a34a 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -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(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(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, diff --git a/src/idl_gen_fbs.cpp b/src/idl_gen_fbs.cpp index 00afe25d4..237230e8e 100644 --- a/src/idl_gen_fbs.cpp +++ b/src/idl_gen_fbs.cpp @@ -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); + } } } diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index a96609c54..34ca2c3e4 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -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(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 diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index b758e9592..a5f325de4 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -423,6 +423,12 @@ CheckedError Parser::Next() { return NoError(); } else if (isdigit(static_cast(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(*cursor_))) cursor_++; diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h index 50fbc28ce..9f3d4de0f 100644 --- a/tests/monster_test_generated.h +++ b/tests/monster_test_generated.h @@ -162,7 +162,7 @@ struct TestSimpleTableWithEnumBuilder { }; inline flatbuffers::Offset 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 CreateStat(flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset id = 0, - int64_t val = 0, - uint16_t count = 0) { + flatbuffers::Offset 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 CreateStat(flatbuffers::FlatBufferBuilder &_fbb return builder_.Finish(); } +inline flatbuffers::Offset 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 CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, - const Vec3 *pos = 0, - int16_t mana = 150, - int16_t hp = 100, - flatbuffers::Offset name = 0, - flatbuffers::Offset> inventory = 0, - Color color = Color_Blue, - Any test_type = Any_NONE, - flatbuffers::Offset test = 0, - flatbuffers::Offset> test4 = 0, - flatbuffers::Offset>> testarrayofstring = 0, - flatbuffers::Offset>> testarrayoftables = 0, - flatbuffers::Offset enemy = 0, - flatbuffers::Offset> testnestedflatbuffer = 0, - flatbuffers::Offset 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> testarrayofbools = 0, - float testf = 3.14159f, - float testf2 = 3.0f, - float testf3 = 0.0f, - flatbuffers::Offset>> testarrayofstring2 = 0) { + const Vec3 *pos = 0, + int16_t mana = 150, + int16_t hp = 100, + flatbuffers::Offset name = 0, + flatbuffers::Offset> inventory = 0, + Color color = Color_Blue, + Any test_type = Any_NONE, + flatbuffers::Offset test = 0, + flatbuffers::Offset> test4 = 0, + flatbuffers::Offset>> testarrayofstring = 0, + flatbuffers::Offset>> testarrayoftables = 0, + flatbuffers::Offset enemy = 0, + flatbuffers::Offset> testnestedflatbuffer = 0, + flatbuffers::Offset 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> testarrayofbools = 0, + float testf = 3.14159f, + float testf2 = 3.0f, + float testf3 = 0.0f, + flatbuffers::Offset>> testarrayofstring2 = 0) { MonsterBuilder builder_(_fbb); builder_.add_testhashu64_fnv1a(testhashu64_fnv1a); builder_.add_testhashs64_fnv1a(testhashs64_fnv1a); @@ -457,6 +464,38 @@ inline flatbuffers::Offset CreateMonster(flatbuffers::FlatBufferBuilder return builder_.Finish(); } +inline flatbuffers::Offset CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, + const Vec3 *pos = 0, + int16_t mana = 150, + int16_t hp = 100, + const char *name = nullptr, + const std::vector *inventory = nullptr, + Color color = Color_Blue, + Any test_type = Any_NONE, + flatbuffers::Offset test = 0, + const std::vector *test4 = nullptr, + const std::vector> *testarrayofstring = nullptr, + const std::vector> *testarrayoftables = nullptr, + flatbuffers::Offset enemy = 0, + const std::vector *testnestedflatbuffer = nullptr, + flatbuffers::Offset 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 *testarrayofbools = nullptr, + float testf = 3.14159f, + float testf2 = 3.0f, + float testf3 = 0.0f, + const std::vector> *testarrayofstring2 = nullptr) { + return CreateMonster(_fbb, pos, mana, hp, name ? 0 : _fbb.CreateString(name), inventory ? 0 : _fbb.CreateVector(*inventory), color, test_type, test, test4 ? 0 : _fbb.CreateVector(*test4), testarrayofstring ? 0 : _fbb.CreateVector>(*testarrayofstring), testarrayoftables ? 0 : _fbb.CreateVector>(*testarrayoftables), enemy, testnestedflatbuffer ? 0 : _fbb.CreateVector(*testnestedflatbuffer), testempty, testbool, testhashs32_fnv1, testhashu32_fnv1, testhashs64_fnv1, testhashu64_fnv1, testhashs32_fnv1a, testhashu32_fnv1a, testhashs64_fnv1a, testhashu64_fnv1a, testarrayofbools ? 0 : _fbb.CreateVector(*testarrayofbools), testf, testf2, testf3, testarrayofstring2 ? 0 : _fbb.CreateVector>(*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(buf); } -inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer(); } - 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(MonsterIdentifier()); } + inline const char *MonsterExtension() { return "mon"; } inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset root) { fbb.Finish(root, MonsterIdentifier()); } diff --git a/tests/namespace_test/namespace_test1_generated.h b/tests/namespace_test/namespace_test1_generated.h index 9e10eb4c1..23a0964fb 100644 --- a/tests/namespace_test/namespace_test1_generated.h +++ b/tests/namespace_test/namespace_test1_generated.h @@ -69,7 +69,7 @@ struct TableInNestedNSBuilder { }; inline flatbuffers::Offset CreateTableInNestedNS(flatbuffers::FlatBufferBuilder &_fbb, - int32_t foo = 0) { + int32_t foo = 0) { TableInNestedNSBuilder builder_(_fbb); builder_.add_foo(foo); return builder_.Finish(); diff --git a/tests/namespace_test/namespace_test2_generated.h b/tests/namespace_test/namespace_test2_generated.h index 8e6b3ada8..885eae29b 100644 --- a/tests/namespace_test/namespace_test2_generated.h +++ b/tests/namespace_test/namespace_test2_generated.h @@ -60,9 +60,9 @@ struct TableInFirstNSBuilder { }; inline flatbuffers::Offset CreateTableInFirstNS(flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset foo_table = 0, - NamespaceA::NamespaceB::EnumInNestedNS foo_enum = NamespaceA::NamespaceB::EnumInNestedNS_A, - const NamespaceA::NamespaceB::StructInNestedNS *foo_struct = 0) { + flatbuffers::Offset 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 CreateTableInC(flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset refer_to_a1 = 0, - flatbuffers::Offset refer_to_a2 = 0) { + flatbuffers::Offset refer_to_a1 = 0, + flatbuffers::Offset 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 CreateSecondTableInA(flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset refer_to_c = 0) { + flatbuffers::Offset refer_to_c = 0) { SecondTableInABuilder builder_(_fbb); builder_.add_refer_to_c(refer_to_c); return builder_.Finish(); diff --git a/tests/test.cpp b/tests/test.cpp index 6f3b06299..402843a6f 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -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 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 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(parser.builder_.GetBufferPointer()); + auto root = flatbuffers::GetRoot(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("{ 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("{ Y:cos(rad(180)) }","float"), -1), true); + + // Test negative hex constant. + TEST_EQ(TestValue("{ Y:-0x80 }","int") == -128, true); } void EnumStringsTest() {