forked from BigfootDev/flatbuffers
Mutable FlatBuffers: in-place updates.
This commit contains the first step in providing mutable FlatBuffers, non-const accessors and mutation functions for existing fields generated from --gen-mutable. Change-Id: Iebee3975f05c1001f8e22824725edeaa6d85fbee Tested: on Linux. Bug: 15777024
This commit is contained in:
@@ -221,22 +221,41 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
|
||||
++it) {
|
||||
auto &field = **it;
|
||||
if (!field.deprecated) { // Deprecated fields won't be accessible.
|
||||
auto is_scalar = IsScalar(field.value.type.base_type);
|
||||
GenComment(field.doc_comment, code_ptr, nullptr, " ");
|
||||
code += " " + GenTypeGet(parser, field.value.type, " ", "const ", " *",
|
||||
true);
|
||||
code += field.name + "() const { return ";
|
||||
// Call a different accessor for pointers, that indirects.
|
||||
std::string call = IsScalar(field.value.type.base_type)
|
||||
auto accessor = is_scalar
|
||||
? "GetField<"
|
||||
: (IsStruct(field.value.type) ? "GetStruct<" : "GetPointer<");
|
||||
call += GenTypeGet(parser, field.value.type, "", "const ", " *", false);
|
||||
call += ">(" + NumToString(field.value.offset);
|
||||
auto offsetstr = NumToString(field.value.offset);
|
||||
auto call =
|
||||
accessor +
|
||||
GenTypeGet(parser, field.value.type, "", "const ", " *", false) +
|
||||
">(" + offsetstr;
|
||||
// Default value as second arg for non-pointer types.
|
||||
if (IsScalar(field.value.type.base_type))
|
||||
call += ", " + field.value.constant;
|
||||
call += ")";
|
||||
code += GenUnderlyingCast(parser, field, true, call);
|
||||
code += "; }\n";
|
||||
if (opts.mutable_buffer) {
|
||||
if (is_scalar) {
|
||||
code += " bool mutate_" + field.name + "(";
|
||||
code += GenTypeBasic(parser, field.value.type, true);
|
||||
code += " " + field.name + ") { return SetField(" + offsetstr + ", ";
|
||||
code += GenUnderlyingCast(parser, field, false, field.name);
|
||||
code += "); }\n";
|
||||
} else {
|
||||
auto type = GenTypeGet(parser, field.value.type, " ", "", " *", true);
|
||||
code += " " + type + "mutable_" + field.name + "() { return ";
|
||||
code += GenUnderlyingCast(parser, field, true,
|
||||
accessor + type + ">(" + offsetstr + ")");
|
||||
code += "; }\n";
|
||||
}
|
||||
}
|
||||
auto nested = field.attributes.Lookup("nested_flatbuffer");
|
||||
if (nested) {
|
||||
auto nested_root = parser.structs_.Lookup(nested->constant);
|
||||
@@ -416,7 +435,8 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
|
||||
code += " return builder_.Finish();\n}\n\n";
|
||||
}
|
||||
|
||||
static void GenPadding(const FieldDef &field, const std::function<void (int bits)> &f) {
|
||||
static void GenPadding(const FieldDef &field,
|
||||
const std::function<void (int bits)> &f) {
|
||||
if (field.padding) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (static_cast<int>(field.padding) & (1 << i))
|
||||
@@ -427,7 +447,7 @@ static void GenPadding(const FieldDef &field, const std::function<void (int bits
|
||||
|
||||
// Generate an accessor struct with constructor for a flatbuffers struct.
|
||||
static void GenStruct(const Parser &parser, StructDef &struct_def,
|
||||
std::string *code_ptr) {
|
||||
const GeneratorOptions &opts, std::string *code_ptr) {
|
||||
if (struct_def.generated) return;
|
||||
std::string &code = *code_ptr;
|
||||
|
||||
@@ -502,14 +522,30 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
|
||||
++it) {
|
||||
auto &field = **it;
|
||||
GenComment(field.doc_comment, code_ptr, nullptr, " ");
|
||||
auto is_scalar = IsScalar(field.value.type.base_type);
|
||||
code += " " + GenTypeGet(parser, field.value.type, " ", "const ", " &",
|
||||
true);
|
||||
code += field.name + "() const { return ";
|
||||
code += GenUnderlyingCast(parser, field, true,
|
||||
IsScalar(field.value.type.base_type)
|
||||
is_scalar
|
||||
? "flatbuffers::EndianScalar(" + field.name + "_)"
|
||||
: field.name + "_");
|
||||
code += "; }\n";
|
||||
if (opts.mutable_buffer) {
|
||||
if (is_scalar) {
|
||||
code += " void mutate_" + field.name + "(";
|
||||
code += GenTypeBasic(parser, field.value.type, true);
|
||||
code += " " + field.name + ") { flatbuffers::WriteScalar(&";
|
||||
code += field.name + "_, ";
|
||||
code += GenUnderlyingCast(parser, field, false, field.name);
|
||||
code += "); }\n";
|
||||
} else {
|
||||
code += " ";
|
||||
code += GenTypeGet(parser, field.value.type, "", "", " &", true);
|
||||
code += "mutable_" + field.name + "() { return " + field.name;
|
||||
code += "_; }\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
code += "};\nSTRUCT_END(" + struct_def.name + ", ";
|
||||
code += NumToString(struct_def.bytesize) + ");\n\n";
|
||||
@@ -581,7 +617,7 @@ std::string GenerateCPP(const Parser &parser,
|
||||
std::string decl_code;
|
||||
for (auto it = parser.structs_.vec.begin();
|
||||
it != parser.structs_.vec.end(); ++it) {
|
||||
if ((**it).fixed) GenStruct(parser, **it, &decl_code);
|
||||
if ((**it).fixed) GenStruct(parser, **it, opts, &decl_code);
|
||||
}
|
||||
for (auto it = parser.structs_.vec.begin();
|
||||
it != parser.structs_.vec.end(); ++it) {
|
||||
@@ -654,6 +690,12 @@ std::string GenerateCPP(const Parser &parser,
|
||||
code += name;
|
||||
code += "(const void *buf) { return flatbuffers::GetRoot<";
|
||||
code += name + ">(buf); }\n\n";
|
||||
if (opts.mutable_buffer) {
|
||||
code += "inline " + name + " *GetMutable";
|
||||
code += name;
|
||||
code += "(void *buf) { return flatbuffers::GetMutableRoot<";
|
||||
code += name + ">(buf); }\n\n";
|
||||
}
|
||||
|
||||
// The root verifier:
|
||||
code += "inline bool Verify";
|
||||
|
||||
Reference in New Issue
Block a user