Commit cfb4ecf6 authored by Paulo Pinheiro's avatar Paulo Pinheiro Committed by Wouter van Oortmerssen

[flac] Add FlexBuffers option for generating data (#5519)

Alongside --binary and --json, an additional
switch (--flexbuffers) can be passed to convert
data using FlexBuffers
parent a9203968
...@@ -349,6 +349,12 @@ void AppendToString(std::string &s, T &&v, bool keys_quoted) { ...@@ -349,6 +349,12 @@ void AppendToString(std::string &s, T &&v, bool keys_quoted) {
class Reference { class Reference {
public: public:
Reference()
: data_(nullptr),
parent_width_(0),
byte_width_(BIT_WIDTH_8),
type_(FBT_NULL) {}
Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width, Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
Type type) Type type)
: data_(data), : data_(data),
......
...@@ -491,6 +491,8 @@ struct ServiceDef : public Definition { ...@@ -491,6 +491,8 @@ struct ServiceDef : public Definition {
// Container of options that may apply to any of the source/text generators. // Container of options that may apply to any of the source/text generators.
struct IDLOptions { struct IDLOptions {
// Use flexbuffers instead for binary and text generation
bool use_flexbuffers;
bool strict_json; bool strict_json;
bool skip_js_exports; bool skip_js_exports;
bool use_goog_js_export_format; bool use_goog_js_export_format;
...@@ -573,7 +575,8 @@ struct IDLOptions { ...@@ -573,7 +575,8 @@ struct IDLOptions {
bool set_empty_to_null; bool set_empty_to_null;
IDLOptions() IDLOptions()
: strict_json(false), : use_flexbuffers(false),
strict_json(false),
skip_js_exports(false), skip_js_exports(false),
use_goog_js_export_format(false), use_goog_js_export_format(false),
use_ES6_js_export_format(false), use_ES6_js_export_format(false),
...@@ -707,6 +710,7 @@ class Parser : public ParserState { ...@@ -707,6 +710,7 @@ class Parser : public ParserState {
explicit Parser(const IDLOptions &options = IDLOptions()) explicit Parser(const IDLOptions &options = IDLOptions())
: current_namespace_(nullptr), : current_namespace_(nullptr),
empty_namespace_(nullptr), empty_namespace_(nullptr),
flex_builder_(256, flexbuffers::BUILDER_FLAG_SHARE_ALL),
root_struct_def_(nullptr), root_struct_def_(nullptr),
opts(options), opts(options),
uses_flexbuffers_(false), uses_flexbuffers_(false),
...@@ -908,6 +912,8 @@ class Parser : public ParserState { ...@@ -908,6 +912,8 @@ class Parser : public ParserState {
std::string error_; // User readable error_ if Parse() == false std::string error_; // User readable error_ if Parse() == false
FlatBufferBuilder builder_; // any data contained in the file FlatBufferBuilder builder_; // any data contained in the file
flexbuffers::Builder flex_builder_;
flexbuffers::Reference flex_root_;
StructDef *root_struct_def_; StructDef *root_struct_def_;
std::string file_identifier_; std::string file_identifier_;
std::string file_extension_; std::string file_extension_;
......
...@@ -149,6 +149,8 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const { ...@@ -149,6 +149,8 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
" --force-defaults Emit default values in binary output from JSON\n" " --force-defaults Emit default values in binary output from JSON\n"
" --force-empty When serializing from object API representation,\n" " --force-empty When serializing from object API representation,\n"
" force strings and vectors to empty rather than null.\n" " force strings and vectors to empty rather than null.\n"
" --flexbuffers Used with \"binary\" and \"json\" options, it generates\n"
" data using schema-less FlexBuffers.\n"
"FILEs may be schemas (must end in .fbs), binary schemas (must end in .bfbs),\n" "FILEs may be schemas (must end in .fbs), binary schemas (must end in .bfbs),\n"
"or JSON files (conforming to preceding schema). FILEs after the -- must be\n" "or JSON files (conforming to preceding schema). FILEs after the -- must be\n"
"binary flatbuffer format files.\n" "binary flatbuffer format files.\n"
...@@ -324,6 +326,8 @@ int FlatCompiler::Compile(int argc, const char **argv) { ...@@ -324,6 +326,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
opts.set_empty_to_null = false; opts.set_empty_to_null = false;
} else if (arg == "--java-primitive-has-method") { } else if (arg == "--java-primitive-has-method") {
opts.java_primitive_has_method = true; opts.java_primitive_has_method = true;
} else if (arg == "--flexbuffers") {
opts.use_flexbuffers = true;
} else { } else {
for (size_t i = 0; i < params_.num_generators; ++i) { for (size_t i = 0; i < params_.num_generators; ++i) {
if (arg == params_.generators[i].generator_opt_long || if (arg == params_.generators[i].generator_opt_long ||
...@@ -407,7 +411,8 @@ int FlatCompiler::Compile(int argc, const char **argv) { ...@@ -407,7 +411,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
} }
} else { } else {
// Check if file contains 0 bytes. // Check if file contains 0 bytes.
if (!is_binary_schema && contents.length() != strlen(contents.c_str())) { if (!opts.use_flexbuffers && !is_binary_schema &&
contents.length() != strlen(contents.c_str())) {
Error("input file appears to be binary: " + filename, true); Error("input file appears to be binary: " + filename, true);
} }
if (is_schema) { if (is_schema) {
...@@ -418,9 +423,20 @@ int FlatCompiler::Compile(int argc, const char **argv) { ...@@ -418,9 +423,20 @@ int FlatCompiler::Compile(int argc, const char **argv) {
} }
if (is_binary_schema) { if (is_binary_schema) {
LoadBinarySchema(*parser.get(), filename, contents); LoadBinarySchema(*parser.get(), filename, contents);
}
if (opts.use_flexbuffers) {
if (opts.lang_to_generate == IDLOptions::kJson) {
parser->flex_root_ = flexbuffers::GetRoot(
reinterpret_cast<const uint8_t *>(contents.c_str()),
contents.size());
} else {
parser->flex_builder_.Clear();
ParseFile(*parser.get(), filename, contents, include_directories);
}
} else { } else {
ParseFile(*parser.get(), filename, contents, include_directories); ParseFile(*parser.get(), filename, contents, include_directories);
if (!is_schema && !parser->builder_.GetSize()) { if (!opts.use_flexbuffers && !is_schema &&
!parser->builder_.GetSize()) {
// If a file doesn't end in .fbs, it must be json/binary. Ensure we // If a file doesn't end in .fbs, it must be json/binary. Ensure we
// didn't just parse a schema with a different extension. // didn't just parse a schema with a different extension.
Error("input file is neither json nor a .fbs (schema) file: " + Error("input file is neither json nor a .fbs (schema) file: " +
......
...@@ -1782,6 +1782,14 @@ std::string BinaryFileName(const Parser &parser, const std::string &path, ...@@ -1782,6 +1782,14 @@ std::string BinaryFileName(const Parser &parser, const std::string &path,
bool GenerateBinary(const Parser &parser, const std::string &path, bool GenerateBinary(const Parser &parser, const std::string &path,
const std::string &file_name) { const std::string &file_name) {
if (parser.opts.use_flexbuffers) {
auto data_vec = parser.flex_builder_.GetBuffer();
auto data_ptr = reinterpret_cast<char *>(data_vec.data());
return !parser.flex_builder_.GetSize() ||
flatbuffers::SaveFile(
BinaryFileName(parser, path, file_name).c_str(), data_ptr,
parser.flex_builder_.GetSize(), true);
}
return !parser.builder_.GetSize() || return !parser.builder_.GetSize() ||
flatbuffers::SaveFile( flatbuffers::SaveFile(
BinaryFileName(parser, path, file_name).c_str(), BinaryFileName(parser, path, file_name).c_str(),
......
...@@ -365,6 +365,12 @@ std::string TextFileName(const std::string &path, ...@@ -365,6 +365,12 @@ std::string TextFileName(const std::string &path,
bool GenerateTextFile(const Parser &parser, const std::string &path, bool GenerateTextFile(const Parser &parser, const std::string &path,
const std::string &file_name) { const std::string &file_name) {
if (parser.opts.use_flexbuffers) {
std::string json;
parser.flex_root_.ToString(true, parser.opts.strict_json, json);
return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(),
json.c_str(), json.size(), true);
}
if (!parser.builder_.GetSize() || !parser.root_struct_def_) return true; if (!parser.builder_.GetSize() || !parser.root_struct_def_) return true;
std::string text; std::string text;
if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &text)) { if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &text)) {
......
...@@ -2710,7 +2710,13 @@ bool Parser::ParseFlexBuffer(const char *source, const char *source_filename, ...@@ -2710,7 +2710,13 @@ bool Parser::ParseFlexBuffer(const char *source, const char *source_filename,
bool Parser::Parse(const char *source, const char **include_paths, bool Parser::Parse(const char *source, const char **include_paths,
const char *source_filename) { const char *source_filename) {
FLATBUFFERS_ASSERT(0 == recurse_protection_counter); FLATBUFFERS_ASSERT(0 == recurse_protection_counter);
auto r = !ParseRoot(source, include_paths, source_filename).Check(); bool r;
if (opts.use_flexbuffers) {
r = ParseFlexBuffer(source, source_filename, &flex_builder_);
} else {
r = !ParseRoot(source, include_paths, source_filename).Check();
}
FLATBUFFERS_ASSERT(0 == recurse_protection_counter); FLATBUFFERS_ASSERT(0 == recurse_protection_counter);
return r; return r;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment