Added --filename-suffix and --filename-ext to flatc (#5778)

* Fixed refractoring issue in reflection/generate_code.sh. Also, mv deletes the original file, so I don't need to clean it up manually in that case.

* Added --filename-suffix and --filename-ext to flatc

* Fixed typo and added example generation of suffix and extension for C++

* Removed extra ;

* Removed clang-format block from a region that didn't need it. Fixed an auto format of another clang-format block

* Added docs, fixed pointer alignment, removed suffix test file
This commit is contained in:
Derek Bailey
2020-03-02 10:15:23 -08:00
committed by GitHub
parent c9a30c9ca2
commit 6ff1898413
33 changed files with 452 additions and 432 deletions

3
.gitignore vendored
View File

@@ -123,4 +123,5 @@ Cargo.lock
.corpus**
.seed**
grpc/google/
**/Package.resolved
**/Package.resolved
.clangd/**

View File

@@ -188,6 +188,13 @@ Additional options:
- `--conform-includes PATH` : Include path for the schema given with
`--conform PATH`.
- `--filename-suffix SUFFIX` : The suffix appended to the generated
file names. Default is '_generated'.
- `--filename-ext EXTENSION` : The extension appended to the generated
file names. Default is language-specific (e.g. "h" for C++). This
should not be used when multiple languages are specified.
- `--include-prefix PATH` : Prefix this path to any generated include
statements.

View File

@@ -252,8 +252,8 @@ void builder_move_ctor_conversion_before_finish_test() {
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
auto monster_offset =
CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0, m1_color(),
Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0,
m1_color(), Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
mb.Finish(monster_offset);
{
auto mon = flatbuffers::GetRoot<Monster>(mb.GetBufferPointer());
@@ -262,7 +262,7 @@ void builder_move_ctor_conversion_before_finish_test() {
TEST_EQ_STR(mon->name()->c_str(), m1_name().c_str());
TEST_EQ(mon->color(), m1_color());
}
TEST_EQ(1, MyGame::Example::Color_Red);
TEST_EQ(1, MyGame::Example::Color_Red);
TEST_EQ(1, m1_color());
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
@@ -302,8 +302,8 @@ void builder_move_assign_conversion_before_finish_test() {
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
mb = std::move(fbb);
auto monster_offset =
CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0, m1_color(),
Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0,
m1_color(), Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
mb.Finish(monster_offset);
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);

View File

@@ -94,15 +94,20 @@ class BaseGenerator {
static std::string NamespaceDir(const Parser &parser, const std::string &path,
const Namespace &ns);
std::string GeneratedFileName(const std::string &path,
const std::string &file_name,
const IDLOptions &options) const;
protected:
BaseGenerator(const Parser &parser, const std::string &path,
const std::string &file_name, std::string qualifying_start,
std::string qualifying_separator)
std::string qualifying_separator, std::string default_extension)
: parser_(parser),
path_(path),
file_name_(file_name),
qualifying_start_(qualifying_start),
qualifying_separator_(qualifying_separator) {}
qualifying_separator_(qualifying_separator),
default_extension_(default_extension) {}
virtual ~BaseGenerator() {}
// No copy/assign.
@@ -138,6 +143,7 @@ class BaseGenerator {
const std::string &file_name_;
const std::string qualifying_start_;
const std::string qualifying_separator_;
const std::string default_extension_;
};
struct CommentConfig {

View File

@@ -365,7 +365,7 @@ template<typename T> class Vector {
// This class is a pointer. Copying will therefore create an invalid object.
// Private and unimplemented copy constructor.
Vector(const Vector &);
Vector& operator=(const Vector&);
Vector &operator=(const Vector &);
template<typename K> static int KeyCompare(const void *ap, const void *bp) {
const K *key = reinterpret_cast<const K *>(ap);
@@ -525,7 +525,7 @@ template<typename T, uint16_t length> class Array<Offset<T>, length> {
static_assert(flatbuffers::is_same<T, void>::value, "unexpected type T");
public:
typedef const void* return_type;
typedef const void *return_type;
const uint8_t *Data() const { return data_; }

View File

@@ -218,16 +218,17 @@ class Object {
class Sized : public Object {
public:
// Size prefix.
Sized(const uint8_t *data, uint8_t byte_width) :
Object(data, byte_width), size_(read_size()) {}
Sized(const uint8_t *data, uint8_t byte_width)
: Object(data, byte_width), size_(read_size()) {}
// Manual size.
Sized(const uint8_t *data, uint8_t byte_width, size_t sz) :
Object(data, byte_width), size_(sz) {}
Sized(const uint8_t *data, uint8_t byte_width, size_t sz)
: Object(data, byte_width), size_(sz) {}
size_t size() const { return size_; }
// Access size stored in `byte_width_` bytes before data_ pointer.
size_t read_size() const {
return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_));
}
protected:
size_t size_;
};
@@ -235,11 +236,10 @@ class Sized : public Object {
class String : public Sized {
public:
// Size prefix.
String(const uint8_t *data, uint8_t byte_width)
: Sized(data, byte_width) {}
String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {}
// Manual size.
String(const uint8_t *data, uint8_t byte_width, size_t sz)
: Sized(data, byte_width, sz) {}
: Sized(data, byte_width, sz) {}
size_t length() const { return size(); }
const char *c_str() const { return reinterpret_cast<const char *>(data_); }
@@ -296,6 +296,7 @@ class TypedVector : public Sized {
Type ElementType() { return type_; }
friend Reference;
private:
Type type_;
@@ -614,8 +615,8 @@ class Reference {
TypedVector AsTypedVector() const {
if (IsTypedVector()) {
auto tv = TypedVector(Indirect(), byte_width_,
ToTypedVectorElementType(type_));
auto tv =
TypedVector(Indirect(), byte_width_, ToTypedVectorElementType(type_));
if (tv.type_ == FBT_STRING) {
// These can't be accessed as strings, since we don't know the bit-width
// of the size field, see the declaration of

View File

@@ -560,6 +560,8 @@ struct IDLOptions {
std::vector<std::string> cpp_includes;
std::string cpp_std;
std::string proto_namespace_suffix;
std::string filename_suffix;
std::string filename_extension;
// Possible options for the more general generator below.
enum Language {
@@ -643,6 +645,8 @@ struct IDLOptions {
force_defaults(false),
java_primitive_has_method(false),
cs_gen_json_serializer(false),
filename_suffix("_generated"),
filename_extension(),
lang(IDLOptions::kJava),
mini_reflect(IDLOptions::kNone),
lang_to_generate(0),
@@ -1126,9 +1130,8 @@ bool GeneratePythonGRPC(const Parser &parser, const std::string &path,
// Generate GRPC Swift interfaces.
// See idl_gen_grpc.cpp.
extern bool GenerateSwiftGRPC(const Parser &parser,
const std::string &path,
const std::string &file_name);
extern bool GenerateSwiftGRPC(const Parser &parser, const std::string &path,
const std::string &file_name);
} // namespace flatbuffers

View File

@@ -636,30 +636,30 @@ inline bool EscapeString(const char *s, size_t length, std::string *_text,
return true;
}
inline std::string BufferToHexText(const void *buffer, size_t buffer_size, size_t max_length,
inline std::string BufferToHexText(const void *buffer, size_t buffer_size,
size_t max_length,
const std::string &wrapped_line_prefix,
const std::string &wrapped_line_suffix) {
std::string text = wrapped_line_prefix;
size_t start_offset = 0;
const char *s = reinterpret_cast<const char *>(buffer);
for (size_t i = 0; s && i < buffer_size; i++) {
// Last iteration or do we have more?
bool have_more= i + 1 < buffer_size;
text += "0x";
text += IntToStringHex(static_cast<uint8_t>(s[i]), 2);
if (have_more) {
text += ',';
}
// If we have more to process and we reached max_length
if (have_more && text.size() + wrapped_line_suffix.size() >= start_offset + max_length) {
text += wrapped_line_suffix;
text += '\n';
start_offset = text.size();
text += wrapped_line_prefix;
}
std::string text = wrapped_line_prefix;
size_t start_offset = 0;
const char *s = reinterpret_cast<const char *>(buffer);
for (size_t i = 0; s && i < buffer_size; i++) {
// Last iteration or do we have more?
bool have_more = i + 1 < buffer_size;
text += "0x";
text += IntToStringHex(static_cast<uint8_t>(s[i]), 2);
if (have_more) { text += ','; }
// If we have more to process and we reached max_length
if (have_more &&
text.size() + wrapped_line_suffix.size() >= start_offset + max_length) {
text += wrapped_line_suffix;
text += '\n';
start_offset = text.size();
text += wrapped_line_prefix;
}
text += wrapped_line_suffix;
return text;
}
text += wrapped_line_suffix;
return text;
}
// Remove paired quotes in a string: "text"|'text' -> text.

View File

@@ -145,6 +145,14 @@ std::string BaseGenerator::GetNameSpace(const Definition &def) const {
return qualified_name;
}
std::string BaseGenerator::GeneratedFileName(const std::string &path,
const std::string &file_name,
const IDLOptions &options) const {
return path + file_name + options.filename_suffix + "." +
(options.filename_extension.empty() ? default_extension_
: options.filename_extension);
}
// Generate a documentation comment, if available.
void GenComment(const std::vector<std::string> &dc, std::string *code_ptr,
const CommentConfig *config, const char *prefix) {

View File

@@ -148,6 +148,10 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
" --conform FILE Specify a schema the following schemas should be\n"
" an evolution of. Gives errors if not.\n"
" --conform-includes Include path for the schema given with --conform PATH\n"
" --filename-suffix The suffix appended to the generated file names.\n"
" Default is '_generated'.\n"
" --filename-ext The extension appended to the generated file names.\n"
" Default is language-specific (e.g., '.h' for C++)\n"
" --include-prefix Prefix this path to any generated include statements.\n"
" PATH\n"
" --keep-prefix Keep original prefix of schema include statement.\n"
@@ -339,6 +343,12 @@ int FlatCompiler::Compile(int argc, const char **argv) {
} else if (arg == "--root-type") {
if (++argi >= argc) Error("missing type following: " + arg, true);
opts.root_type = argv[argi];
} else if (arg == "--filename-suffix") {
if (++argi >= argc) Error("missing filename suffix: " + arg, true);
opts.filename_suffix = argv[argi];
} else if (arg == "--filename-ext") {
if (++argi >= argc) Error("missing filename extension: " + arg, true);
opts.filename_extension = argv[argi];
} else if (arg == "--force-defaults") {
opts.force_defaults = true;
} else if (arg == "--force-empty") {
@@ -353,7 +363,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
} else if (arg == "--flexbuffers") {
opts.use_flexbuffers = true;
} else if (arg == "--cpp-std") {
if (++argi >= argc) Error("missing C++ standard specification" + arg, true);
if (++argi >= argc)
Error("missing C++ standard specification" + arg, true);
opts.cpp_std = argv[argi];
} else {
for (size_t i = 0; i < params_.num_generators; ++i) {

View File

@@ -30,7 +30,9 @@ static void Error(const flatbuffers::FlatCompiler *flatc,
const std::string &err, bool usage, bool show_exe_name) {
if (show_exe_name) { printf("%s: ", g_program_name); }
printf("error: %s\n", err.c_str());
if (usage && flatc) { printf("%s", flatc->GetUsageString(g_program_name).c_str()); }
if (usage && flatc) {
printf("%s", flatc->GetUsageString(g_program_name).c_str());
}
exit(1);
}
@@ -105,8 +107,8 @@ int main(int argc, const char *argv[]) {
{ flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema",
true, nullptr, flatbuffers::IDLOptions::kJsonSchema,
"Generate Json schema", nullptr },
{ flatbuffers::GenerateSwift, nullptr, "--swift", "swift",
true, flatbuffers::GenerateSwiftGRPC, flatbuffers::IDLOptions::kSwift,
{ flatbuffers::GenerateSwift, nullptr, "--swift", "swift", true,
flatbuffers::GenerateSwiftGRPC, flatbuffers::IDLOptions::kSwift,
"Generate Swift files for tables/structs", nullptr },
};

View File

@@ -48,36 +48,29 @@ static inline std::string NumToStringCpp(std::string val, BaseType type) {
}
}
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name) {
return path + file_name + "_generated.h";
}
static std::string GenIncludeGuard(const std::string &file_name,
const Namespace &name_space,
const std::string &postfix= "") {
// Generate include guard.
std::string guard = file_name;
// Remove any non-alpha-numeric characters that may appear in a filename.
struct IsAlnum {
bool operator()(char c) const { return !is_alnum(c); }
};
guard.erase(std::remove_if(guard.begin(), guard.end(), IsAlnum()),
guard.end());
guard = "FLATBUFFERS_GENERATED_" + guard;
guard += "_";
// For further uniqueness, also add the namespace.
for (auto it = name_space.components.begin();
it != name_space.components.end(); ++it) {
guard += *it + "_";
}
// Anything extra to add to the guard?
if (!postfix.empty()) {
guard += postfix + "_";
}
guard += "H_";
std::transform(guard.begin(), guard.end(), guard.begin(), ToUpper);
return guard;
const std::string &postfix = "") {
// Generate include guard.
std::string guard = file_name;
// Remove any non-alpha-numeric characters that may appear in a filename.
struct IsAlnum {
bool operator()(char c) const { return !is_alnum(c); }
};
guard.erase(std::remove_if(guard.begin(), guard.end(), IsAlnum()),
guard.end());
guard = "FLATBUFFERS_GENERATED_" + guard;
guard += "_";
// For further uniqueness, also add the namespace.
for (auto it = name_space.components.begin();
it != name_space.components.end(); ++it) {
guard += *it + "_";
}
// Anything extra to add to the guard?
if (!postfix.empty()) { guard += postfix + "_"; }
guard += "H_";
std::transform(guard.begin(), guard.end(), guard.begin(), ToUpper);
return guard;
}
namespace cpp {
@@ -89,20 +82,16 @@ struct IDLOptionsCpp : public IDLOptions {
// All fields start with 'g_' prefix to distinguish from the base IDLOptions.
CppStandard g_cpp_std; // Base version of C++ standard.
bool g_only_fixed_enums; // Generate underlaying type for all enums.
// clang-format off
IDLOptionsCpp(const IDLOptions &opts)
: IDLOptions(opts),
g_cpp_std(CPP_STD_11),
g_only_fixed_enums(true)
{}
// clang-format on
: IDLOptions(opts), g_cpp_std(CPP_STD_11), g_only_fixed_enums(true) {}
};
class CppGenerator : public BaseGenerator {
public:
CppGenerator(const Parser &parser, const std::string &path,
const std::string &file_name, IDLOptionsCpp opts)
: BaseGenerator(parser, path, file_name, "", "::"),
: BaseGenerator(parser, path, file_name, "", "::", "h"),
cur_name_space_(nullptr),
opts_(opts),
float_const_gen_("std::numeric_limits<double>::",
@@ -221,9 +210,10 @@ class CppGenerator : public BaseGenerator {
if (it->second.empty()) continue;
auto noext = flatbuffers::StripExtension(it->second);
auto basename = flatbuffers::StripPath(noext);
code_ += "#include \"" + opts_.include_prefix +
(opts_.keep_include_path ? noext : basename) + "_generated.h\"";
auto includeName =
GeneratedFileName(opts_.include_prefix,
opts_.keep_include_path ? noext : basename, opts_);
code_ += "#include \"" + includeName + "\"";
num_includes++;
}
if (num_includes) code_ += "";
@@ -256,7 +246,8 @@ class CppGenerator : public BaseGenerator {
code_ += "// Binary schema not generated, no root struct found";
} else {
auto &struct_def = *parser_.root_struct_def_;
const auto include_guard = GenIncludeGuard(file_name_, *struct_def.defined_namespace, "bfbs");
const auto include_guard =
GenIncludeGuard(file_name_, *struct_def.defined_namespace, "bfbs");
code_ += "#ifndef " + include_guard;
code_ += "#define " + include_guard;
@@ -270,13 +261,15 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("STRUCT_NAME", name);
// Create code to return the binary schema data.
auto binary_schema_hex_text = BufferToHexText(parser_.builder_.GetBufferPointer(),
parser_.builder_.GetSize(), 105, " ", "");
auto binary_schema_hex_text =
BufferToHexText(parser_.builder_.GetBufferPointer(),
parser_.builder_.GetSize(), 105, " ", "");
code_ += "struct {{STRUCT_NAME}}BinarySchema {";
code_ += " static const uint8_t *data() {";
code_ += " // Buffer containing the binary schema.";
code_ += " static const uint8_t bfbsData[" + NumToString(parser_.builder_.GetSize()) + "] = {";
code_ += " static const uint8_t bfbsData[" +
NumToString(parser_.builder_.GetSize()) + "] = {";
code_ += binary_schema_hex_text;
code_ += " };";
code_ += " return bfbsData;";
@@ -300,7 +293,8 @@ class CppGenerator : public BaseGenerator {
}
// We are just adding "_bfbs" to the generated filename.
const auto file_path = GeneratedFileName(path_, file_name_ + "_bfbs");
const auto file_path =
GeneratedFileName(path_, file_name_ + "_bfbs", opts_);
const auto final_code = code_.ToString();
return SaveFile(file_path.c_str(), final_code, false);
@@ -312,7 +306,8 @@ class CppGenerator : public BaseGenerator {
code_.Clear();
code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
const auto include_guard = GenIncludeGuard(file_name_, *parser_.current_namespace_);
const auto include_guard =
GenIncludeGuard(file_name_, *parser_.current_namespace_);
code_ += "#ifndef " + include_guard;
code_ += "#define " + include_guard;
code_ += "";
@@ -582,12 +577,12 @@ class CppGenerator : public BaseGenerator {
// Close the include guard.
code_ += "#endif // " + include_guard;
const auto file_path = GeneratedFileName(path_, file_name_);
const auto file_path = GeneratedFileName(path_, file_name_, opts_);
const auto final_code = code_.ToString();
// Save the file and optionally generate the binary schema code.
return SaveFile(file_path.c_str(), final_code, false) &&
(!parser_.opts.binary_schema_gen_embed || generate_bfbs_embed());
(!parser_.opts.binary_schema_gen_embed || generate_bfbs_embed());
}
private:
@@ -625,9 +620,8 @@ class CppGenerator : public BaseGenerator {
return false;
}
bool VectorElementUserFacing(const Type& type) const {
return opts_.g_cpp_std >= cpp::CPP_STD_17 &&
opts_.g_only_fixed_enums &&
bool VectorElementUserFacing(const Type &type) const {
return opts_.g_cpp_std >= cpp::CPP_STD_17 && opts_.g_only_fixed_enums &&
IsEnum(type);
}
@@ -662,15 +656,15 @@ class CppGenerator : public BaseGenerator {
return "flatbuffers::String";
}
case BASE_TYPE_VECTOR: {
const auto type_name = GenTypeWire(type.VectorType(), "",
VectorElementUserFacing(type.VectorType()));
const auto type_name = GenTypeWire(
type.VectorType(), "", VectorElementUserFacing(type.VectorType()));
return "flatbuffers::Vector<" + type_name + ">";
}
case BASE_TYPE_STRUCT: {
return WrapInNameSpace(*type.struct_def);
}
case BASE_TYPE_UNION:
// fall through
// fall through
default: {
return "void";
}
@@ -1065,9 +1059,7 @@ class CppGenerator : public BaseGenerator {
GenComment(enum_def.doc_comment);
code_ +=
(opts_.scoped_enums ? "enum class " : "enum ") + Name(enum_def) + "\\";
if (opts_.g_only_fixed_enums) {
code_ += " : {{BASE_TYPE}}\\";
}
if (opts_.g_only_fixed_enums) { code_ += " : {{BASE_TYPE}}\\"; }
code_ += " {";
code_.SetValue("SEP", ",");
@@ -1912,9 +1904,7 @@ class CppGenerator : public BaseGenerator {
code_ += " typedef {{NATIVE_NAME}} NativeTableType;";
}
code_ += " typedef {{STRUCT_NAME}}Builder Builder;";
if (opts_.g_cpp_std >= cpp::CPP_STD_17) {
code_ += " struct Traits;";
}
if (opts_.g_cpp_std >= cpp::CPP_STD_17) { code_ += " struct Traits;"; }
if (opts_.mini_reflect != IDLOptions::kNone) {
code_ +=
" static const flatbuffers::TypeTable *MiniReflectTypeTable() {";
@@ -2329,8 +2319,8 @@ class CppGenerator : public BaseGenerator {
const auto type = WrapInNameSpace(*vtype.struct_def);
code_ += "_fbb.CreateVectorOfSortedTables<" + type + ">\\";
} else {
const auto type = GenTypeWire(
vtype, "", VectorElementUserFacing(vtype));
const auto type =
GenTypeWire(vtype, "", VectorElementUserFacing(vtype));
code_ += "_fbb.CreateVector<" + type + ">\\";
}
code_ +=
@@ -2362,8 +2352,7 @@ class CppGenerator : public BaseGenerator {
const char *vec_elem_access,
const char *vec_type_access) {
auto type_name = WrapInNameSpace(*afield.value.type.enum_def);
return type_name + "Union::UnPack(" + "_e" +
vec_elem_access + ", " +
return type_name + "Union::UnPack(" + "_e" + vec_elem_access + ", " +
EscapeKeyword(afield.name + UnionTypeFieldSuffix()) + "()" +
vec_type_access + ", _resolver)";
}
@@ -2553,22 +2542,24 @@ class CppGenerator : public BaseGenerator {
// For optional fields, check to see if there actually is any data
// in _o->field before attempting to access it. If there isn't,
// depending on set_empty_strings_to_null either set it to 0 or an empty string.
// depending on set_empty_strings_to_null either set it to 0 or an empty
// string.
if (!field.required) {
auto empty_value =
opts_.set_empty_strings_to_null ? "0" : "_fbb.CreateSharedString(\"\")";
auto empty_value = opts_.set_empty_strings_to_null
? "0"
: "_fbb.CreateSharedString(\"\")";
code = value + ".empty() ? " + empty_value + " : " + code;
}
break;
}
// Vector fields come in several flavours, of the forms:
// _fbb.CreateVector(_o->field);
// _fbb.CreateVector((const utype*)_o->field.data(), _o->field.size());
// _fbb.CreateVectorOfStrings(_o->field)
// _fbb.CreateVectorOfStructs(_o->field)
// _fbb.CreateVector<Offset<T>>(_o->field.size() [&](size_t i) {
// return CreateT(_fbb, _o->Get(i), rehasher);
// });
// Vector fields come in several flavours, of the forms:
// _fbb.CreateVector(_o->field);
// _fbb.CreateVector((const utype*)_o->field.data(),
// _o->field.size()); _fbb.CreateVectorOfStrings(_o->field)
// _fbb.CreateVectorOfStructs(_o->field)
// _fbb.CreateVector<Offset<T>>(_o->field.size() [&](size_t i) {
// return CreateT(_fbb, _o->Get(i), rehasher);
// });
case BASE_TYPE_VECTOR: {
auto vector_type = field.value.type.VectorType();
switch (vector_type.base_type) {
@@ -2659,9 +2650,9 @@ class CppGenerator : public BaseGenerator {
}
}
// If set_empty_vectors_to_null option is enabled, for optional fields, check to
// see if there actually is any data in _o->field before attempting to
// access it.
// If set_empty_vectors_to_null option is enabled, for optional fields,
// check to see if there actually is any data in _o->field before
// attempting to access it.
if (opts_.set_empty_vectors_to_null && !field.required) {
code = value + ".size() ? " + code + " : 0";
}
@@ -3120,8 +3111,10 @@ std::string CPPMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name) {
const auto filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
cpp::CppGenerator geneartor(parser, path, file_name, parser.opts);
const auto included_files = parser.GetIncludedFilesRecursive(file_name);
std::string make_rule = GeneratedFileName(path, filebase) + ": ";
std::string make_rule =
geneartor.GeneratedFileName(path, filebase, parser.opts) + ": ";
for (auto it = included_files.begin(); it != included_files.end(); ++it) {
make_rule += " " + *it;
}

View File

@@ -41,7 +41,7 @@ class CSharpGenerator : public BaseGenerator {
public:
CSharpGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "."),
: BaseGenerator(parser, path, file_name, "", ".", "cs"),
cur_name_space_(nullptr) {}
CSharpGenerator &operator=(const CSharpGenerator &);

View File

@@ -24,11 +24,6 @@
namespace flatbuffers {
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name) {
return path + file_name + "_generated.dart";
}
namespace dart {
const std::string _kFb = "fb";
@@ -55,7 +50,7 @@ class DartGenerator : public BaseGenerator {
DartGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", ".") {}
: BaseGenerator(parser, path, file_name, "", ".", "dart") {}
// Iterate through all definitions we haven't generate code for (enums,
// structs, and tables) and output them to a single file.
bool generate() {
@@ -84,21 +79,25 @@ class DartGenerator : public BaseGenerator {
for (auto kv2 = namespace_code.begin(); kv2 != namespace_code.end();
++kv2) {
if (kv2->first != kv->first) {
code += "import '" +
GeneratedFileName(
"./", file_name_ +
(!kv2->first.empty() ? "_" + kv2->first : "")) +
"' as " + ImportAliasName(kv2->first) + ";\n";
code +=
"import '" +
GeneratedFileName(
"./",
file_name_ + (!kv2->first.empty() ? "_" + kv2->first : ""),
parser_.opts) +
"' as " + ImportAliasName(kv2->first) + ";\n";
}
}
code += "\n";
code += kv->second;
if (!SaveFile(GeneratedFileName(
path_, file_name_ +
(!kv->first.empty() ? "_" + kv->first : ""))
.c_str(),
code, false)) {
if (!SaveFile(
GeneratedFileName(
path_,
file_name_ + (!kv->first.empty() ? "_" + kv->first : ""),
parser_.opts)
.c_str(),
code, false)) {
return false;
}
}
@@ -151,7 +150,8 @@ class DartGenerator : public BaseGenerator {
*code +=
"import '" +
GeneratedFileName(
"", basename + (the_namespace == "" ? "" : "_" + the_namespace)) +
"", basename + (the_namespace == "" ? "" : "_" + the_namespace),
parser_.opts) +
"';\n";
}
}
@@ -449,13 +449,13 @@ class DartGenerator : public BaseGenerator {
code += " final " + _kFb + ".BufferContext _bc;\n";
code += " final int _bcOffset;\n\n";
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields;
std::vector<std::pair<int, FieldDef *>> non_deprecated_fields;
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
if (field.deprecated) continue;
auto offset = static_cast<int>(it - struct_def.fields.vec.begin());
non_deprecated_fields.push_back(std::make_pair(offset, &field));
it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
if (field.deprecated) continue;
auto offset = static_cast<int>(it - struct_def.fields.vec.begin());
non_deprecated_fields.push_back(std::make_pair(offset, &field));
}
GenImplementationGetters(struct_def, non_deprecated_fields, &code);
@@ -464,7 +464,8 @@ class DartGenerator : public BaseGenerator {
GenReader(struct_def, &reader_name, &reader_code);
GenBuilder(struct_def, non_deprecated_fields, &builder_name, &builder_code);
GenObjectBuilder(struct_def, non_deprecated_fields, &object_builder_name, &builder_code);
GenObjectBuilder(struct_def, non_deprecated_fields, &object_builder_name,
&builder_code);
code += reader_code;
code += builder_code;
@@ -500,9 +501,10 @@ class DartGenerator : public BaseGenerator {
return ns + "." + parts.back();
}
void GenImplementationGetters(const StructDef &struct_def,
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields,
std::string *code_ptr) {
void GenImplementationGetters(
const StructDef &struct_def,
std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
std::string *code_ptr) {
auto &code = *code_ptr;
for (auto it = non_deprecated_fields.begin();
@@ -554,9 +556,12 @@ class DartGenerator : public BaseGenerator {
if (!field.value.constant.empty() && field.value.constant != "0") {
if (IsBool(field.value.type.base_type)) {
code += "true";
} else if (field.value.constant == "nan" || field.value.constant == "+nan" || field.value.constant == "-nan") {
} else if (field.value.constant == "nan" ||
field.value.constant == "+nan" ||
field.value.constant == "-nan") {
code += "double.nan";
} else if (field.value.constant == "inf" || field.value.constant == "+inf") {
} else if (field.value.constant == "inf" ||
field.value.constant == "+inf") {
code += "double.infinity";
} else if (field.value.constant == "-inf") {
code += "double.negativeInfinity";
@@ -626,9 +631,8 @@ class DartGenerator : public BaseGenerator {
}
void GenBuilder(const StructDef &struct_def,
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields,
std::string *builder_name_ptr,
std::string *code_ptr) {
std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
std::string *builder_name_ptr, std::string *code_ptr) {
if (non_deprecated_fields.size() == 0) { return; }
auto &code = *code_ptr;
auto &builder_name = *builder_name_ptr;
@@ -648,9 +652,10 @@ class DartGenerator : public BaseGenerator {
code += "}\n\n";
}
void StructBuilderBody(const StructDef &struct_def,
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields,
std::string *code_ptr) {
void StructBuilderBody(
const StructDef &struct_def,
std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
std::string *code_ptr) {
auto &code = *code_ptr;
code += " int finish(";
@@ -692,9 +697,10 @@ class DartGenerator : public BaseGenerator {
code += " }\n\n";
}
void TableBuilderBody(const StructDef &struct_def,
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields,
std::string *code_ptr) {
void TableBuilderBody(
const StructDef &struct_def,
std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
std::string *code_ptr) {
auto &code = *code_ptr;
code += " void begin() {\n";
@@ -736,10 +742,10 @@ class DartGenerator : public BaseGenerator {
code += " }\n";
}
void GenObjectBuilder(const StructDef &struct_def,
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields,
std::string *builder_name_ptr,
std::string *code_ptr) {
void GenObjectBuilder(
const StructDef &struct_def,
std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
std::string *builder_name_ptr, std::string *code_ptr) {
auto &code = *code_ptr;
auto &builder_name = *builder_name_ptr;
@@ -855,9 +861,9 @@ class DartGenerator : public BaseGenerator {
code += "}\n";
}
void StructObjectBuilderBody(std::vector<std::pair<int, FieldDef*>> non_deprecated_fields,
std::string *code_ptr,
bool prependUnderscore = true) {
void StructObjectBuilderBody(
std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
std::string *code_ptr, bool prependUnderscore = true) {
auto &code = *code_ptr;
for (auto it = non_deprecated_fields.rbegin();
@@ -885,9 +891,9 @@ class DartGenerator : public BaseGenerator {
code += " return fbBuilder.offset;\n";
}
void TableObjectBuilderBody(std::vector<std::pair<int, FieldDef*>> non_deprecated_fields,
std::string *code_ptr,
bool prependUnderscore = true) {
void TableObjectBuilderBody(
std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
std::string *code_ptr, bool prependUnderscore = true) {
std::string &code = *code_ptr;
code += " fbBuilder.startTable();\n";
@@ -936,7 +942,9 @@ std::string DartMakeRule(const Parser &parser, const std::string &path,
auto filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
auto make_rule = GeneratedFileName(path, filebase) + ": ";
dart::DartGenerator generator(parser, path, file_name);
auto make_rule =
generator.GeneratedFileName(path, file_name, parser.opts) + ": ";
auto included_files = parser.GetIncludedFilesRecursive(file_name);
for (auto it = included_files.begin(); it != included_files.end(); ++it) {

View File

@@ -99,7 +99,9 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
for (auto enum_def_it = parser.enums_.vec.begin();
enum_def_it != parser.enums_.vec.end(); ++enum_def_it) {
EnumDef &enum_def = **enum_def_it;
if (parser.opts.include_dependence_headers && enum_def.generated) { continue; }
if (parser.opts.include_dependence_headers && enum_def.generated) {
continue;
}
GenNameSpace(*enum_def.defined_namespace, &schema, &last_namespace);
GenComment(enum_def.doc_comment, &schema, nullptr);
if (enum_def.is_union)
@@ -121,7 +123,9 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
++it) {
StructDef &struct_def = **it;
if (parser.opts.include_dependence_headers && struct_def.generated) { continue; }
if (parser.opts.include_dependence_headers && struct_def.generated) {
continue;
}
GenNameSpace(*struct_def.defined_namespace, &schema, &last_namespace);
GenComment(struct_def.doc_comment, &schema, nullptr);
schema += "table " + struct_def.name + " {\n";

View File

@@ -35,11 +35,6 @@
namespace flatbuffers {
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name) {
return path + file_name + "_generated.go";
}
namespace go {
// see https://golang.org/ref/spec#Keywords
@@ -64,7 +59,7 @@ class GoGenerator : public BaseGenerator {
GoGenerator(const Parser &parser, const std::string &path,
const std::string &file_name, const std::string &go_namespace)
: BaseGenerator(parser, path, file_name, "" /* not used*/,
"" /* not used */),
"" /* not used */, "go"),
cur_name_space_(nullptr) {
std::istringstream iss(go_namespace);
std::string component;
@@ -112,7 +107,8 @@ class GoGenerator : public BaseGenerator {
const bool is_enum = !parser_.enums_.vec.empty();
BeginFile(LastNamespacePart(go_namespace_), true, is_enum, &code);
code += one_file_code;
const std::string filename = GeneratedFileName(path_, file_name_);
const std::string filename =
GeneratedFileName(path_, file_name_, parser_.opts);
return SaveFile(filename.c_str(), code, false);
}

View File

@@ -269,7 +269,7 @@ class GoGRPCGenerator : public flatbuffers::BaseGenerator {
public:
GoGRPCGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "" /*Unused*/),
: BaseGenerator(parser, path, file_name, "", "" /*Unused*/, "go"),
parser_(parser),
path_(path),
file_name_(file_name) {}
@@ -346,7 +346,7 @@ class JavaGRPCGenerator : public flatbuffers::BaseGenerator {
public:
JavaGRPCGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "." /*separator*/) {}
: BaseGenerator(parser, path, file_name, "", "." /*separator*/, "java") {}
bool generate() {
FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageJava);
@@ -415,7 +415,7 @@ class SwiftGRPCGenerator : public flatbuffers::BaseGenerator {
public:
SwiftGRPCGenerator(const Parser &parser, const std::string &path,
const std::string &filename)
: BaseGenerator(parser, path, filename, "", "" /*Unused*/) {}
: BaseGenerator(parser, path, filename, "", "" /*Unused*/, "swift") {}
bool generate() {
code_.Clear();

View File

@@ -42,7 +42,7 @@ class JavaGenerator : public BaseGenerator {
public:
JavaGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "."),
: BaseGenerator(parser, path, file_name, "", ".", "java"),
cur_name_space_(nullptr) {}
JavaGenerator &operator=(const JavaGenerator &);

View File

@@ -26,8 +26,6 @@
namespace flatbuffers {
const std::string kGeneratedFileNamePostfix = "_generated";
struct JsTsLanguageParameters {
IDLOptions::Language language;
std::string file_extension;
@@ -61,12 +59,6 @@ const JsTsLanguageParameters &GetJsLangParams(IDLOptions::Language lang) {
}
}
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name,
const JsTsLanguageParameters &lang) {
return path + file_name + kGeneratedFileNamePostfix + lang.file_extension;
}
namespace jsts {
// Iterate through all definitions we haven't generate code for (enums, structs,
// and tables) and output them to a single file.
@@ -78,7 +70,8 @@ class JsTsGenerator : public BaseGenerator {
JsTsGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "."),
: BaseGenerator(parser, path, file_name, "", ".",
parser.opts.lang == IDLOptions::kJs ? "js" : "ts"),
lang_(GetJsLangParams(parser_.opts.lang)) {}
// Iterate through all definitions we haven't generate code for (enums,
// structs, and tables) and output them to a single file.
@@ -112,8 +105,8 @@ class JsTsGenerator : public BaseGenerator {
code += exports_code;
}
return SaveFile(GeneratedFileName(path_, file_name_, lang_).c_str(), code,
false);
return SaveFile(GeneratedFileName(path_, file_name_, parser_.opts).c_str(),
code, false);
}
private:
@@ -524,10 +517,10 @@ class JsTsGenerator : public BaseGenerator {
if (parser_.opts.keep_include_path) {
auto it = parser_.included_files_.find(full_file_name);
FLATBUFFERS_ASSERT(it != parser_.included_files_.end());
path =
flatbuffers::StripExtension(it->second) + kGeneratedFileNamePostfix;
path = flatbuffers::StripExtension(it->second) +
parser_.opts.filename_suffix;
} else {
path = base_name + kGeneratedFileNamePostfix;
path = base_name + parser_.opts.filename_suffix;
}
// Add the include prefix and make the path always relative
@@ -601,7 +594,8 @@ class JsTsGenerator : public BaseGenerator {
}
std::string GenerateNewExpression(const std::string &object_name) {
return "new " + object_name + (lang_.language == IDLOptions::kTs ? "()" : "");
return "new " + object_name +
(lang_.language == IDLOptions::kTs ? "()" : "");
}
void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr,
@@ -624,7 +618,9 @@ class JsTsGenerator : public BaseGenerator {
code += " = function(bb, obj) {\n";
}
if (size_prefixed) {
code += " bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);\n";
code +=
" bb.setPosition(bb.position() + "
"flatbuffers.SIZE_PREFIX_LENGTH);\n";
}
code += " return (obj || " + GenerateNewExpression(object_name);
code += ").__init(bb.readInt32(bb.position()) + bb.position(), bb);\n";
@@ -870,7 +866,8 @@ class JsTsGenerator : public BaseGenerator {
code +=
MaybeAdd(field.value.offset) + ", " + GenBBAccess() + ");\n";
} else {
code += offset_prefix + "(obj || " + GenerateNewExpression(type) + ").__init(";
code += offset_prefix + "(obj || " + GenerateNewExpression(type) +
").__init(";
code += field.value.type.struct_def->fixed
? "this.bb_pos + offset"
: GenBBAccess() + ".__indirect(this.bb_pos + offset)";
@@ -952,7 +949,8 @@ class JsTsGenerator : public BaseGenerator {
}
if (vectortype.base_type == BASE_TYPE_STRUCT) {
code += offset_prefix + "(obj || " + GenerateNewExpression(vectortypename);
code += offset_prefix + "(obj || " +
GenerateNewExpression(vectortypename);
code += ").__init(";
code += vectortype.struct_def->fixed
? index
@@ -1388,11 +1386,12 @@ bool GenerateJSTS(const Parser &parser, const std::string &path,
std::string JSTSMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name) {
FLATBUFFERS_ASSERT(parser.opts.lang <= IDLOptions::kMAX);
const auto &lang = GetJsLangParams(parser.opts.lang);
std::string filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
std::string make_rule = GeneratedFileName(path, filebase, lang) + ": ";
jsts::JsTsGenerator generator(parser, path, file_name);
std::string make_rule =
generator.GeneratedFileName(path, filebase, parser.opts) + ": ";
auto included_files = parser.GetIncludedFilesRecursive(file_name);
for (auto it = included_files.begin(); it != included_files.end(); ++it) {

View File

@@ -22,11 +22,6 @@
namespace flatbuffers {
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name) {
return path + file_name + ".schema.json";
}
namespace jsons {
std::string GenNativeType(BaseType type) {
@@ -116,11 +111,18 @@ class JsonSchemaGenerator : public BaseGenerator {
public:
JsonSchemaGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "") {}
: BaseGenerator(parser, path, file_name, "", "", "json") {}
explicit JsonSchemaGenerator(const BaseGenerator &base_generator)
: BaseGenerator(base_generator) {}
std::string GeneratedFileName(const std::string &path,
const std::string &file_name,
const IDLOptions &options /* unused */) const {
(void)options;
return path + file_name + ".schema.json";
}
bool generate() {
if (parser_.root_struct_def_ == nullptr) { return false; }
code_.Clear();
@@ -203,7 +205,8 @@ class JsonSchemaGenerator : public BaseGenerator {
GenFullName(parser_.root_struct_def_) + "\"";
code_ += "}"; // close schema root
const std::string file_path = GeneratedFileName(path_, file_name_);
const std::string file_path =
GeneratedFileName(path_, file_name_, parser_.opts);
const std::string final_code = code_.ToString();
return SaveFile(file_path.c_str(), final_code, false);
}

View File

@@ -59,7 +59,7 @@ class KotlinGenerator : public BaseGenerator {
public:
KotlinGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "."),
: BaseGenerator(parser, path, file_name, "", ".", "kt"),
cur_name_space_(nullptr) {}
KotlinGenerator &operator=(const KotlinGenerator &);

View File

@@ -29,7 +29,8 @@ class LobsterGenerator : public BaseGenerator {
public:
LobsterGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "" /* not used */, "_") {
: BaseGenerator(parser, path, file_name, "" /* not used */, "_",
"lobster") {
static const char *const keywords[] = {
"nil", "true", "false", "return", "struct", "class",
"import", "int", "float", "string", "any", "def",
@@ -367,8 +368,8 @@ class LobsterGenerator : public BaseGenerator {
auto &struct_def = **it;
GenStruct(struct_def, &code);
}
return SaveFile((path_ + file_name_ + "_generated.lobster").c_str(), code,
false);
return SaveFile(GeneratedFileName(path_, file_name_, parser_.opts).c_str(),
code, false);
}
private:

View File

@@ -42,7 +42,7 @@ class LuaGenerator : public BaseGenerator {
LuaGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "" /* not used */,
"" /* not used */) {
"" /* not used */, "lua") {
static const char *const keywords[] = {
"and", "break", "do", "else", "elseif", "end", "false", "for",
"function", "goto", "if", "in", "local", "nil", "not", "or",

View File

@@ -31,7 +31,7 @@ class PhpGenerator : public BaseGenerator {
public:
PhpGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "\\", "\\") {}
: BaseGenerator(parser, path, file_name, "\\", "\\", "php") {}
bool generate() {
if (!GenerateEnums()) return false;
if (!GenerateStructs()) return false;

View File

@@ -39,7 +39,7 @@ class PythonGenerator : public BaseGenerator {
PythonGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "" /* not used */,
"" /* not used */),
"" /* not used */, "py"),
float_const_gen_("float('nan')", "float('inf')", "float('-inf')") {
static const char *const keywords[] = {
"False", "None", "True", "and", "as", "assert", "break",
@@ -139,8 +139,7 @@ class PythonGenerator : public BaseGenerator {
}
// Initialize an existing object with other data, to avoid an allocation.
void InitializeExisting(const StructDef &struct_def,
std::string *code_ptr) {
void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) {
auto &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
@@ -178,8 +177,7 @@ class PythonGenerator : public BaseGenerator {
// Get the value of a struct's scalar.
void GetScalarFieldOfStruct(const StructDef &struct_def,
const FieldDef &field,
std::string *code_ptr) {
const FieldDef &field, std::string *code_ptr) {
auto &code = *code_ptr;
std::string getter = GenGetter(field.value.type);
GenReceiver(struct_def, code_ptr);
@@ -216,8 +214,7 @@ class PythonGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct.
// Specific to Struct.
void GetStructFieldOfStruct(const StructDef &struct_def,
const FieldDef &field,
std::string *code_ptr) {
const FieldDef &field, std::string *code_ptr) {
auto &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field));
@@ -301,7 +298,8 @@ class PythonGenerator : public BaseGenerator {
// TODO(rw): this works and is not the good way to it:
bool is_native_table = TypeName(field) == "*flatbuffers.Table";
if (is_native_table) {
code += Indent + Indent + Indent + "from flatbuffers.table import Table\n";
code +=
Indent + Indent + Indent + "from flatbuffers.table import Table\n";
} else if (parser_.opts.include_dependence_headers) {
code += Indent + Indent + Indent;
code += "from " + GenPackageReference(field.value.type) + " import " +
@@ -330,8 +328,7 @@ class PythonGenerator : public BaseGenerator {
// Get the value of a vector's struct member.
void GetMemberOfVectorOfStruct(const StructDef &struct_def,
const FieldDef &field,
std::string *code_ptr) {
const FieldDef &field, std::string *code_ptr) {
auto &code = *code_ptr;
auto vectortype = field.value.type.VectorType();
@@ -412,8 +409,7 @@ class PythonGenerator : public BaseGenerator {
}
// Begin the creator function signature.
void BeginBuilderArgs(const StructDef &struct_def,
std::string *code_ptr) {
void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) {
auto &code = *code_ptr;
code += "\n";
@@ -447,9 +443,7 @@ class PythonGenerator : public BaseGenerator {
} else {
auto &code = *code_ptr;
code += std::string(", ") + nameprefix;
if (has_field_name) {
code += MakeCamel(NormalizedName(field), false);
}
if (has_field_name) { code += MakeCamel(NormalizedName(field), false); }
code += namesuffix;
}
}
@@ -517,8 +511,7 @@ class PythonGenerator : public BaseGenerator {
}
// Get the value of a table's starting offset.
void GetStartOfTable(const StructDef &struct_def,
std::string *code_ptr) {
void GetStartOfTable(const StructDef &struct_def, std::string *code_ptr) {
auto &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Start";
code += "(builder): ";
@@ -528,11 +521,11 @@ class PythonGenerator : public BaseGenerator {
}
// Set the value of a table's field.
void BuildFieldOfTable(const StructDef &struct_def,
const FieldDef &field, const size_t offset,
std::string *code_ptr) {
void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const size_t offset, std::string *code_ptr) {
auto &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Add" + MakeCamel(NormalizedName(field));
code += "def " + NormalizedName(struct_def) + "Add" +
MakeCamel(NormalizedName(field));
code += "(builder, ";
code += MakeCamel(NormalizedName(field), false);
code += "): ";
@@ -554,8 +547,8 @@ class PythonGenerator : public BaseGenerator {
}
// Set the value of one of the members of a table's vector.
void BuildVectorOfTable(const StructDef &struct_def,
const FieldDef &field, std::string *code_ptr) {
void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
std::string *code_ptr) {
auto &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Start";
code += MakeCamel(NormalizedName(field));
@@ -569,8 +562,7 @@ class PythonGenerator : public BaseGenerator {
}
// Get the offset of the end of a table.
void GetEndOffsetOnTable(const StructDef &struct_def,
std::string *code_ptr) {
void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
auto &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "End";
code += "(builder): ";
@@ -777,14 +769,9 @@ class PythonGenerator : public BaseGenerator {
import_list->insert("import " + package_reference);
}
break;
case BASE_TYPE_STRING:
field_type += "str";
break;
case BASE_TYPE_NONE:
field_type += "None";
break;
default:
break;
case BASE_TYPE_STRING: field_type += "str"; break;
case BASE_TYPE_NONE: field_type += "None"; break;
default: break;
}
field_types += field_type + separator_string;
}
@@ -806,8 +793,7 @@ class PythonGenerator : public BaseGenerator {
}
}
void GenStructInit(const FieldDef &field,
std::string *field_type_ptr,
void GenStructInit(const FieldDef &field, std::string *field_type_ptr,
std::set<std::string> *import_list,
std::set<std::string> *import_typing_list) {
import_typing_list->insert("Optional");
@@ -1118,8 +1104,7 @@ class PythonGenerator : public BaseGenerator {
GenUnPackForScalarVector(struct_def, field, &code);
break;
}
default:
GenUnPackForScalar(struct_def, field, &code);
default: GenUnPackForScalar(struct_def, field, &code);
}
}
@@ -1228,45 +1213,19 @@ class PythonGenerator : public BaseGenerator {
std::string type_name;
switch (vectortype.base_type) {
case BASE_TYPE_BOOL:
type_name = "Bool";
break;
case BASE_TYPE_CHAR:
type_name = "Byte";
break;
case BASE_TYPE_UCHAR:
type_name = "Uint8";
break;
case BASE_TYPE_SHORT:
type_name = "Int16";
break;
case BASE_TYPE_USHORT:
type_name = "Uint16";
break;
case BASE_TYPE_INT:
type_name = "Int32";
break;
case BASE_TYPE_UINT:
type_name = "Uint32";
break;
case BASE_TYPE_LONG:
type_name = "Int64";
break;
case BASE_TYPE_ULONG:
type_name = "Uint64";
break;
case BASE_TYPE_FLOAT:
type_name = "Float32";
break;
case BASE_TYPE_DOUBLE:
type_name = "Float64";
break;
case BASE_TYPE_STRING:
type_name = "UOffsetTRelative";
break;
default:
type_name = "VOffsetT";
break;
case BASE_TYPE_BOOL: type_name = "Bool"; break;
case BASE_TYPE_CHAR: type_name = "Byte"; break;
case BASE_TYPE_UCHAR: type_name = "Uint8"; break;
case BASE_TYPE_SHORT: type_name = "Int16"; break;
case BASE_TYPE_USHORT: type_name = "Uint16"; break;
case BASE_TYPE_INT: type_name = "Int32"; break;
case BASE_TYPE_UINT: type_name = "Uint32"; break;
case BASE_TYPE_LONG: type_name = "Int64"; break;
case BASE_TYPE_ULONG: type_name = "Uint64"; break;
case BASE_TYPE_FLOAT: type_name = "Float32"; break;
case BASE_TYPE_DOUBLE: type_name = "Float64"; break;
case BASE_TYPE_STRING: type_name = "UOffsetTRelative"; break;
default: type_name = "VOffsetT"; break;
}
code += type_name;
}
@@ -1527,8 +1486,7 @@ class PythonGenerator : public BaseGenerator {
case BASE_TYPE_STRING:
GenUnionCreatorForString(enum_def, ev, &code);
break;
default:
break;
default: break;
}
}
code += GenIndents(1) + "return None";

View File

@@ -23,11 +23,6 @@
namespace flatbuffers {
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name) {
return path + file_name + "_generated.rs";
}
// Convert a camelCaseIdentifier or CamelCaseIdentifier to a
// snake_case_indentifier.
std::string MakeSnakeCase(const std::string &in) {
@@ -188,7 +183,7 @@ class RustGenerator : public BaseGenerator {
public:
RustGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "::"),
: BaseGenerator(parser, path, file_name, "", "::", "rs"),
cur_name_space_(nullptr) {
const char *keywords[] = {
// list taken from:
@@ -292,7 +287,7 @@ class RustGenerator : public BaseGenerator {
}
if (cur_name_space_) SetNameSpace(nullptr);
const auto file_path = GeneratedFileName(path_, file_name_);
const auto file_path = GeneratedFileName(path_, file_name_, parser_.opts);
const auto final_code = code_.ToString();
return SaveFile(file_path.c_str(), final_code, false);
}
@@ -1329,16 +1324,17 @@ class RustGenerator : public BaseGenerator {
// If the user defined schemas name a field that clashes with a
// language reserved word, flatc will try to escape the field name by
// appending an underscore. This works well for most cases, except
// one. When generating union accessors (and referring to them
// one. When generating union accessors (and referring to them
// internally within the code generated here), an extra underscore
// will be appended to the name, causing build failures.
// will be appended to the name, causing build failures.
//
// This only happens when unions have members that overlap with
// language reserved words.
//
// language reserved words.
//
// To avoid this problem the type field name is used unescaped here:
code_ +=
" if self.{{FIELD_TYPE_FIELD_NAME}}_type() == {{U_ELEMENT_ENUM_TYPE}} {";
" if self.{{FIELD_TYPE_FIELD_NAME}}_type() == "
"{{U_ELEMENT_ENUM_TYPE}} {";
code_ +=
" self.{{FIELD_NAME}}().map(|u| "
"{{U_ELEMENT_TABLE_TYPE}}::init_from_table(u))";
@@ -1764,7 +1760,7 @@ class RustGenerator : public BaseGenerator {
std::string indent = std::string(white_spaces, ' ');
code_ += "";
for (auto it = parser_.included_files_.begin();
it != parser_.included_files_.end(); ++it) {
it != parser_.included_files_.end(); ++it) {
if (it->second.empty()) continue;
auto noext = flatbuffers::StripExtension(it->second);
auto basename = flatbuffers::StripPath(noext);
@@ -1834,7 +1830,9 @@ std::string RustMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name) {
std::string filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
std::string make_rule = GeneratedFileName(path, filebase) + ": ";
rust::RustGenerator generator(parser, path, file_name);
std::string make_rule =
generator.GeneratedFileName(path, filebase, parser.opts) + ": ";
auto included_files = parser.GetIncludedFilesRecursive(file_name);
for (auto it = included_files.begin(); it != included_files.end(); ++it) {

View File

@@ -49,7 +49,7 @@ class SwiftGenerator : public BaseGenerator {
public:
SwiftGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", "."),
: BaseGenerator(parser, path, file_name, "", ".", "swift"),
cur_name_space_(nullptr) {
namespace_depth = 0;
static const char *const keywords[] = {
@@ -181,7 +181,7 @@ class SwiftGenerator : public BaseGenerator {
if (cur_name_space_) SetNameSpace(nullptr);
const auto filename = GeneratedFileName(path_, file_name_);
const auto filename = GeneratedFileName(path_, file_name_, parser_.opts);
const auto final_code = code_.ToString();
return SaveFile(filename.c_str(), final_code, false);
}
@@ -843,10 +843,6 @@ class SwiftGenerator : public BaseGenerator {
return EscapeKeyword(MakeCamel(def.name, false));
}
static std::string GeneratedFileName(const std::string &path,
const std::string &file_name) {
return path + file_name + "_generated.swift";
}
// MARK: - Copied from the cpp implementation, needs revisiting
void SetNameSpace(const Namespace *ns) {
if (cur_name_space_ == ns) { return; }

View File

@@ -3231,8 +3231,8 @@ Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
// Is uint64>max(int64) tested?
IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0,
// result may be platform-dependent if underlying is float (not double)
IsFloat(value.type.base_type) ? d : 0.0,
deprecated, required, key, attr__, docs__);
IsFloat(value.type.base_type) ? d : 0.0, deprecated, required, key,
attr__, docs__);
// TODO: value.constant is almost always "0", we could save quite a bit of
// space by sharing it. Same for common values of value.type.
}

View File

@@ -274,5 +274,4 @@ void SetupDefaultCRTReportMode() {
// clang-format on
}
} // namespace flatbuffers

View File

@@ -49,6 +49,18 @@ $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS -o namespace_test namespace_te
../flatc --python $TEST_BASE_FLAGS arrays_test.fbs
../flatc --dart monster_extra.fbs
# Tests if the --filename-suffix and --filename-ext works and produces the same
# outputs.
../flatc --cpp --filename-suffix _suffix --filename-ext hpp $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS -I include_test monster_test.fbs
if [ -f "monster_test_suffix.hpp" ]; then
if ! cmp -s "monster_test_suffix.hpp" "monster_test_generated.h"; then
echo "[Error] Filename suffix option did not produce identical results"
fi
rm "monster_test_suffix.hpp"
else
echo "[Error] Filename suffix option did not produce a file"
fi
# Flag c++17 requires Clang6, GCC7, MSVC2017 (_MSC_VER >= 1914) or higher.
TEST_CPP17_FLAGS="--cpp --cpp-std c++17 -o ./cpp17/generated_cpp17 $TEST_NOINCL_FLAGS"
../flatc $TEST_CPP17_FLAGS -I include_test monster_test.fbs

View File

@@ -45,7 +45,7 @@
#include "test_assert.h"
#include "flatbuffers/flexbuffers.h"
#include "monster_test_bfbs_generated.h" // Generated using --bfbs-comments --bfbs-builtins --cpp --bfbs-gen-embed
#include "monster_test_bfbs_generated.h" // Generated using --bfbs-comments --bfbs-builtins --cpp --bfbs-gen-embed
// clang-format off
// Check that char* and uint8_t* are interoperable types.
@@ -1151,13 +1151,13 @@ void ParseProtoTestWithSuffix() {
flatbuffers::LoadFile((test_data_path + "prototest/test.proto").c_str(),
false, &protofile),
true);
TEST_EQ(
flatbuffers::LoadFile((test_data_path + "prototest/test_suffix.golden").c_str(),
false, &goldenfile),
true);
TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "prototest/test_union_suffix.golden").c_str(), false,
&goldenunionfile),
(test_data_path + "prototest/test_suffix.golden").c_str(), false,
&goldenfile),
true);
TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "prototest/test_union_suffix.golden").c_str(),
false, &goldenunionfile),
true);
flatbuffers::IDLOptions opts;
@@ -1204,17 +1204,17 @@ void ParseProtoTestWithIncludes() {
flatbuffers::LoadFile((test_data_path + "prototest/test.proto").c_str(),
false, &protofile),
true);
TEST_EQ(
flatbuffers::LoadFile((test_data_path + "prototest/imported.proto").c_str(),
false, &importprotofile),
true);
TEST_EQ(
flatbuffers::LoadFile((test_data_path + "prototest/test_include.golden").c_str(),
false, &goldenfile),
true);
TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "prototest/test_union_include.golden").c_str(), false,
&goldenunionfile),
(test_data_path + "prototest/imported.proto").c_str(), false,
&importprotofile),
true);
TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "prototest/test_include.golden").c_str(), false,
&goldenfile),
true);
TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "prototest/test_union_include.golden").c_str(),
false, &goldenunionfile),
true);
flatbuffers::IDLOptions opts;
@@ -1232,12 +1232,15 @@ void ParseProtoTestWithIncludes() {
// Generate fbs from import.proto
flatbuffers::Parser import_parser(opts);
TEST_EQ(import_parser.Parse(importprotofile.c_str(), include_directories), true);
TEST_EQ(import_parser.Parse(importprotofile.c_str(), include_directories),
true);
auto import_fbs = flatbuffers::GenerateFBS(import_parser, "test");
// Ensure generated file is parsable.
flatbuffers::Parser parser2;
TEST_EQ(parser2.Parse(import_fbs.c_str(), include_directories, "imported.fbs"), true);
TEST_EQ(
parser2.Parse(import_fbs.c_str(), include_directories, "imported.fbs"),
true);
TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
TEST_EQ_STR(fbs.c_str(), goldenfile.c_str());
@@ -1523,7 +1526,7 @@ void FuzzTest2() {
break;
}
}
TEST_NOTNULL(nullptr); //-V501 (this comment supresses CWE-570 warning)
TEST_NOTNULL(nullptr); //-V501 (this comment supresses CWE-570 warning)
}
// clang-format off
@@ -2444,68 +2447,72 @@ void InvalidNestedFlatbufferTest() {
void EvolutionTest() {
// VS10 does not support typed enums, exclude from tests
#if !defined(_MSC_VER) || _MSC_VER >= 1700
const int NUM_VERSIONS = 2;
std::string schemas[NUM_VERSIONS];
std::string jsonfiles[NUM_VERSIONS];
std::vector<uint8_t> binaries[NUM_VERSIONS];
const int NUM_VERSIONS = 2;
std::string schemas[NUM_VERSIONS];
std::string jsonfiles[NUM_VERSIONS];
std::vector<uint8_t> binaries[NUM_VERSIONS];
flatbuffers::IDLOptions idl_opts;
idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary;
flatbuffers::Parser parser(idl_opts);
flatbuffers::IDLOptions idl_opts;
idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary;
flatbuffers::Parser parser(idl_opts);
// Load all the schema versions and their associated data.
for (int i = 0; i < NUM_VERSIONS; ++i) {
std::string schema = test_data_path + "evolution_test/evolution_v" +
flatbuffers::NumToString(i + 1) + ".fbs";
TEST_ASSERT(flatbuffers::LoadFile(schema.c_str(), false, &schemas[i]));
std::string json = test_data_path + "evolution_test/evolution_v" +
flatbuffers::NumToString(i + 1) + ".json";
TEST_ASSERT(flatbuffers::LoadFile(json.c_str(), false, &jsonfiles[i]));
// Load all the schema versions and their associated data.
for (int i = 0; i < NUM_VERSIONS; ++i) {
std::string schema = test_data_path + "evolution_test/evolution_v" +
flatbuffers::NumToString(i + 1) + ".fbs";
TEST_ASSERT(flatbuffers::LoadFile(schema.c_str(), false, &schemas[i]));
std::string json = test_data_path + "evolution_test/evolution_v" +
flatbuffers::NumToString(i + 1) + ".json";
TEST_ASSERT(flatbuffers::LoadFile(json.c_str(), false, &jsonfiles[i]));
TEST_ASSERT(parser.Parse(schemas[i].c_str()));
TEST_ASSERT(parser.Parse(jsonfiles[i].c_str()));
TEST_ASSERT(parser.Parse(schemas[i].c_str()));
TEST_ASSERT(parser.Parse(jsonfiles[i].c_str()));
auto bufLen = parser.builder_.GetSize();
auto buf = parser.builder_.GetBufferPointer();
binaries[i].reserve(bufLen);
std::copy(buf, buf + bufLen, std::back_inserter(binaries[i]));
}
auto bufLen = parser.builder_.GetSize();
auto buf = parser.builder_.GetBufferPointer();
binaries[i].reserve(bufLen);
std::copy(buf, buf + bufLen, std::back_inserter(binaries[i]));
}
// Assert that all the verifiers for the different schema versions properly verify any version data.
for (int i = 0; i < NUM_VERSIONS; ++i) {
flatbuffers::Verifier verifier(&binaries[i].front(), binaries[i].size());
TEST_ASSERT(Evolution::V1::VerifyRootBuffer(verifier));
TEST_ASSERT(Evolution::V2::VerifyRootBuffer(verifier));
}
// Assert that all the verifiers for the different schema versions properly
// verify any version data.
for (int i = 0; i < NUM_VERSIONS; ++i) {
flatbuffers::Verifier verifier(&binaries[i].front(), binaries[i].size());
TEST_ASSERT(Evolution::V1::VerifyRootBuffer(verifier));
TEST_ASSERT(Evolution::V2::VerifyRootBuffer(verifier));
}
// Test backwards compatibility by reading old data with an evolved schema.
auto root_v1_viewed_from_v2 = Evolution::V2::GetRoot(&binaries[0].front());
// field 'j' is new in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->j());
// field 'k' is new in version 2 with a default of 56.
TEST_EQ(root_v1_viewed_from_v2->k(), 56);
// field 'c' of 'TableA' is new in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->e()->c());
// 'TableC' was added to field 'c' union in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->c_as_TableC());
// The field 'c' union should be of type 'TableB' regardless of schema version
TEST_ASSERT(root_v1_viewed_from_v2->c_type() == Evolution::V2::Union::TableB);
// The field 'f' was renamed to 'ff' in version 2, it should still be readable.
TEST_EQ(root_v1_viewed_from_v2->ff()->a(), 16);
// Test backwards compatibility by reading old data with an evolved schema.
auto root_v1_viewed_from_v2 = Evolution::V2::GetRoot(&binaries[0].front());
// field 'j' is new in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->j());
// field 'k' is new in version 2 with a default of 56.
TEST_EQ(root_v1_viewed_from_v2->k(), 56);
// field 'c' of 'TableA' is new in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->e()->c());
// 'TableC' was added to field 'c' union in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->c_as_TableC());
// The field 'c' union should be of type 'TableB' regardless of schema version
TEST_ASSERT(root_v1_viewed_from_v2->c_type() == Evolution::V2::Union::TableB);
// The field 'f' was renamed to 'ff' in version 2, it should still be
// readable.
TEST_EQ(root_v1_viewed_from_v2->ff()->a(), 16);
// Test forwards compatibility by reading new data with an old schema.
auto root_v2_viewed_from_v1 = Evolution::V1::GetRoot(&binaries[1].front());
// The field 'c' union in version 2 is a new table (index = 3) and should still be accessible,
// but not interpretable.
TEST_EQ(static_cast<uint8_t>(root_v2_viewed_from_v1->c_type()), 3);
TEST_NOTNULL(root_v2_viewed_from_v1->c());
// The field 'd' enum in verison 2 has new members and should still be accessible, but not interpretable.
TEST_EQ(static_cast<int8_t>(root_v2_viewed_from_v1->d()), 3);
// The field 'a' in version 2 is deprecated and should return the default value (0) instead of the value stored in
// the in the buffer (42).
TEST_EQ(root_v2_viewed_from_v1->a(), 0);
// The field 'ff' was originally named 'f' in version 1, it should still be readable.
TEST_EQ(root_v2_viewed_from_v1->f()->a(), 35);
// Test forwards compatibility by reading new data with an old schema.
auto root_v2_viewed_from_v1 = Evolution::V1::GetRoot(&binaries[1].front());
// The field 'c' union in version 2 is a new table (index = 3) and should
// still be accessible, but not interpretable.
TEST_EQ(static_cast<uint8_t>(root_v2_viewed_from_v1->c_type()), 3);
TEST_NOTNULL(root_v2_viewed_from_v1->c());
// The field 'd' enum in verison 2 has new members and should still be
// accessible, but not interpretable.
TEST_EQ(static_cast<int8_t>(root_v2_viewed_from_v1->d()), 3);
// The field 'a' in version 2 is deprecated and should return the default
// value (0) instead of the value stored in the in the buffer (42).
TEST_EQ(root_v2_viewed_from_v1->a(), 0);
// The field 'ff' was originally named 'f' in version 1, it should still be
// readable.
TEST_EQ(root_v2_viewed_from_v1->f()->a(), 35);
#endif
}
@@ -3290,45 +3297,51 @@ void FixedLengthArrayJsonTest(bool binary) {
}
void TestEmbeddedBinarySchema() {
// load JSON from disk
std::string jsonfile;
TEST_EQ(flatbuffers::LoadFile((test_data_path + "monsterdata_test.golden").c_str(),
false, &jsonfile), true);
// load JSON from disk
std::string jsonfile;
TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "monsterdata_test.golden").c_str(), false,
&jsonfile),
true);
// parse schema first, so we can use it to parse the data after
flatbuffers::Parser parserOrg, parserGen;
flatbuffers::Verifier verifier(MyGame::Example::MonsterBinarySchema::data(),
MyGame::Example::MonsterBinarySchema::size());
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
TEST_EQ(parserOrg.Deserialize(MyGame::Example::MonsterBinarySchema::data(),
MyGame::Example::MonsterBinarySchema::size()), true);
TEST_EQ(parserGen.Deserialize(MyGame::Example::MonsterBinarySchema::data(),
MyGame::Example::MonsterBinarySchema::size()), true);
TEST_EQ(parserOrg.Parse(jsonfile.c_str()), true);
// parse schema first, so we can use it to parse the data after
flatbuffers::Parser parserOrg, parserGen;
flatbuffers::Verifier verifier(MyGame::Example::MonsterBinarySchema::data(),
MyGame::Example::MonsterBinarySchema::size());
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
TEST_EQ(parserOrg.Deserialize(MyGame::Example::MonsterBinarySchema::data(),
MyGame::Example::MonsterBinarySchema::size()),
true);
TEST_EQ(parserGen.Deserialize(MyGame::Example::MonsterBinarySchema::data(),
MyGame::Example::MonsterBinarySchema::size()),
true);
TEST_EQ(parserOrg.Parse(jsonfile.c_str()), true);
// First, verify it, just in case:
flatbuffers::Verifier verifierOrg(parserOrg.builder_.GetBufferPointer(),
parserOrg.builder_.GetSize());
TEST_EQ(VerifyMonsterBuffer(verifierOrg), true);
// First, verify it, just in case:
flatbuffers::Verifier verifierOrg(parserOrg.builder_.GetBufferPointer(),
parserOrg.builder_.GetSize());
TEST_EQ(VerifyMonsterBuffer(verifierOrg), true);
// Export to JSON
std::string jsonGen;
TEST_EQ(GenerateText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen), true);
// Export to JSON
std::string jsonGen;
TEST_EQ(
GenerateText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen),
true);
// Import from JSON
TEST_EQ(parserGen.Parse(jsonGen.c_str()), true);
// Import from JSON
TEST_EQ(parserGen.Parse(jsonGen.c_str()), true);
// Verify buffer from generated JSON
flatbuffers::Verifier verifierGen(parserGen.builder_.GetBufferPointer(),
parserGen.builder_.GetSize());
TEST_EQ(VerifyMonsterBuffer(verifierGen), true);
// Verify buffer from generated JSON
flatbuffers::Verifier verifierGen(parserGen.builder_.GetBufferPointer(),
parserGen.builder_.GetSize());
TEST_EQ(VerifyMonsterBuffer(verifierGen), true);
// Compare generated buffer to original
TEST_EQ(parserOrg.builder_.GetSize(), parserGen.builder_.GetSize());
TEST_EQ(std::memcmp(parserOrg.builder_.GetBufferPointer(),
parserGen.builder_.GetBufferPointer(),
parserOrg.builder_.GetSize()),
0);
// Compare generated buffer to original
TEST_EQ(parserOrg.builder_.GetSize(), parserGen.builder_.GetSize());
TEST_EQ(std::memcmp(parserOrg.builder_.GetBufferPointer(),
parserGen.builder_.GetBufferPointer(),
parserOrg.builder_.GetSize()),
0);
}
int FlatBufferTests() {

View File

@@ -26,7 +26,9 @@ void TestFail(const char *expval, const char *val, const char *exp,
void TestEqStr(const char *expval, const char *val, const char *exp,
const char *file, int line, const char *func) {
if (strcmp(expval, val) != 0) { TestFail(expval, val, exp, file, line, func); }
if (strcmp(expval, val) != 0) {
TestFail(expval, val, exp, file, line, func);
}
}
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && defined(_MSC_VER) && \

View File

@@ -155,5 +155,4 @@ void FlatBufferBuilderTest() {
}
// Link-time check using pointer type.
void CheckTestGeneratedIsValid(const MyGame::Example::Color&)
{}
void CheckTestGeneratedIsValid(const MyGame::Example::Color &) {}