4

I have the following classes:

namespace Message;

struct BBox {
 xmin:float;
 xmax:float;
 ymin:float;
 ymax:float;
}

table msg {
  key:string;
  boxes: [BBox];
}

root_type Message;

To create the object I do something such as

b = flatbuffers.Builder(0)
msg.msgStart(b)
msg.msgAddKey(b, b.CreateString(key))

v = flatbuffers.Builder(0)
size = len(boxes)
msg.msgBoxesVector(v, size)
for elem in boxes:
    xmin, ymin, xmax, ymax = elem
    BBox.CreateBBox(v, xmin, xmax, ymin, ymax)
boxes = v.EndVector(size)
msg.msgAddBoxes(b, boxes)
obj = msg.msgEnd(b)
b.Finish(obj)

and no error is thrown

However when I try to display the results, the key is good but the size of the vector and the content is wrong

rep = msg.msg.GetRootAsmsg(bytearray(b.Output()), 0)
print rep.BoxesLength()  # give me 4 instead of 1 
for i in range(rep.BoxesLength()):
    print rep.Boxes(i).Xmin(),  rep.Boxes(i).Ymin()
    print rep.Boxes(i).Xmax(),  rep.Boxes(i).Ymax()
Alexis
  • 2,149
  • 2
  • 25
  • 39

2 Answers2

5

We have an open issue about the Python port not doing enough error checking: https://github.com/google/flatbuffers/issues/299

The creation of the string and the vector should happen before msgStart. also, you should use just one Builder object (use just b, not v), since the above code refers from one buffer to another, which won't work.

EDIT: the Python implementation now correctly signals an error when you try to nest vector/string/table generation. It still can't detect cross-buffer offsets however.

Aardappel
  • 5,559
  • 1
  • 19
  • 22
3

I will give what I've done, hoping it may help other people (based on Aardappel answer)

b = flatbuffers.Builder(0)

if boxes:
    boxesOffsets = 0
    msg.msgStartBoxesVector(b, len(boxes))
    for elem in boxes:
        xmin, ymin, xmax, ymax = elem
        BBox.CreateBBox(b, float(xmin), float(xmax), float(ymin), float(ymax))
    boxesOffsets = b.EndVector(len(boxes))

msg.msgStart(b)
msg.msgAddKey(b, b.CreateString(key))
msg.msgAddUrl(b, b.CreateString(url))
msg.msgAddCountry(b, b.CreateString(country))
msg.msgAddLimit(b, limit)

if boxes:
    msg.msgAddBoxes(b, boxesOffsets)

obj = msg.msgEnd(b)
b.Finish(obj)
Alexis
  • 2,149
  • 2
  • 25
  • 39