Commit a4de6de7 authored by Jon Simantov's avatar Jon Simantov

Add optional root table name to SetString and ResizeVector.

This allows you to use these functions with a flatbuffer whose root
table type does't correspond with the root table type of the schema.

If you don't specify the table name, it will use the root table from
the schema by default (mimicing the current behavior).
parent f66e93cd
...@@ -271,10 +271,13 @@ inline const reflection::Object &GetUnionType( ...@@ -271,10 +271,13 @@ inline const reflection::Object &GetUnionType(
// "delta" may be negative (shrinking). // "delta" may be negative (shrinking).
// Unless "delta" is a multiple of the largest alignment, you'll create a small // Unless "delta" is a multiple of the largest alignment, you'll create a small
// amount of garbage space in the buffer (usually 0..7 bytes). // amount of garbage space in the buffer (usually 0..7 bytes).
// If your FlatBuffer's root table is not the schema's root table, you should
// pass in the name of the root table in root_table_name.
class ResizeContext { class ResizeContext {
public: public:
ResizeContext(const reflection::Schema &schema, uoffset_t start, int delta, ResizeContext(const reflection::Schema &schema, uoffset_t start, int delta,
std::vector<uint8_t> *flatbuf) std::vector<uint8_t> *flatbuf,
const char* root_table_name = nullptr)
: schema_(schema), startptr_(flatbuf->data() + start), : schema_(schema), startptr_(flatbuf->data() + start),
delta_(delta), buf_(*flatbuf), delta_(delta), buf_(*flatbuf),
dag_check_(flatbuf->size() / sizeof(uoffset_t), false) { dag_check_(flatbuf->size() / sizeof(uoffset_t), false) {
...@@ -284,7 +287,10 @@ class ResizeContext { ...@@ -284,7 +287,10 @@ class ResizeContext {
// Now change all the offsets by delta_. // Now change all the offsets by delta_.
auto root = GetAnyRoot(buf_.data()); auto root = GetAnyRoot(buf_.data());
Straddle<uoffset_t, 1>(buf_.data(), root, buf_.data()); Straddle<uoffset_t, 1>(buf_.data(), root, buf_.data());
ResizeTable(*schema.root_table(), root); ResizeTable(root_table_name
? *schema.objects()->LookupByKey(root_table_name)
: *schema.root_table(),
root);
// We can now add or remove bytes at start. // We can now add or remove bytes at start.
if (delta_ > 0) buf_.insert(buf_.begin() + start, delta_, 0); if (delta_ > 0) buf_.insert(buf_.begin() + start, delta_, 0);
else buf_.erase(buf_.begin() + start, buf_.begin() + start - delta_); else buf_.erase(buf_.begin() + start, buf_.begin() + start - delta_);
...@@ -396,14 +402,15 @@ class ResizeContext { ...@@ -396,14 +402,15 @@ class ResizeContext {
// live inside a std::vector so we can resize the buffer if needed. // live inside a std::vector so we can resize the buffer if needed.
// "str" must live inside "flatbuf" and may be invalidated after this call. // "str" must live inside "flatbuf" and may be invalidated after this call.
inline void SetString(const reflection::Schema &schema, const std::string &val, inline void SetString(const reflection::Schema &schema, const std::string &val,
const String *str, std::vector<uint8_t> *flatbuf) { const String *str, std::vector<uint8_t> *flatbuf,
const char* root_table_name) {
auto delta = static_cast<int>(val.size()) - static_cast<int>(str->Length()); auto delta = static_cast<int>(val.size()) - static_cast<int>(str->Length());
auto start = static_cast<uoffset_t>(reinterpret_cast<const uint8_t *>(str) - auto start = static_cast<uoffset_t>(reinterpret_cast<const uint8_t *>(str) -
flatbuf->data() + flatbuf->data() +
sizeof(uoffset_t)); sizeof(uoffset_t));
if (delta) { if (delta) {
// Different size, we must expand (or contract). // Different size, we must expand (or contract).
ResizeContext(schema, start, delta, flatbuf); ResizeContext(schema, start, delta, flatbuf, root_table_name);
if (delta < 0) { if (delta < 0) {
// Clear the old string, since we don't want parts of it remaining. // Clear the old string, since we don't want parts of it remaining.
memset(flatbuf->data() + start, 0, str->Length()); memset(flatbuf->data() + start, 0, str->Length());
...@@ -416,17 +423,20 @@ inline void SetString(const reflection::Schema &schema, const std::string &val, ...@@ -416,17 +423,20 @@ inline void SetString(const reflection::Schema &schema, const std::string &val,
// Resizes a flatbuffers::Vector inside a FlatBuffer. FlatBuffer must // Resizes a flatbuffers::Vector inside a FlatBuffer. FlatBuffer must
// live inside a std::vector so we can resize the buffer if needed. // live inside a std::vector so we can resize the buffer if needed.
// "vec" must live inside "flatbuf" and may be invalidated after this call. // "vec" must live inside "flatbuf" and may be invalidated after this call.
// If your FlatBuffer's root table is not the schema's root table, you should
// pass in the name of the root table in "root_table_name".
template<typename T> void ResizeVector(const reflection::Schema &schema, template<typename T> void ResizeVector(const reflection::Schema &schema,
uoffset_t newsize, T val, uoffset_t newsize, T val,
const Vector<T> *vec, const Vector<T> *vec,
std::vector<uint8_t> *flatbuf) { std::vector<uint8_t> *flatbuf,
const char* root_table_name = nullptr) {
auto delta_elem = static_cast<int>(newsize) - static_cast<int>(vec->size()); auto delta_elem = static_cast<int>(newsize) - static_cast<int>(vec->size());
auto delta_bytes = delta_elem * static_cast<int>(sizeof(T)); auto delta_bytes = delta_elem * static_cast<int>(sizeof(T));
auto vec_start = reinterpret_cast<const uint8_t *>(vec) - flatbuf->data(); auto vec_start = reinterpret_cast<const uint8_t *>(vec) - flatbuf->data();
auto start = static_cast<uoffset_t>(vec_start + sizeof(uoffset_t) + auto start = static_cast<uoffset_t>(vec_start + sizeof(uoffset_t) +
sizeof(T) * vec->size()); sizeof(T) * vec->size());
if (delta_bytes) { if (delta_bytes) {
ResizeContext(schema, start, delta_bytes, flatbuf); ResizeContext(schema, start, delta_bytes, flatbuf, root_table_name);
WriteScalar(flatbuf->data() + vec_start, newsize); // Length field. WriteScalar(flatbuf->data() + vec_start, newsize); // Length field.
// Set new elements to "val". // Set new elements to "val".
for (int i = 0; i < delta_elem; i++) { for (int i = 0; i < delta_elem; i++) {
......
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