If I am going to modify a flatbuffer, the recommended way is to deserialize the contents and then re-serialize the contents. Fine. But I am hoping there is some way to avoid going all the way to the deepest levels.
I have a table that contains two subtables and a string. I want to modify that string. Is there some way to initialize the builder with the flattened bytes of the first two tables directly lifted out of the existing buffer without recreating them?
I am hoping for something like this:
table Alpha {
... contents ...
}
table Beta {
... contents ...
}
table Alphabet {
alpha:Alpha;
beta:Beta;
comment:string;
}
Assuming that raw_data is a uint8_t array of flattened form of Alphabet:
const auto* current = GetAlphabet(raw_data);
flatbuffers::FlatBufferBuilder builder;
builder.CreateAlphabetDirect(builder,
current->alpha(), // somehow get the bytes
current->beta(), // for alpha & beta here
// and just copy them over.
"NewString");
You can't get just the bytes for a sub-table like Alpha
, as the data may be discontinuous, and it may share vtables with the rest of the buffer.
If you absolutely must do this without re-serializing, there are two options I see:
Stick Alpha
and Beta
each in a nested_flatbuffer
(see docs), which is exactly for this use case of being able to copy a sub-buffer independently. Total size of the buffer may grow a bit though, access to their contents is a little different.
table Table1 {
// data fields here
}
table Table2 {
nested:[ubyte] (nested_flatbuffer: "Table1");
}
Use the C++ reflection functionality. I would not recommend this as the API for this is horrible and error-prone, but it is likely the most efficient way of adding a string to the end of existing buffer.