* Generate code to encode and decode nested flatbuffers in Python.
* Delete accidental trailing whitespace.
* Fully delete trailing whitespace.
code += "\n";
}
+ // Returns a nested flatbuffer as itself.
+ void GetVectorAsNestedFlatbuffer(const StructDef &struct_def,
+ const FieldDef &field,
+ std::string *code_ptr) {
+ auto nested = field.attributes.Lookup("nested_flatbuffer");
+ if (!nested) { return; } // There is no nested flatbuffer.
+
+ std::string unqualified_name = nested->constant;
+ std::string qualified_name = nested->constant;
+ auto nested_root = parser_.LookupStruct(nested->constant);
+ if (nested_root == nullptr) {
+ qualified_name = parser_.current_namespace_->GetFullyQualifiedName(
+ nested->constant);
+ nested_root = parser_.LookupStruct(qualified_name);
+ }
+ FLATBUFFERS_ASSERT(nested_root); // Guaranteed to exist by parser.
+ (void)nested_root;
+
+ auto &code = *code_ptr;
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field)) + "NestedRoot(self):";
+
+ code += OffsetPrefix(field);
+
+ code += Indent + Indent + Indent;
+ code += "from " + qualified_name + " import " + unqualified_name + "\n";
+ code += Indent + Indent + Indent + "return " + unqualified_name;
+ code += ".GetRootAs" + unqualified_name;
+ code += "(self._tab.Bytes, self._tab.Vector(o))\n";
+ code += Indent + Indent + "return 0\n";
+ code += "\n";
+ }
+
// Begin the creator function signature.
void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) {
auto &code = *code_ptr;
code += ")\n";
}
+ // Set the value of one of the members of a table's vector and fills in the
+ // elements from a bytearray. This is for simplifying the use of nested
+ // flatbuffers.
+ void BuildVectorOfTableFromBytes(const StructDef &struct_def,
+ const FieldDef &field,
+ std::string *code_ptr) {
+ auto nested = field.attributes.Lookup("nested_flatbuffer");
+ if (!nested) { return; } // There is no nested flatbuffer.
+
+ std::string unqualified_name = nested->constant;
+ std::string qualified_name = nested->constant;
+ auto nested_root = parser_.LookupStruct(nested->constant);
+ if (nested_root == nullptr) {
+ qualified_name =
+ parser_.current_namespace_->GetFullyQualifiedName(nested->constant);
+ nested_root = parser_.LookupStruct(qualified_name);
+ }
+ FLATBUFFERS_ASSERT(nested_root); // Guaranteed to exist by parser.
+ (void)nested_root;
+
+ auto &code = *code_ptr;
+ code += "def " + NormalizedName(struct_def) + "Make";
+ code += MakeCamel(NormalizedName(field));
+ code += "VectorFromBytes(builder, bytes):\n";
+ code += Indent + "builder.StartVector(";
+ auto vector_type = field.value.type.VectorType();
+ auto alignment = InlineAlignment(vector_type);
+ auto elem_size = InlineSize(vector_type);
+ code += NumToString(elem_size);
+ code += ", len(bytes), " + NumToString(alignment);
+ code += ")\n";
+ code += Indent + "builder.head = builder.head - len(bytes)\n";
+ code += Indent + "builder.Bytes[builder.head : builder.head + len(bytes)]";
+ code += " = bytes\n";
+ code += Indent + "return builder.EndVector(len(bytes))\n";
+ }
+
// Get the offset of the end of a table.
void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
auto &code = *code_ptr;
} else {
GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
GetVectorOfNonStructAsNumpy(struct_def, field, code_ptr);
+ GetVectorAsNestedFlatbuffer(struct_def, field, code_ptr);
}
break;
}
BuildFieldOfTable(struct_def, field, offset, code_ptr);
if (IsVector(field.value.type)) {
BuildVectorOfTable(struct_def, field, code_ptr);
+ BuildVectorOfTableFromBytes(struct_def, field, code_ptr);
}
}
return 0
# Monster
+ def TestnestedflatbufferNestedRoot(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
+ if o != 0:
+ from MyGame.Example.Monster import Monster
+ return Monster.GetRootAsMonster(self._tab.Bytes, self._tab.Vector(o))
+ return 0
+
+ # Monster
def TestnestedflatbufferLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
if o != 0:
return 0
# Monster
+ def TestrequirednestedflatbufferNestedRoot(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
+ if o != 0:
+ from MyGame.Example.Monster import Monster
+ return Monster.GetRootAsMonster(self._tab.Bytes, self._tab.Vector(o))
+ return 0
+
+ # Monster
def TestrequirednestedflatbufferLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
if o != 0:
def MonsterAddEnemy(builder, enemy): builder.PrependUOffsetTRelativeSlot(12, flatbuffers.number_types.UOffsetTFlags.py_type(enemy), 0)
def MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer): builder.PrependUOffsetTRelativeSlot(13, flatbuffers.number_types.UOffsetTFlags.py_type(testnestedflatbuffer), 0)
def MonsterStartTestnestedflatbufferVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterMakeTestnestedflatbufferVectorFromBytes(builder, bytes):
+ builder.StartVector(1, len(bytes), 1)
+ builder.head = builder.head - len(bytes)
+ builder.Bytes[builder.head : builder.head + len(bytes)] = bytes
+ return builder.EndVector(len(bytes))
def MonsterAddTestempty(builder, testempty): builder.PrependUOffsetTRelativeSlot(14, flatbuffers.number_types.UOffsetTFlags.py_type(testempty), 0)
def MonsterAddTestbool(builder, testbool): builder.PrependBoolSlot(15, testbool, 0)
def MonsterAddTesthashs32Fnv1(builder, testhashs32Fnv1): builder.PrependInt32Slot(16, testhashs32Fnv1, 0)
def MonsterAddSignedEnum(builder, signedEnum): builder.PrependInt8Slot(48, signedEnum, -1)
def MonsterAddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer): builder.PrependUOffsetTRelativeSlot(49, flatbuffers.number_types.UOffsetTFlags.py_type(testrequirednestedflatbuffer), 0)
def MonsterStartTestrequirednestedflatbufferVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterMakeTestrequirednestedflatbufferVectorFromBytes(builder, bytes):
+ builder.StartVector(1, len(bytes), 1)
+ builder.head = builder.head - len(bytes)
+ builder.Bytes[builder.head : builder.head + len(bytes)] = bytes
+ return builder.EndVector(len(bytes))
def MonsterEnd(builder): return builder.EndObject()
import MyGame.Example.Ability
lambda: mon2.TestnestedflatbufferAsNumpy(),
NumpyRequiredForThisFeature)
+ def test_nested_monster_testnestedflatbuffer(self):
+ b = flatbuffers.Builder(0)
+
+ # build another monster to nest inside testnestedflatbuffer
+ nestedB = flatbuffers.Builder(0)
+ nameStr = nestedB.CreateString("Nested Monster")
+ MyGame.Example.Monster.MonsterStart(nestedB)
+ MyGame.Example.Monster.MonsterAddHp(nestedB, 30)
+ MyGame.Example.Monster.MonsterAddName(nestedB, nameStr)
+ nestedMon = MyGame.Example.Monster.MonsterEnd(nestedB)
+ nestedB.Finish(nestedMon)
+
+ # write the nested FB bytes
+ sub_buf = MyGame.Example.Monster.MonsterMakeTestnestedflatbufferVectorFromBytes(
+ b, nestedB.Output())
+
+ # make the parent monster and include the bytes of the nested monster
+ MyGame.Example.Monster.MonsterStart(b)
+ MyGame.Example.Monster.MonsterAddTestnestedflatbuffer(b, sub_buf)
+ mon = MyGame.Example.Monster.MonsterEnd(b)
+ b.Finish(mon)
+
+ # inspect the resulting data:
+ mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+ b.Head())
+ nestedMon2 = mon2.TestnestedflatbufferNestedRoot()
+ self.assertEqual(b"Nested Monster", nestedMon2.Name())
+ self.assertEqual(30, nestedMon2.Hp())
+
def test_nondefault_monster_testempty(self):
b = flatbuffers.Builder(0)