in extensions/nanoarrow_ipc/src/nanoarrow/nanoarrow_ipc_decoder.c [620:698]
static int ArrowIpcDecoderSetTypeUnion(struct ArrowSchema* schema,
flatbuffers_generic_t type_generic,
int64_t n_children, struct ArrowError* error) {
ns(Union_table_t) type = (ns(Union_table_t))type_generic;
int union_mode = ns(Union_mode(type));
if (n_children < 0 || n_children > 127) {
ArrowErrorSet(error,
"Expected between 0 and 127 children for Union type but found %ld",
(long)n_children);
return EINVAL;
}
// Max valid typeIds size is 127; the longest single ID that could be present here
// is -INT_MIN (11 chars). With commas and the prefix the max size would be
// 1527 characters. (Any ids outside the range 0...127 are unlikely to be valid
// elsewhere but they could in theory be present here).
char union_types_str[2048];
memset(union_types_str, 0, sizeof(union_types_str));
char* format_cursor = union_types_str;
int format_out_size = sizeof(union_types_str);
int n_chars = 0;
const char* format_prefix;
switch (union_mode) {
case ns(UnionMode_Sparse):
n_chars = snprintf(format_cursor, format_out_size, "+us:");
format_cursor += n_chars;
format_out_size -= n_chars;
break;
case ns(UnionMode_Dense):
n_chars = snprintf(format_cursor, format_out_size, "+ud:");
format_cursor += n_chars;
format_out_size -= n_chars;
break;
default:
ArrowErrorSet(error, "Unexpected Union UnionMode value: %d", (int)union_mode);
return EINVAL;
}
if (ns(Union_typeIds_is_present(type))) {
flatbuffers_int32_vec_t type_ids = ns(Union_typeIds(type));
int64_t n_type_ids = flatbuffers_int32_vec_len(type_ids);
if (n_type_ids != n_children) {
ArrowErrorSet(
error,
"Expected between %ld children for Union type with %ld typeIds but found %ld",
(long)n_type_ids, (long)n_type_ids, (long)n_children);
return EINVAL;
}
if (n_type_ids > 0) {
n_chars = snprintf(format_cursor, format_out_size, "%d",
flatbuffers_int32_vec_at(type_ids, 0));
format_cursor += n_chars;
format_out_size -= n_chars;
for (int64_t i = 1; i < n_type_ids; i++) {
n_chars = snprintf(format_cursor, format_out_size, ",%d",
(int)flatbuffers_int32_vec_at(type_ids, i));
format_cursor += n_chars;
format_out_size -= n_chars;
}
}
} else if (n_children > 0) {
n_chars = snprintf(format_cursor, format_out_size, "0");
format_cursor += n_chars;
format_out_size -= n_chars;
for (int64_t i = 1; i < n_children; i++) {
n_chars = snprintf(format_cursor, format_out_size, ",%d", (int)i);
format_cursor += n_chars;
format_out_size -= n_chars;
}
}
return ArrowIpcDecoderSetTypeSimpleNested(schema, union_types_str, error);
}