mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-23 16:30:02 +00:00
Add buffer verification functionality to FlatBuffers
Bug: 15732628 Change-Id: I0b7cb65982d6b8957d5a899cca7d2b5d2ef53206 Tested: On Windows, OS X and Linux
This commit is contained in:
@@ -24,8 +24,13 @@ public class Monster extends Table {
|
||||
public Test test4(int j) { return test4(new Test(), j); }
|
||||
public Test test4(Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__init(__vector(o) + j * 4, bb) : null; }
|
||||
public int test4Length() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }
|
||||
public String testarrayofstring(int j) { int o = __offset(24); return o != 0 ? __string(__vector(o) + j * 4) : null; }
|
||||
public int testarrayofstringLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }
|
||||
public Monster testarrayoftables(int j) { return testarrayoftables(new Monster(), j); }
|
||||
public Monster testarrayoftables(Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
|
||||
public int testarrayoftablesLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }
|
||||
|
||||
public static void startMonster(FlatBufferBuilder builder) { builder.startObject(10); }
|
||||
public static void startMonster(FlatBufferBuilder builder) { builder.startObject(12); }
|
||||
public static void addPos(FlatBufferBuilder builder, int pos) { builder.addStruct(0, pos, 0); }
|
||||
public static void addMana(FlatBufferBuilder builder, short mana) { builder.addShort(1, mana, 150); }
|
||||
public static void addHp(FlatBufferBuilder builder, short hp) { builder.addShort(2, hp, 100); }
|
||||
@@ -37,6 +42,10 @@ public class Monster extends Table {
|
||||
public static void addTest(FlatBufferBuilder builder, int test) { builder.addOffset(8, test, 0); }
|
||||
public static void addTest4(FlatBufferBuilder builder, int test4) { builder.addOffset(9, test4, 0); }
|
||||
public static void startTest4Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems); }
|
||||
public static void addTestarrayofstring(FlatBufferBuilder builder, int testarrayofstring) { builder.addOffset(10, testarrayofstring, 0); }
|
||||
public static void startTestarrayofstringVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems); }
|
||||
public static void addTestarrayoftables(FlatBufferBuilder builder, int testarrayoftables) { builder.addOffset(11, testarrayoftables, 0); }
|
||||
public static void startTestarrayoftablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems); }
|
||||
public static int endMonster(FlatBufferBuilder builder) { return builder.endObject(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ table Monster {
|
||||
color:Color = Blue;
|
||||
test:Any;
|
||||
test4:[Test];
|
||||
testarrayofstring:[string];
|
||||
testarrayoftables:[Monster];
|
||||
}
|
||||
|
||||
root_type Monster;
|
||||
|
||||
@@ -33,6 +33,8 @@ inline const char **EnumNamesAny() {
|
||||
|
||||
inline const char *EnumNameAny(int e) { return EnumNamesAny()[e]; }
|
||||
|
||||
bool VerifyAny(const flatbuffers::Verifier &verifier, const void *union_obj, uint8_t type);
|
||||
|
||||
struct Test;
|
||||
struct Vec3;
|
||||
struct Monster;
|
||||
@@ -88,6 +90,30 @@ struct Monster : private flatbuffers::Table {
|
||||
uint8_t test_type() const { return GetField<uint8_t>(18, 0); }
|
||||
const void *test() const { return GetPointer<const void *>(20); }
|
||||
const flatbuffers::Vector<const Test *> *test4() const { return GetPointer<const flatbuffers::Vector<const Test *> *>(22); }
|
||||
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(24); }
|
||||
const flatbuffers::Vector<flatbuffers::Offset<Monster>> *testarrayoftables() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Monster>> *>(26); }
|
||||
bool Verify(const flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTable(verifier) &&
|
||||
VerifyField<Vec3>(verifier, 4 /* pos */) &&
|
||||
VerifyField<int16_t>(verifier, 6 /* mana */) &&
|
||||
VerifyField<int16_t>(verifier, 8 /* hp */) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, 10 /* name */) &&
|
||||
verifier.Verify(name()) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, 14 /* inventory */) &&
|
||||
verifier.Verify(inventory()) &&
|
||||
VerifyField<int8_t>(verifier, 16 /* color */) &&
|
||||
VerifyField<uint8_t>(verifier, 18 /* test_type */) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, 20 /* test */) &&
|
||||
VerifyAny(verifier, test(), test_type()) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, 22 /* test4 */) &&
|
||||
verifier.Verify(test4()) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, 24 /* testarrayofstring */) &&
|
||||
verifier.Verify(testarrayofstring()) &&
|
||||
verifier.VerifyVectorOfStrings(testarrayofstring()) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, 26 /* testarrayoftables */) &&
|
||||
verifier.Verify(testarrayoftables()) &&
|
||||
verifier.VerifyVectorOfTables(testarrayoftables());
|
||||
}
|
||||
};
|
||||
|
||||
struct MonsterBuilder {
|
||||
@@ -102,12 +128,17 @@ struct MonsterBuilder {
|
||||
void add_test_type(uint8_t test_type) { fbb_.AddElement<uint8_t>(18, test_type, 0); }
|
||||
void add_test(flatbuffers::Offset<void> test) { fbb_.AddOffset(20, test); }
|
||||
void add_test4(flatbuffers::Offset<flatbuffers::Vector<const Test *>> test4) { fbb_.AddOffset(22, test4); }
|
||||
void add_testarrayofstring(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring) { fbb_.AddOffset(24, testarrayofstring); }
|
||||
void add_testarrayoftables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Monster>>> testarrayoftables) { fbb_.AddOffset(26, testarrayoftables); }
|
||||
MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
flatbuffers::Offset<Monster> Finish() { return flatbuffers::Offset<Monster>(fbb_.EndTable(start_, 10)); }
|
||||
MonsterBuilder &operator=(const MonsterBuilder &);
|
||||
flatbuffers::Offset<Monster> Finish() { return flatbuffers::Offset<Monster>(fbb_.EndTable(start_, 12)); }
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const Vec3 *pos, int16_t mana, int16_t hp, flatbuffers::Offset<flatbuffers::String> name, flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory, int8_t color, uint8_t test_type, flatbuffers::Offset<void> test, flatbuffers::Offset<flatbuffers::Vector<const Test *>> test4) {
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const Vec3 *pos, int16_t mana, int16_t hp, flatbuffers::Offset<flatbuffers::String> name, flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory, int8_t color, uint8_t test_type, flatbuffers::Offset<void> test, flatbuffers::Offset<flatbuffers::Vector<const Test *>> test4, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Monster>>> testarrayoftables) {
|
||||
MonsterBuilder builder_(_fbb);
|
||||
builder_.add_testarrayoftables(testarrayoftables);
|
||||
builder_.add_testarrayofstring(testarrayofstring);
|
||||
builder_.add_test4(test4);
|
||||
builder_.add_test(test);
|
||||
builder_.add_inventory(inventory);
|
||||
@@ -120,8 +151,18 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
bool VerifyAny(const flatbuffers::Verifier &verifier, const void *union_obj, uint8_t type) {
|
||||
switch (type) {
|
||||
case Any_NONE: return true;
|
||||
case Any_Monster: return reinterpret_cast<const Monster *>(union_obj)->Verify(verifier);
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline const Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot<Monster>(buf); }
|
||||
|
||||
inline bool VerifyMonsterBuffer(const flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<Monster>(); }
|
||||
|
||||
}; // namespace MyGame
|
||||
}; // namespace Example
|
||||
|
||||
|
||||
Binary file not shown.
@@ -79,10 +79,19 @@ std::string CreateFlatBufferTest() {
|
||||
mb.add_hp(20);
|
||||
auto mloc2 = mb.Finish();
|
||||
|
||||
// Create an array of strings:
|
||||
flatbuffers::Offset<flatbuffers::String> strings[2];
|
||||
strings[0] = builder.CreateString("bob");
|
||||
strings[1] = builder.CreateString("fred");
|
||||
auto vecofstrings = builder.CreateVector(strings, 2);
|
||||
|
||||
// Create an array of tables:
|
||||
auto vecoftables = builder.CreateVector(&mloc2, 1);
|
||||
|
||||
// shortcut for creating monster with all fields set:
|
||||
auto mloc = CreateMonster(builder, &vec, 150, 80, name, inventory, Color_Blue,
|
||||
Any_Monster, mloc2.Union(), // Store a union.
|
||||
testv);
|
||||
testv, vecofstrings, vecoftables);
|
||||
|
||||
builder.Finish(mloc);
|
||||
|
||||
@@ -101,6 +110,13 @@ std::string CreateFlatBufferTest() {
|
||||
// example of accessing a buffer loaded in memory:
|
||||
void AccessFlatBufferTest(const std::string &flatbuf) {
|
||||
|
||||
// First, verify the buffers integrity (optional)
|
||||
flatbuffers::Verifier verifier(
|
||||
reinterpret_cast<const uint8_t *>(flatbuf.c_str()),
|
||||
flatbuf.length());
|
||||
TEST_EQ(VerifyMonsterBuffer(verifier), true);
|
||||
|
||||
// Access the buffer from the root.
|
||||
auto monster = GetMonster(flatbuf.c_str());
|
||||
|
||||
TEST_EQ(monster->hp(), 80);
|
||||
@@ -128,11 +144,22 @@ void AccessFlatBufferTest(const std::string &flatbuf) {
|
||||
TEST_NOTNULL(monster2);
|
||||
TEST_EQ(monster2->hp(), 20);
|
||||
|
||||
// Example of accessing a vector of strings:
|
||||
auto vecofstrings = monster->testarrayofstring();
|
||||
TEST_EQ(vecofstrings->Length(), 2U);
|
||||
TEST_EQ(strcmp(vecofstrings->Get(0)->c_str(), "bob"), 0);
|
||||
TEST_EQ(strcmp(vecofstrings->Get(1)->c_str(), "fred"), 0);
|
||||
|
||||
// Example of accessing a vector of tables:
|
||||
auto vecoftables = monster->testarrayoftables();
|
||||
TEST_EQ(vecoftables->Length(), 1U);
|
||||
TEST_EQ(vecoftables->Get(0)->hp(), 20);
|
||||
|
||||
// Since Flatbuffers uses explicit mechanisms to override the default
|
||||
// compiler alignment, double check that the compiler indeed obeys them:
|
||||
// (Test consists of a short and byte):
|
||||
TEST_EQ(flatbuffers::AlignOf<Test>(), static_cast<size_t>(2));
|
||||
TEST_EQ(sizeof(Test), static_cast<size_t>(4));
|
||||
TEST_EQ(flatbuffers::AlignOf<Test>(), 2UL);
|
||||
TEST_EQ(sizeof(Test), 4UL);
|
||||
|
||||
auto tests = monster->test4();
|
||||
TEST_NOTNULL(tests);
|
||||
@@ -163,6 +190,11 @@ void ParseAndGenerateTextTest() {
|
||||
|
||||
// here, parser.builder_ contains a binary buffer that is the parsed data.
|
||||
|
||||
// First, verify it, just in case:
|
||||
flatbuffers::Verifier verifier(parser.builder_.GetBufferPointer(),
|
||||
parser.builder_.GetSize());
|
||||
TEST_EQ(VerifyMonsterBuffer(verifier), true);
|
||||
|
||||
// to ensure it is correct, we now generate text back from the binary,
|
||||
// and compare the two:
|
||||
std::string jsongen;
|
||||
|
||||
Reference in New Issue
Block a user