Fixed incorrect verifier code for nested tables.
authorWouter van Oortmerssen <wvo@google.com>
Wed, 9 Jul 2014 18:44:26 +0000 (11:44 -0700)
committerWouter van Oortmerssen <wvo@google.com>
Thu, 10 Jul 2014 00:13:03 +0000 (17:13 -0700)
It was outputting the type instead of the field name, and didn't deal
with NULL fields. Added test case.

Also fixed token enums having the wrong value, resulting in
unreadable error messages.

Change-Id: Icd9b4d22f417bfad5824c0f58e067ce3f2e2dc6f
Tested: on Windows and Linux.

include/flatbuffers/flatbuffers.h
src/idl_gen_cpp.cpp
src/idl_parser.cpp
tests/MyGame/Example/Monster.java
tests/monster_test.fbs
tests/monster_test_generated.h
tests/monsterdata_test_wire.bin
tests/test.cpp

index ff33255..d817e86 100644 (file)
@@ -582,6 +582,11 @@ class Verifier {
     return Verify(elem, sizeof(T));
   }
 
+  // Verify a pointer (may be NULL) of a table type.
+  template<typename T> bool VerifyTable(const T *table) const {
+    return !table || table->Verify(*this);
+  }
+
   // Verify a pointer (may be NULL) of any vector type.
   template<typename T> bool Verify(const Vector<T> *vec) const {
     const uint8_t *end;
index bbb8632..688ee78 100644 (file)
@@ -155,8 +155,8 @@ static void GenComment(const std::string &dc,
       if (!ev.value) {
         code_post += ": return true;\n";  // "NONE" enum value.
       } else {
-        code_post += ": return reinterpret_cast<const " + ev.struct_def->name;
-        code_post += " *>(union_obj)->Verify(verifier);\n";
+        code_post += ": return verifier.VerifyTable(reinterpret_cast<const ";
+        code_post += ev.struct_def->name + " *>(union_obj));\n";
       }
     }
     code_post += "    default: return false;\n  }\n}\n\n";
@@ -213,8 +213,8 @@ static void GenTable(StructDef &struct_def, std::string *code_ptr) {
           break;
         case BASE_TYPE_STRUCT:
           if (!field.value.type.struct_def->fixed) {
-            code += prefix + field.value.type.struct_def->name;
-            code += "()->Verify()";
+            code += prefix + "verifier.VerifyTable(" + field.name;
+            code += "())";
           }
           break;
         case BASE_TYPE_STRING:
index 70f22ed..e4d2d94 100644 (file)
@@ -83,7 +83,7 @@ template<> inline Offset<void> atot<Offset<void>>(const char *s) {
   TD(NameSpace, 265, "namespace") \
   TD(RootType, 266, "root_type")
 enum {
-  #define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) kToken ## NAME,
+  #define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) kToken ## NAME = VALUE,
     FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN)
   #undef FLATBUFFERS_TOKEN
   #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE) kToken ## ENUM,
index 26bdf70..24a3afe 100755 (executable)
@@ -29,8 +29,10 @@ public class Monster extends Table {
   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 Monster enemy() { return enemy(new Monster()); }
+  public Monster enemy(Monster obj) { int o = __offset(28); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
 
-  public static void startMonster(FlatBufferBuilder builder) { builder.startObject(12); }
+  public static void startMonster(FlatBufferBuilder builder) { builder.startObject(13); }
   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); }
@@ -46,6 +48,7 @@ public class Monster extends Table {
   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 void addEnemy(FlatBufferBuilder builder, int enemy) { builder.addOffset(12, enemy, 0); }
   public static int endMonster(FlatBufferBuilder builder) { return builder.endObject(); }
 };
 
index a9f95ea..cf191c4 100755 (executable)
@@ -29,6 +29,7 @@ table Monster {
   /// multiline too
   testarrayoftables:[Monster] (id: 11);
   testarrayofstring:[string] (id: 10);
+  enemy:Monster (id:12);
   test:Any (id: 8);
   test4:[Test] (id: 9);
 }
index 627cb1f..0a45a20 100755 (executable)
@@ -92,6 +92,7 @@ struct Monster : private flatbuffers::Table {
   const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(24); }
   /// an example documentation comment: this will end up in the generated code multiline too
   const flatbuffers::Vector<flatbuffers::Offset<Monster>> *testarrayoftables() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Monster>> *>(26); }
+  const Monster *enemy() const { return GetPointer<const Monster *>(28); }
   bool Verify(const flatbuffers::Verifier &verifier) const {
     return VerifyTable(verifier) &&
            VerifyField<Vec3>(verifier, 4 /* pos */) &&
@@ -112,7 +113,9 @@ struct Monster : private flatbuffers::Table {
            verifier.VerifyVectorOfStrings(testarrayofstring()) &&
            VerifyField<flatbuffers::uoffset_t>(verifier, 26 /* testarrayoftables */) &&
            verifier.Verify(testarrayoftables()) &&
-           verifier.VerifyVectorOfTables(testarrayoftables());
+           verifier.VerifyVectorOfTables(testarrayoftables()) &&
+           VerifyField<flatbuffers::uoffset_t>(verifier, 28 /* enemy */) &&
+           verifier.VerifyTable(enemy());
   }
 };
 
@@ -130,13 +133,15 @@ struct MonsterBuilder {
   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); }
+  void add_enemy(flatbuffers::Offset<Monster> enemy) { fbb_.AddOffset(28, enemy); }
   MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
   MonsterBuilder &operator=(const MonsterBuilder &);
-  flatbuffers::Offset<Monster> Finish() { return flatbuffers::Offset<Monster>(fbb_.EndTable(start_, 12)); }
+  flatbuffers::Offset<Monster> Finish() { return flatbuffers::Offset<Monster>(fbb_.EndTable(start_, 13)); }
 };
 
-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) {
+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, flatbuffers::Offset<Monster> enemy) {
   MonsterBuilder builder_(_fbb);
+  builder_.add_enemy(enemy);
   builder_.add_testarrayoftables(testarrayoftables);
   builder_.add_testarrayofstring(testarrayofstring);
   builder_.add_test4(test4);
@@ -154,7 +159,7 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
 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);
+    case Any_Monster: return verifier.VerifyTable(reinterpret_cast<const Monster *>(union_obj));
     default: return false;
   }
 }
index 9a7b16d..f09bf50 100755 (executable)
Binary files a/tests/monsterdata_test_wire.bin and b/tests/monsterdata_test_wire.bin differ
index 901c230..5aa8157 100644 (file)
@@ -91,7 +91,7 @@ std::string CreateFlatBufferTest() {
   // 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, vecofstrings, vecoftables);
+                            testv, vecofstrings, vecoftables, 0);
 
   builder.Finish(mloc);