void bt_ctf_field_string_destroy(struct bt_ctf_field *);
static
-int bt_ctf_field_generic_validate(struct bt_ctf_field *field);
+int bt_ctf_field_generic_validate(struct bt_ctf_field *);
static
-int bt_ctf_field_structure_validate(struct bt_ctf_field *field);
+int bt_ctf_field_structure_validate(struct bt_ctf_field *);
static
-int bt_ctf_field_variant_validate(struct bt_ctf_field *field);
+int bt_ctf_field_variant_validate(struct bt_ctf_field *);
static
-int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field);
+int bt_ctf_field_enumeration_validate(struct bt_ctf_field *);
static
-int bt_ctf_field_array_validate(struct bt_ctf_field *field);
+int bt_ctf_field_array_validate(struct bt_ctf_field *);
static
-int bt_ctf_field_sequence_validate(struct bt_ctf_field *field);
+int bt_ctf_field_sequence_validate(struct bt_ctf_field *);
static
-int bt_ctf_field_generic_reset(struct bt_ctf_field *field);
+int bt_ctf_field_generic_reset(struct bt_ctf_field *);
static
-int bt_ctf_field_structure_reset(struct bt_ctf_field *field);
+int bt_ctf_field_structure_reset(struct bt_ctf_field *);
static
-int bt_ctf_field_variant_reset(struct bt_ctf_field *field);
+int bt_ctf_field_variant_reset(struct bt_ctf_field *);
static
-int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field);
+int bt_ctf_field_enumeration_reset(struct bt_ctf_field *);
static
-int bt_ctf_field_array_reset(struct bt_ctf_field *field);
+int bt_ctf_field_array_reset(struct bt_ctf_field *);
static
-int bt_ctf_field_sequence_reset(struct bt_ctf_field *field);
+int bt_ctf_field_sequence_reset(struct bt_ctf_field *);
static
-int bt_ctf_field_string_reset(struct bt_ctf_field *field);
+int bt_ctf_field_string_reset(struct bt_ctf_field *);
static
int bt_ctf_field_integer_serialize(struct bt_ctf_field *,
int increase_packet_size(struct ctf_stream_pos *pos);
static
-struct bt_ctf_field *(*field_create_funcs[])(
+struct bt_ctf_field *(* const field_create_funcs[])(
struct bt_ctf_field_type *) = {
[CTF_TYPE_INTEGER] = bt_ctf_field_integer_create,
[CTF_TYPE_ENUM] = bt_ctf_field_enumeration_create,
};
static
-void (*field_destroy_funcs[])(struct bt_ctf_field *) = {
+void (* const field_destroy_funcs[])(struct bt_ctf_field *) = {
[CTF_TYPE_INTEGER] = bt_ctf_field_integer_destroy,
[CTF_TYPE_ENUM] = bt_ctf_field_enumeration_destroy,
[CTF_TYPE_FLOAT] =
};
static
-int (*field_validate_funcs[])(struct bt_ctf_field *) = {
+int (* const field_validate_funcs[])(struct bt_ctf_field *) = {
[CTF_TYPE_INTEGER] = bt_ctf_field_generic_validate,
[CTF_TYPE_ENUM] = bt_ctf_field_enumeration_validate,
[CTF_TYPE_FLOAT] = bt_ctf_field_generic_validate,
};
static
-int (*field_reset_funcs[])(struct bt_ctf_field *) = {
+int (* const field_reset_funcs[])(struct bt_ctf_field *) = {
[CTF_TYPE_INTEGER] = bt_ctf_field_generic_reset,
[CTF_TYPE_ENUM] = bt_ctf_field_enumeration_reset,
[CTF_TYPE_FLOAT] = bt_ctf_field_generic_reset,
};
static
-int (*field_serialize_funcs[])(struct bt_ctf_field *,
+int (* const field_serialize_funcs[])(struct bt_ctf_field *,
struct ctf_stream_pos *) = {
[CTF_TYPE_INTEGER] = bt_ctf_field_integer_serialize,
[CTF_TYPE_ENUM] = bt_ctf_field_enumeration_serialize,
};
static
-int (*field_copy_funcs[])(struct bt_ctf_field *, struct bt_ctf_field *) = {
+int (* const field_copy_funcs[])(struct bt_ctf_field *,
+ struct bt_ctf_field *) = {
[CTF_TYPE_INTEGER] = bt_ctf_field_integer_copy,
[CTF_TYPE_ENUM] = bt_ctf_field_enumeration_copy,
[CTF_TYPE_FLOAT] = bt_ctf_field_floating_point_copy,
}
new_field = bt_ctf_field_create(field_type);
- bt_ctf_field_get(new_field);
array->elements->pdata[(size_t)index] = new_field;
end:
if (field_type) {
bt_ctf_field_type_put(field_type);
}
+ if (new_field) {
+ bt_ctf_field_get(new_field);
+ }
return new_field;
}
}
new_field = bt_ctf_field_create(field_type);
- bt_ctf_field_get(new_field);
sequence->elements->pdata[(size_t)index] = new_field;
end:
if (field_type) {
bt_ctf_field_type_put(field_type);
}
+ if (new_field) {
+ bt_ctf_field_get(new_field);
+ }
return new_field;
}
}
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) {
return ret;
}
+int bt_ctf_field_string_append(struct bt_ctf_field *field,
+ const char *value)
+{
+ int ret = 0;
+ struct bt_ctf_field_string *string_field;
+
+ if (!field || !value ||
+ bt_ctf_field_type_get_type_id(field->type) !=
+ CTF_TYPE_STRING) {
+ ret = -1;
+ goto end;
+ }
+
+ string_field = container_of(field, struct bt_ctf_field_string, parent);
+
+ if (string_field->payload) {
+ g_string_append(string_field->payload, value);
+ } else {
+ string_field->payload = g_string_new(value);
+ }
+
+ string_field->parent.payload_set = 1;
+
+end:
+ return ret;
+}
+
+int bt_ctf_field_string_append_len(struct bt_ctf_field *field,
+ const char *value, unsigned int length)
+{
+ int i;
+ int ret = 0;
+ unsigned int effective_length = length;
+ struct bt_ctf_field_string *string_field;
+
+ if (!field || !value ||
+ bt_ctf_field_type_get_type_id(field->type) !=
+ CTF_TYPE_STRING) {
+ ret = -1;
+ goto end;
+ }
+
+ string_field = container_of(field, struct bt_ctf_field_string, parent);
+
+ /* make sure no null bytes are appended */
+ for (i = 0; i < length; ++i) {
+ if (value[i] == '\0') {
+ effective_length = i;
+ break;
+ }
+ }
+
+ if (string_field->payload) {
+ g_string_append_len(string_field->payload, value,
+ effective_length);
+ } else {
+ string_field->payload = g_string_new_len(value,
+ effective_length);
+ }
+
+ string_field->parent.payload_set = 1;
+
+end:
+ return ret;
+}
+
BT_HIDDEN
int bt_ctf_field_validate(struct bt_ctf_field *field)
{
return ret;
}
-BT_HIDDEN
struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
{
int ret;
goto end;
}
- bt_ctf_field_type_get(field->type);
- copy->type = field->type;
+ copy->payload_set = field->payload_set;
ret = field_copy_funcs[type_id](field, copy);
if (ret) {
bt_ctf_field_put(copy);
}
string = container_of(field, struct bt_ctf_field_string, parent);
- g_string_free(string->payload, TRUE);
+ if (string->payload) {
+ g_string_free(string->payload, TRUE);
+ }
g_free(string);
}
struct bt_ctf_field_integer *integer_src, *integer_dst;
integer_src = container_of(src, struct bt_ctf_field_integer, parent);
- integer_dst = container_of(src, struct bt_ctf_field_integer, parent);
+ integer_dst = container_of(dst, struct bt_ctf_field_integer, parent);
memcpy(&integer_dst->definition, &integer_src->definition,
sizeof(struct definition_integer));
int bt_ctf_field_structure_copy(struct bt_ctf_field *src,
struct bt_ctf_field *dst)
{
- int ret, i;
+ int ret = 0, i;
struct bt_ctf_field_structure *struct_src, *struct_dst;
struct_src = container_of(src, struct bt_ctf_field_structure, parent);
struct_dst = container_of(dst, struct bt_ctf_field_structure, parent);
+ /* This field_name_to_index HT is owned by the structure field type */
struct_dst->field_name_to_index = struct_src->field_name_to_index;
- struct_dst->fields = g_ptr_array_sized_new(struct_src->fields->len);
- if (!struct_dst->fields) {
- ret = -1;
- goto end;
- }
+ g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
for (i = 0; i < struct_src->fields->len; i++) {
- struct bt_ctf_field *field_copy = bt_ctf_field_copy(
- g_ptr_array_index(struct_src->fields, i));
+ struct bt_ctf_field *field =
+ g_ptr_array_index(struct_src->fields, i);
+ struct bt_ctf_field *field_copy = NULL;
- if (!field_copy) {
- ret = -1;
- goto end;
+ if (field) {
+ field_copy = bt_ctf_field_copy(field);
+
+ if (!field_copy) {
+ ret = -1;
+ goto end;
+ }
}
- g_ptr_array_add(struct_dst->fields, field_copy);
+
+ g_ptr_array_index(struct_dst->fields, i) = field_copy;
}
end:
return ret;
array_src = container_of(src, struct bt_ctf_field_array, parent);
array_dst = container_of(dst, struct bt_ctf_field_array, parent);
- array_dst->elements = g_ptr_array_sized_new(array_src->elements->len);
+ g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
for (i = 0; i < array_src->elements->len; i++) {
- struct bt_ctf_field *field_copy = bt_ctf_field_copy(
- g_ptr_array_index(array_src->elements, i));
+ struct bt_ctf_field *field =
+ g_ptr_array_index(array_src->elements, i);
+ struct bt_ctf_field *field_copy = NULL;
- if (!field_copy) {
- ret = -1;
- goto end;
+ if (field) {
+ field_copy = bt_ctf_field_copy(field);
+
+ if (!field_copy) {
+ ret = -1;
+ goto end;
+ }
}
- g_ptr_array_add(array_dst->elements, field_copy);
+
+ g_ptr_array_index(array_dst->elements, i) = field_copy;
}
end:
return ret;
{
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);
- sequence_dst->elements = g_ptr_array_sized_new(
- 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));
+ struct bt_ctf_field *field =
+ g_ptr_array_index(sequence_src->elements, i);
+ struct bt_ctf_field *field_copy = NULL;
- if (!field_copy) {
- ret = -1;
- goto end;
+ if (field) {
+ field_copy = bt_ctf_field_copy(field);
+
+ if (!field_copy) {
+ ret = -1;
+ goto end;
+ }
}
- g_ptr_array_add(sequence_dst->elements, field_copy);
+
+ g_ptr_array_index(sequence_dst->elements, i) = field_copy;
}
end:
return ret;