Search code examples
javaflatbuffers

Add an encoded flatbuffer table to a parent in Java


I have the following flatbuffer schema:

table Image {
    ...
}    

table Pose {
    r:[double] (required);
    q:[double] (required);
}

table StampedImage {
    pose: Pose (required);
    image: Image (required);
}

I understand how to encode a flatbuffer object. For instance, to encode a Pose object as a byte array:

    double[] r = ...
    double[] q = ...
    FlatBufferBuilder fbb = new FlatBufferBuilder();
    int rvec = Pose.createRVector(fbb, r);
    int qvec = Pose.createQVector(fbb, q);
    Pose.startPose(fbb);
    Pose.addR(fbb, rvec);
    Pose.addQ(fbb, qvec);
    Pose.finishPoseBuffer(fbb, Pose.endPose(fbb));
    byte[] encodedPose = fbb.sizedByteArray();

Furthermore, I understand how to "add" a pose to the parent class:

    FlatBufferBuilder fbb = new FlatBufferBuilder();

    int rOff = Pose.createRVector(fbb, r);
    int qOff = Pose.createQVector(fbb, q);
    Pose.startPose(fbb);
    Pose.addR(fbb, rOff);
    Pose.addQ(fbb, qOff);
    int poseOff = Pose.endPose(fbb);

    // Create the image
    int imageOff = ...

    StampedImage.startStampedImage(fbb);
    StampedImage.addPose(fbb, poseOff);
    StampedImage.addImage(fbb, imageOff);
    fbb.finish(StampedImage.endStampedImage(fbb));

But what I would like to do is to add the encodedPose data to the parent StampedImage directly. My use case is that I am setting up a conglomerater... I am receiving pose data from one source as encoded byte arrays, and image data from another source (also as encoded byte arrays). So I want to be able to "combine" these objects into a single encoded object. For instance, the function signature would look like:

public byte[] encodeStampedImage( byte[] encodedPose, byte[] encodedImage ){
    .... ?????
}

One approach would be to decode the objects, and then to reencode them, but that would have a huge overhead:

public byte[] encodeStampedImage( byte[] encodedPose, byte[] encodedImage ){
    Pose pose   = Pose.getRootAsPose(   ByteBuffer.wrap(encodedPose ));
    Image image = Image.getRootAsImage( ByteBuffer.wrap(encodedImage));
    // Get r and q vectors from pose, then add them 

    FlatBufferBuilder fbb = new FlatBufferBuilder();

    int rOff = Pose.createRVector(fbb, pose.rAsByteBuffer().array());
    int qOff = Pose.createRVector(fbb, pose.qAsByteBuffer().array());
    // Proceed as before... 
}

I feel like there must be a better way to avoid these extra allocations. If the children are already encoded, isn't there some way to directly create a parent object from them?


Solution

  • There is currently no direct way to do this in the API. It is certainly possible, and in theory simple: you'd just add the bytes of the child-buffer to the parent, and then pass an offset to it to the parent constructor. That would require a new function in FlatBufferBuilder though.