}
tag_enum_value = tag_enum_integer->definition.value._signed;
+
+ /*
+ * If the variant currently has a tag and a payload, and if the
+ * requested tag value is the same as the current one, return
+ * the current payload instead of creating a fresh one.
+ */
+ if (variant->tag && variant->payload) {
+ struct bt_ctf_field *cur_tag_container = NULL;
+ struct bt_ctf_field_integer *cur_tag_enum_integer;
+ int64_t cur_tag_value;
+
+ cur_tag_container =
+ bt_ctf_field_enumeration_get_container(variant->tag);
+ cur_tag_enum_integer = container_of(cur_tag_container,
+ struct bt_ctf_field_integer, parent);
+ bt_ctf_field_put(cur_tag_container);
+ cur_tag_value = cur_tag_enum_integer->definition.value._signed;
+
+ if (cur_tag_value == tag_enum_value) {
+ new_field = variant->payload;
+ bt_ctf_field_get(new_field);
+ goto end;
+ }
+ }
+
field_type = bt_ctf_field_type_variant_get_field_type_signed(
variant_type, tag_enum_value);
if (!field_type) {
}
if (string_field->payload) {
- g_string_insert_len(string_field->payload, -1, value,
+ g_string_append_len(string_field->payload, value,
effective_length);
} else {
string_field->payload = g_string_new_len(value,
goto end;
}
+ copy->payload_set = field->payload_set;
ret = field_copy_funcs[type_id](field, copy);
if (ret) {
bt_ctf_field_put(copy);
{
int ret = 0, i;
struct bt_ctf_field_sequence *sequence_src, *sequence_dst;
+ struct bt_ctf_field *src_length;
+ struct bt_ctf_field *dst_length;
sequence_src = container_of(src, struct bt_ctf_field_sequence, parent);
sequence_dst = container_of(dst, struct bt_ctf_field_sequence, parent);
- g_ptr_array_set_size(sequence_dst->elements,
- sequence_src->elements->len);
+ src_length = bt_ctf_field_sequence_get_length(src);
+
+ if (!src_length) {
+ /* no length set yet: keep destination sequence empty */
+ goto end;
+ }
+
+ /* copy source length */
+ dst_length = bt_ctf_field_copy(src_length);
+ bt_ctf_field_put(src_length);
+
+ if (!dst_length) {
+ ret = -1;
+ goto end;
+ }
+
+ /* this will initialize the destination sequence's internal array */
+ ret = bt_ctf_field_sequence_set_length(dst, dst_length);
+ bt_ctf_field_put(dst_length);
+
+ if (ret) {
+ goto end;
+ }
+
+ assert(sequence_dst->elements->len == sequence_src->elements->len);
+
for (i = 0; i < sequence_src->elements->len; i++) {
struct bt_ctf_field *field_copy = bt_ctf_field_copy(
g_ptr_array_index(sequence_src->elements, i));
ret = -1;
goto end;
}
+
g_ptr_array_index(sequence_dst->elements, i) = field_copy;
}
end: