mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-02 12:05:50 +00:00
Make string/vector field serialization order not depend on optimizer.
Multiple calls of e.g. CreateString inside a call to a CreateTable could cause those strings to end up in different locations in the wire format, since order or argument evaluation is undefined. This is allowed by the FlatBuffer format, but it is not helpful, especially when debugging the contents of binaries, or comparing against a "golden" binary for tests etc. Now making sure that all the CreateTableDirect calls first serialize sub strings/vectors before calling CreateTable. Also made similar changes to the serialization of "binary schemas". Change-Id: I5747c4038b37a0d400aca2bc592bec751cf5c172
This commit is contained in:
@@ -2060,36 +2060,30 @@ class CppGenerator : public BaseGenerator {
|
||||
|
||||
// Generate a CreateXDirect function with vector types as parameters
|
||||
if (has_string_or_vector_fields) {
|
||||
code_ +=
|
||||
"inline flatbuffers::Offset<{{STRUCT_NAME}}> "
|
||||
"Create{{STRUCT_NAME}}Direct(";
|
||||
code_ += "inline flatbuffers::Offset<{{STRUCT_NAME}}> "
|
||||
"Create{{STRUCT_NAME}}Direct(";
|
||||
code_ += " flatbuffers::FlatBufferBuilder &_fbb\\";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
const auto &field = **it;
|
||||
if (!field.deprecated) { GenParam(field, true, ",\n "); }
|
||||
}
|
||||
|
||||
// Need to call "Create" with the struct namespace.
|
||||
const auto qualified_create_name =
|
||||
struct_def.defined_namespace->GetFullyQualifiedName("Create");
|
||||
code_.SetValue("CREATE_NAME", TranslateNameSpace(qualified_create_name));
|
||||
|
||||
code_ += ") {";
|
||||
code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}(";
|
||||
code_ += " _fbb\\";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
const auto &field = **it;
|
||||
if (!field.deprecated) {
|
||||
code_.SetValue("FIELD_NAME", Name(field));
|
||||
|
||||
if (field.value.type.base_type == BASE_TYPE_STRING) {
|
||||
code_ +=
|
||||
",\n {{FIELD_NAME}} ? "
|
||||
"_fbb.CreateString({{FIELD_NAME}}) : 0\\";
|
||||
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
|
||||
"_fbb.CreateString({{FIELD_NAME}}) : 0;";
|
||||
} else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
|
||||
code_ += ",\n {{FIELD_NAME}} ? \\";
|
||||
code_ += " auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? \\";
|
||||
const auto vtype = field.value.type.VectorType();
|
||||
if (IsStruct(vtype)) {
|
||||
const auto type = WrapInNameSpace(*vtype.struct_def);
|
||||
@@ -2098,9 +2092,21 @@ class CppGenerator : public BaseGenerator {
|
||||
const auto type = GenTypeWire(vtype, "", false);
|
||||
code_ += "_fbb.CreateVector<" + type + ">\\";
|
||||
}
|
||||
code_ += "(*{{FIELD_NAME}}) : 0\\";
|
||||
} else {
|
||||
code_ += ",\n {{FIELD_NAME}}\\";
|
||||
code_ += "(*{{FIELD_NAME}}) : 0;";
|
||||
}
|
||||
}
|
||||
}
|
||||
code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}(";
|
||||
code_ += " _fbb\\";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
const auto &field = **it;
|
||||
if (!field.deprecated) {
|
||||
code_.SetValue("FIELD_NAME", Name(field));
|
||||
code_ += ",\n {{FIELD_NAME}}\\";
|
||||
if (field.value.type.base_type == BASE_TYPE_STRING ||
|
||||
field.value.type.base_type == BASE_TYPE_VECTOR) {
|
||||
code_ += "__\\";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user