dvidelabs / flatcc

FlatBuffers Compiler and Library in C for C
Apache License 2.0
631 stars 180 forks source link

Documentation for vector of union #241

Closed HFabi closed 1 year ago

HFabi commented 1 year ago

Hello, I am trying to use a vector of union in my flatbuffers' schema, but unfortunately, there is no documentation how this could be achieved.

// schema.fbs
union Layer { Domain, User }

table Structure {
  layers:[Layer];
}
table Domain {
  loc:int32;
}
table User {
  example:int32;
}

Currently I am using the following code to write into the buffer, which seems to be fine (Am I already wrong here?).

// write
flatcc_builder_init(B);

structure_Domain_ref_t domain_1 = structure_Domain_create(B, 2);
structure_Layer_union_ref_t domain_union_1 = structure_Layer_as_Domain(domain_1);

structure_Domain_ref_t domain_2 = structure_Domain_create(B, 3);
structure_Layer_union_ref_t domain_union_2 = structure_Layer_as_Domain(domain_2);

structure_Layer_vec_start(B);
structure_Layer_vec_push(B, domain_union_1);
structure_Layer_vec_push(B, domain_union_2);
structure_Layer_union_vec_ref_t layers = structure_Layer_vec_end(B);

structure_Structure_start_as_root(B);
structure_Structure_layers_add(B, layers);
structure_Structure_end_as_root(B);

uint8_t *buf = flatcc_builder_finalize_buffer(B, size);

I cannot figure out, how I am able to read the vector of union from the buffer again:

// read
structure_Structure_table_t structure = structure_Structure_as_root(buf);
// is this the correct type?
structure_Layer_vec_t layers = structure_Structure_layers(structure);
size_t layers_len = structure_Layer_vec_len(layers);

for(int i = 0; i < layers_len; i++) {

  // is this the correct type?
  const structure_Layer_union_type_t ith_layer = structure_Layer_vec_at(layers, i);
  // is always false?
  if(ith_layer == structure_Layer_Domain) {
      // not sure how to parse or access the layer/ lines of code field?
   } else {
        printf("else");
    }
}
// -> leads to segmentation error

Does anyone have a similar problem or any ideas how to solve this?

EDIT:

I am sorry, this is my fault. I found the test that covers union vectors as described in the README and was able to solve my problem:

void read(uint8_t *buf, size_t size) {
    structure_Structure_table_t structure = structure_Structure_as_root(buf);
    structure_Layer_union_vec_t layers = structure_Structure_layers_union(structure);
    size_t layers_len = structure_Layer_union_vec_len(layers);

    for(int i = 0; i < layers_len; i++) {
        structure_Layer_union_t ith_layer = structure_Layer_union_vec_at(layers, i);

        if(ith_layer.type == structure_Layer_Domain) {
            structure_Domain_table_t domain_layer = ith_layer.value;
            int32_t loc = structure_Domain_loc(domain_layer);
            printf("Domain with loc:  %d", loc);
        } else {
            printf("else");
        }
    }
}
mikkelfj commented 1 year ago

For reference, her is the link to the builder documentation: https://github.com/dvidelabs/flatcc/blob/master/doc/builder.md#union-vectors