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:
Wouter van Oortmerssen
2015-04-27 16:25:06 -07:00
parent a8d6962ac2
commit 3ec5dddb00
10 changed files with 225 additions and 22 deletions

View File

@@ -127,7 +127,7 @@ flatbuffers::unique_ptr_t CreateFlatBufferTest(std::string &buffer) {
}
// example of accessing a buffer loaded in memory:
void AccessFlatBufferTest(const uint8_t *flatbuf, const std::size_t length) {
void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length) {
// First, verify the buffers integrity (optional)
flatbuffers::Verifier verifier(flatbuf, length);
@@ -159,6 +159,8 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, const std::size_t length) {
for (auto it = inventory->begin(); it != inventory->end(); ++it)
TEST_EQ(*it, inv_data[it - inventory->begin()]);
TEST_EQ(monster->color(), Color_Blue);
// Example of accessing a union:
TEST_EQ(monster->test_type(), Any_Monster); // First make sure which it is.
auto monster2 = reinterpret_cast<const Monster *>(monster->test());
@@ -200,7 +202,39 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, const std::size_t length) {
for (auto it = tests->begin(); it != tests->end(); ++it) {
TEST_EQ(it->a() == 10 || it->a() == 30, true); // Just testing iterators.
}
}
// Change a FlatBuffer in-place, after it has been constructed.
void MutateFlatBuffersTest(uint8_t *flatbuf, std::size_t length) {
// Get non-const pointer to root.
auto monster = GetMutableMonster(flatbuf);
// Each of these tests mutates, then tests, then set back to the original,
// so we can test that the buffer in the end still passes our original test.
auto hp_ok = monster->mutate_hp(10);
TEST_EQ(hp_ok, true); // Field was present.
TEST_EQ(monster->hp(), 10);
monster->mutate_hp(80);
auto mana_ok = monster->mutate_mana(10);
TEST_EQ(mana_ok, false); // Field was NOT present, because default value.
// Mutate structs.
auto pos = monster->mutable_pos();
auto test3 = pos->mutable_test3(); // Struct inside a struct.
test3.mutate_a(50); // Struct fields never fail.
TEST_EQ(test3.a(), 50);
test3.mutate_a(10);
// Mutate vectors.
auto inventory = monster->mutable_inventory();
inventory->Mutate(9, 100);
TEST_EQ(inventory->Get(9), 100);
inventory->Mutate(9, 9);
// Run the verifier and the regular test to make sure we didn't trample on
// anything.
AccessFlatBufferTest(flatbuf, length);
}
// example of parsing text straight into a buffer, and generating
@@ -626,6 +660,8 @@ int main(int /*argc*/, const char * /*argv*/[]) {
rawbuf.length());
AccessFlatBufferTest(flatbuf.get(), rawbuf.length());
MutateFlatBuffersTest(flatbuf.get(), rawbuf.length());
#ifndef __ANDROID__ // requires file access
ParseAndGenerateTextTest();
ParseProtoTest();