Nesting vectors (With wrapping the inner vector in a table)

1,700 views
Skip to first unread message

Alexey Rybalchenko

unread,
Jan 25, 2016, 7:36:22 AM1/25/16
to FlatBuffers
Hi,

I am trying to fill the following flatbuffer:

table DigiBuffer {
  data
:[ubyte];
}

table
Digi {
  x
:int;
  bigBuffer
:DigiBuffer;
}

table
DigiPayload {
  digis
:[Digi];
}

root_type
DigiPayload;



using this code:

flatbuffers::FlatBufferBuilder builder = new flatbuffers::FlatBufferBuilder();
flatbuffers
::Offset<TestDetectorFlat::Digi> digis[numEntries]; // numEntries ~= 20-30

for (int i = 0; i < numEntries; ++i) {
   
DigiBufferBuilder dbb(builder);
   
// fBigBuffer is array<unsigned char, 100000>
   
auto bigBuffer = builder->CreateVector(fBigBuffer.data(), sizeof(fBigBuffer)); // here assertion `!nested' fails.
    dbb
.add_data(bigBuffer);
   
auto dbloc = dbb.Finish();

   
DigiBuilder db(builder);
    db
.add_x(4); // x:int
    db
.add_bigBuffer(dbloc); // bigBuffer:DigiBuffer

    digis
[i] = db.Finish();
}

auto dvector = builder->CreateVector(digis, nDigis);
auto mloc = CreateDigiPayload(builder, dvector); // digis:[Digi]
FinishDigiPayloadBuffer(builder, mloc);

It compiles fine, but when running it fails on assertion:
flatbuffers.h:664: void flatbuffers::FlatBufferBuilder::NotNested(): Assertion `!nested' failed.

The docs mention: "Nesting vectors is not supported, instead you can wrap the inner vector in a table.", which is why I added the DigiBuffer table in the first place (having only bigBuffer:[ubyte] in Digi originally). But I guess the way I do the nesting is wrong.

Can you please explain what I am doing wrong or give an example on how to nest vectors-tables properly.

Maxim Zaks

unread,
Jan 26, 2016, 8:01:05 AM1/26/16
to FlatBuffers
I guess you have to move this line up

auto bigBuffer = builder->CreateVector(fBigBuffer.data(), sizeof(fBigBuffer)); // here assertion `!nested' fails.

before

DigiBufferBuilder dbb(builder);

this is due to fact that you first have to create a vector, get its offset, than create the DigiBuffer Table and than add vectors offset to the table.
When you start a table you "reserve" an offset. You will "release" this reservation when you call finish. A vector string or a table can be created/started only when there is no previous reservation.
The explanation is a bit higher level, if you are interested in the details, why it is the case you would have to look in the implementation.
Message has been deleted

Alexey Rybalchenko

unread,
Jan 27, 2016, 5:16:48 AM1/27/16
to FlatBuffers
This helped, thank you!

Daniel D

unread,
Mar 4, 2016, 4:03:36 AM3/4/16
to FlatBuffers
Hi all,
I created the following flatbuffer:

namespace flatbuffers_tbl1;

table
Info{
    num
:int;
}

table
Tbl1 {
    age
: int = 22;
    name
: string;
    vec
:[Info];
}

root_type
Tbl1;

I am trying create buffer but I don't know how to CreateVector vec:[Info]  and add vec to tbl1Builder. Anyone can give me an tutorial:

flatbuffers::FlatBufferBuilder fbb;
   
auto nameData = fbb.CreateString("AAAA");

   
InfoBuilder infoBuilder(fbb);
    infoBuilder
.add_num(11);
   
auto infoloc = infoBuilder.Finish();

   
Tbl1Builder tbl1Builder(fbb);
    tbl1Builder
.add_age(33);
    tbl1Builder
.add_name(nameData);

   
auto maloc = tbl1Builder.Finish();
   
FinishTbl1Buffer(fbb, maloc);

Wouter van Oortmerssen

unread,
Mar 7, 2016, 4:48:27 PM3/7/16
to Daniel D, FlatBuffers
https://google.github.io/flatbuffers/flatbuffers_guide_tutorial.html

search for `weapons_vector` as an example how to write an vector of tables.

--
You received this message because you are subscribed to the Google Groups "FlatBuffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to flatbuffers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages