Commit eaa2b414 authored by Oli Wilkinson's avatar Oli Wilkinson

Added generation of typed helpers when using nested_flatbuffers in Java/C#. Fixes #3500

parent 63b526db
......@@ -876,7 +876,27 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
break;
}
}
// generate object accessors if is nested_flatbuffer
auto nested = field.attributes.Lookup("nested_flatbuffer");
if (nested) {
auto nested_qualified_name =
parser.namespaces_.back()->GetFullyQualifiedName(nested->constant);
auto nested_type = parser.structs_.Lookup(nested_qualified_name);
auto nested_type_name = WrapInNameSpace(parser, *nested_type);
auto nestedMethodName = MakeCamel(field.name, lang.first_camel_upper)
+ "As" + nested_type_name;
auto getNestedMethodName = nestedMethodName;
if (lang.language == IDLOptions::kCSharp) {
getNestedMethodName = "Get" + nestedMethodName;
}
code += " public " + nested_type_name + " ";
code += nestedMethodName + "() { return ";
code += getNestedMethodName + "(new " + nested_type_name + "()); }\n";
code += " public " + nested_type_name + " " + getNestedMethodName;
code += "(" + nested_type_name + " obj) { ";
code += "int o = __offset(" + NumToString(field.value.offset) +"); ";
code += "return o != 0 ? obj.__init(__indirect(__vector(o)), bb) : null; }\n";
}
// generate mutators for scalar fields or vectors of scalars
if (parser.opts.mutable_buffer) {
auto underlying_type = field.value.type.base_type == BASE_TYPE_VECTOR
......
......@@ -215,5 +215,44 @@ namespace FlatBuffers.Test
Assert.AreEqual("NONE", Any.NONE.ToString());
Assert.AreEqual("Monster", Any.Monster.ToString());
}
[FlatBuffersTestMethod]
public void TestNestedFlatBuffer()
{
const string nestedMonsterName = "NestedMonsterName";
const short nestedMonsterHp = 600;
const short nestedMonsterMana = 1024;
// Create nested buffer as a Monster type
var fbb1 = new FlatBufferBuilder(16);
var str1 = fbb1.CreateString(nestedMonsterName);
Monster.StartMonster(fbb1);
Monster.AddName(fbb1, str1);
Monster.AddHp(fbb1, nestedMonsterHp);
Monster.AddMana(fbb1, nestedMonsterMana);
var monster1 = Monster.EndMonster(fbb1);
Monster.FinishMonsterBuffer(fbb1, monster1);
var fbb1Bytes = fbb1.SizedByteArray();
fbb1 = null;
// Create a Monster which has the first buffer as a nested buffer
var fbb2 = new FlatBufferBuilder(16);
var str2 = fbb2.CreateString("My Monster");
var nestedBuffer = Monster.CreateTestnestedflatbufferVector(fbb2, fbb1Bytes);
Monster.StartMonster(fbb2);
Monster.AddName(fbb2, str2);
Monster.AddHp(fbb2, 50);
Monster.AddMana(fbb2, 32);
Monster.AddTestnestedflatbuffer(fbb2, nestedBuffer);
var monster = Monster.EndMonster(fbb2);
Monster.FinishMonsterBuffer(fbb2, monster);
// Now test the data extracted from the nested buffer
var mons = Monster.GetRootAsMonster(fbb2.DataBuffer);
var nestedMonster = mons.TestnestedflatbufferAsMonster();
Assert.AreEqual(nestedMonsterMana, nestedMonster.Mana);
Assert.AreEqual(nestedMonsterHp, nestedMonster.Hp);
Assert.AreEqual(nestedMonsterName, nestedMonster.Name);
}
}
}
......@@ -159,6 +159,8 @@ class JavaTest {
TestNamespaceNesting();
TestNestedFlatBuffer();
System.out.println("FlatBuffers test: completed successfully");
}
......@@ -242,6 +244,42 @@ class JavaTest {
TableInFirstNS.addFooTable(fbb, nestedTableOff);
int off = TableInFirstNS.endTableInFirstNS(fbb);
}
static void TestNestedFlatBuffer() {
final String nestedMonsterName = "NestedMonsterName";
final short nestedMonsterHp = 600;
final short nestedMonsterMana = 1024;
FlatBufferBuilder fbb1 = new FlatBufferBuilder(16);
int str1 = fbb1.createString(nestedMonsterName);
Monster.startMonster(fbb1);
Monster.addName(fbb1, str1);
Monster.addHp(fbb1, nestedMonsterHp);
Monster.addMana(fbb1, nestedMonsterMana);
int monster1 = Monster.endMonster(fbb1);
Monster.finishMonsterBuffer(fbb1, monster1);
byte[] fbb1Bytes = fbb1.sizedByteArray();
fbb1 = null;
FlatBufferBuilder fbb2 = new FlatBufferBuilder(16);
int str2 = fbb2.createString("My Monster");
int nestedBuffer = Monster.createTestnestedflatbufferVector(fbb2, fbb1Bytes);
Monster.startMonster(fbb2);
Monster.addName(fbb2, str2);
Monster.addHp(fbb2, (short)50);
Monster.addMana(fbb2, (short)32);
Monster.addTestnestedflatbuffer(fbb2, nestedBuffer);
int monster = Monster.endMonster(fbb2);
Monster.finishMonsterBuffer(fbb2, monster);
// Now test the data extracted from the nested buffer
Monster mons = Monster.getRootAsMonster(fbb2.dataBuffer());
Monster nestedMonster = mons.testnestedflatbufferAsMonster();
TestEq(nestedMonsterMana, nestedMonster.mana());
TestEq(nestedMonsterHp, nestedMonster.hp());
TestEq(nestedMonsterName, nestedMonster.name());
}
static <T> void TestEq(T a, T b) {
if (!a.equals(b)) {
......
......@@ -45,6 +45,8 @@ public sealed class Monster : Table {
public byte GetTestnestedflatbuffer(int j) { int o = __offset(30); return o != 0 ? bb.Get(__vector(o) + j * 1) : (byte)0; }
public int TestnestedflatbufferLength { get { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; } }
public ArraySegment<byte>? GetTestnestedflatbufferBytes() { return __vector_as_arraysegment(30); }
public Monster TestnestedflatbufferAsMonster() { return GetTestnestedflatbufferAsMonster(new Monster()); }
public Monster GetTestnestedflatbufferAsMonster(Monster obj) { int o = __offset(30); return o != 0 ? obj.__init(__indirect(__vector(o)), bb) : null; }
public bool MutateTestnestedflatbuffer(int j, byte testnestedflatbuffer) { int o = __offset(30); if (o != 0) { bb.Put(__vector(o) + j * 1, testnestedflatbuffer); return true; } else { return false; } }
public Stat Testempty { get { return GetTestempty(new Stat()); } }
public Stat GetTestempty(Stat obj) { int o = __offset(32); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
......
......@@ -51,6 +51,8 @@ public final class Monster extends Table {
public int testnestedflatbuffer(int j) { int o = __offset(30); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
public int testnestedflatbufferLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; }
public ByteBuffer testnestedflatbufferAsByteBuffer() { return __vector_as_bytebuffer(30, 1); }
public Monster testnestedflatbufferAsMonster() { return testnestedflatbufferAsMonster(new Monster()); }
public Monster testnestedflatbufferAsMonster(Monster obj) { int o = __offset(30); return o != 0 ? obj.__init(__indirect(__vector(o)), bb) : null; }
public boolean mutateTestnestedflatbuffer(int j, int testnestedflatbuffer) { int o = __offset(30); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)testnestedflatbuffer); return true; } else { return false; } }
public Stat testempty() { return testempty(new Stat()); }
public Stat testempty(Stat obj) { int o = __offset(32); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
......
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