forked from BigfootDev/flatbuffers
[flac] Add FlexBuffers option for generating data (#5519)
Alongside --binary and --json, an additional switch (--flexbuffers) can be passed to convert data using FlexBuffers
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
a92039687a
commit
cfb4ecf6f0
@@ -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 {
|
|||||||
|
|
||||||
// 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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
" --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) {
|
|||||||
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) {
|
|||||||
}
|
}
|
||||||
} 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) {
|
|||||||
}
|
}
|
||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user