/*
* event-fields.c
*
- * Babeltrace CTF Writer
+ * Babeltrace CTF IR - Event Fields
*
* Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
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 *);
+static
+int bt_ctf_field_structure_reset(struct bt_ctf_field *);
+static
+int bt_ctf_field_variant_reset(struct bt_ctf_field *);
+static
+int bt_ctf_field_enumeration_reset(struct bt_ctf_field *);
+static
+int bt_ctf_field_array_reset(struct bt_ctf_field *);
+static
+int bt_ctf_field_sequence_reset(struct bt_ctf_field *);
+static
+int bt_ctf_field_string_reset(struct bt_ctf_field *);
static
int bt_ctf_field_integer_serialize(struct bt_ctf_field *,
int bt_ctf_field_string_serialize(struct bt_ctf_field *,
struct ctf_stream_pos *);
+static
+int bt_ctf_field_integer_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+int bt_ctf_field_enumeration_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+int bt_ctf_field_floating_point_copy(struct bt_ctf_field *,
+ struct bt_ctf_field *);
+static
+int bt_ctf_field_structure_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+int bt_ctf_field_variant_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+int bt_ctf_field_array_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+int bt_ctf_field_sequence_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+int bt_ctf_field_string_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+
static
int increase_packet_size(struct ctf_stream_pos *pos);
[CTF_TYPE_STRING] = bt_ctf_field_generic_validate,
};
+static
+int (*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,
+ [CTF_TYPE_STRUCT] = bt_ctf_field_structure_reset,
+ [CTF_TYPE_VARIANT] = bt_ctf_field_variant_reset,
+ [CTF_TYPE_ARRAY] = bt_ctf_field_array_reset,
+ [CTF_TYPE_SEQUENCE] = bt_ctf_field_sequence_reset,
+ [CTF_TYPE_STRING] = bt_ctf_field_string_reset,
+};
+
static
int (*field_serialize_funcs[])(struct bt_ctf_field *,
struct ctf_stream_pos *) = {
[CTF_TYPE_STRING] = bt_ctf_field_string_serialize,
};
+static
+int (*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,
+ [CTF_TYPE_STRUCT] = bt_ctf_field_structure_copy,
+ [CTF_TYPE_VARIANT] = bt_ctf_field_variant_copy,
+ [CTF_TYPE_ARRAY] = bt_ctf_field_array_copy,
+ [CTF_TYPE_SEQUENCE] = bt_ctf_field_sequence_copy,
+ [CTF_TYPE_STRING] = bt_ctf_field_string_copy,
+};
+
struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type)
{
struct bt_ctf_field *field = NULL;
struct bt_ctf_field *new_field = NULL;
GQuark field_quark;
struct bt_ctf_field_structure *structure;
- struct bt_ctf_field_type_structure *structure_type;
- struct bt_ctf_field_type *field_type;
+ struct bt_ctf_field_type *field_type = NULL;
size_t index;
if (!field || !name ||
field_quark = g_quark_from_string(name);
structure = container_of(field, struct bt_ctf_field_structure, parent);
- structure_type = container_of(field->type,
- struct bt_ctf_field_type_structure, parent);
- field_type = bt_ctf_field_type_structure_get_type(structure_type, name);
+ field_type =
+ bt_ctf_field_type_structure_get_field_type_by_name(field->type,
+ name);
if (!g_hash_table_lookup_extended(structure->field_name_to_index,
GUINT_TO_POINTER(field_quark), NULL, (gpointer *)&index)) {
goto error;
end:
bt_ctf_field_get(new_field);
error:
+ if (field_type) {
+ bt_ctf_field_type_put(field_type);
+ }
return new_field;
}
struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
- struct bt_ctf_field *field, size_t index)
+ struct bt_ctf_field *field, int index)
{
int ret;
const char *field_name;
int ret = 0;
GQuark field_quark;
struct bt_ctf_field_structure *structure;
- struct bt_ctf_field_type_structure *structure_type;
- struct bt_ctf_field_type *expected_field_type;
+ struct bt_ctf_field_type *expected_field_type = NULL;
size_t index;
if (!field || !name || !value ||
field_quark = g_quark_from_string(name);
structure = container_of(field, struct bt_ctf_field_structure, parent);
- structure_type = container_of(field->type,
- struct bt_ctf_field_type_structure, parent);
- expected_field_type = bt_ctf_field_type_structure_get_type(
- structure_type, name);
+ expected_field_type =
+ bt_ctf_field_type_structure_get_field_type_by_name(field->type,
+ name);
if (expected_field_type != value->type) {
ret = -1;
goto end;
structure->fields->pdata[index] = value;
bt_ctf_field_get(value);
end:
+ if (expected_field_type) {
+ bt_ctf_field_type_put(expected_field_type);
+ }
return ret;
}
uint64_t index)
{
struct bt_ctf_field *new_field = NULL;
+ struct bt_ctf_field_type *field_type = NULL;
struct bt_ctf_field_array *array;
- struct bt_ctf_field_type_array *array_type;
- struct bt_ctf_field_type *field_type;
if (!field || bt_ctf_field_type_get_type_id(field->type) !=
CTF_TYPE_ARRAY) {
goto end;
}
- array_type = container_of(field->type, struct bt_ctf_field_type_array,
- parent);
- field_type = bt_ctf_field_type_array_get_element_type(array_type);
+ field_type = bt_ctf_field_type_array_get_element_type(field->type);
if (array->elements->pdata[(size_t)index]) {
new_field = array->elements->pdata[(size_t)index];
goto end;
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);
+ }
return new_field;
}
uint64_t index)
{
struct bt_ctf_field *new_field = NULL;
+ struct bt_ctf_field_type *field_type = NULL;
struct bt_ctf_field_sequence *sequence;
- struct bt_ctf_field_type_sequence *sequence_type;
- struct bt_ctf_field_type *field_type;
if (!field || bt_ctf_field_type_get_type_id(field->type) !=
CTF_TYPE_SEQUENCE) {
goto end;
}
- sequence_type = container_of(field->type,
- struct bt_ctf_field_type_sequence, parent);
- field_type = bt_ctf_field_type_sequence_get_element_type(sequence_type);
+ field_type = bt_ctf_field_type_sequence_get_element_type(field->type);
if (sequence->elements->pdata[(size_t)index]) {
new_field = sequence->elements->pdata[(size_t)index];
goto end;
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);
+ }
return new_field;
}
tag_enum_integer = container_of(tag_enum, struct bt_ctf_field_integer,
parent);
- if (!bt_ctf_field_validate(variant->tag)) {
+ if (bt_ctf_field_validate(tag_field) < 0) {
goto end;
}
tag_enum_value = tag_enum_integer->definition.value._signed;
- field_type = bt_ctf_field_type_variant_get_field_type(variant_type,
- tag_enum_value);
+ field_type = bt_ctf_field_type_variant_get_field_type_signed(
+ variant_type, tag_enum_value);
if (!field_type) {
goto end;
}
struct bt_ctf_field *container = NULL;
struct bt_ctf_field_enumeration *enumeration;
- if (!field) {
+ if (!field || bt_ctf_field_type_get_type_id(field->type) !=
+ CTF_TYPE_ENUM) {
goto end;
}
string = container_of(field, struct bt_ctf_field_string, parent);
if (string->payload) {
- g_string_free(string->payload, TRUE);
+ g_string_assign(string->payload, value);
+ } else {
+ string->payload = g_string_new(value);
}
- string->payload = g_string_new(value);
string->parent.payload_set = 1;
end:
return ret;
return ret;
}
+BT_HIDDEN
+int bt_ctf_field_reset(struct bt_ctf_field *field)
+{
+ int ret = 0;
+ enum ctf_type_id type_id;
+
+ if (!field) {
+ ret = -1;
+ goto end;
+ }
+
+ type_id = bt_ctf_field_type_get_type_id(field->type);
+ if (type_id <= CTF_TYPE_UNKNOWN || type_id >= NR_CTF_TYPES) {
+ ret = -1;
+ goto end;
+ }
+
+ ret = field_reset_funcs[type_id](field);
+end:
+ return ret;
+}
+
BT_HIDDEN
int bt_ctf_field_serialize(struct bt_ctf_field *field,
struct ctf_stream_pos *pos)
return ret;
}
+BT_HIDDEN
+struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
+{
+ int ret;
+ struct bt_ctf_field *copy = NULL;
+ enum ctf_type_id type_id;
+
+ if (!field) {
+ goto end;
+ }
+
+ type_id = bt_ctf_field_type_get_type_id(field->type);
+ if (type_id <= CTF_TYPE_UNKNOWN || type_id >= NR_CTF_TYPES) {
+ goto end;
+ }
+
+ copy = bt_ctf_field_create(field->type);
+ if (!copy) {
+ goto end;
+ }
+
+ ret = field_copy_funcs[type_id](field, copy);
+ if (ret) {
+ bt_ctf_field_put(copy);
+ copy = NULL;
+ }
+end:
+ return copy;
+}
+
static
struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
{
return ret;
}
+static
+int bt_ctf_field_generic_reset(struct bt_ctf_field *field)
+{
+ int ret = 0;
+
+ if (!field) {
+ ret = -1;
+ goto end;
+ }
+
+ field->payload_set = 0;
+end:
+ return ret;
+}
+
+static
+int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field)
+{
+ int ret = 0;
+ struct bt_ctf_field_enumeration *enumeration;
+
+ if (!field) {
+ ret = -1;
+ goto end;
+ }
+
+ enumeration = container_of(field, struct bt_ctf_field_enumeration,
+ parent);
+ if (!enumeration->payload) {
+ goto end;
+ }
+
+ ret = bt_ctf_field_reset(enumeration->payload);
+end:
+ return ret;
+}
+
+static
+int bt_ctf_field_structure_reset(struct bt_ctf_field *field)
+{
+ size_t i;
+ int ret = 0;
+ struct bt_ctf_field_structure *structure;
+
+ if (!field) {
+ ret = -1;
+ goto end;
+ }
+
+ structure = container_of(field, struct bt_ctf_field_structure, parent);
+ for (i = 0; i < structure->fields->len; i++) {
+ struct bt_ctf_field *member = structure->fields->pdata[i];
+
+ if (!member) {
+ /*
+ * Structure members are lazily initialized; skip if
+ * this member has not been allocated yet.
+ */
+ continue;
+ }
+
+ ret = bt_ctf_field_reset(member);
+ if (ret) {
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+static
+int bt_ctf_field_variant_reset(struct bt_ctf_field *field)
+{
+ int ret = 0;
+ struct bt_ctf_field_variant *variant;
+
+ if (!field) {
+ ret = -1;
+ goto end;
+ }
+
+ variant = container_of(field, struct bt_ctf_field_variant, parent);
+ if (variant->payload) {
+ ret = bt_ctf_field_reset(variant->payload);
+ }
+end:
+ return ret;
+}
+
+static
+int bt_ctf_field_array_reset(struct bt_ctf_field *field)
+{
+ size_t i;
+ int ret = 0;
+ struct bt_ctf_field_array *array;
+
+ if (!field) {
+ ret = -1;
+ goto end;
+ }
+
+ array = container_of(field, struct bt_ctf_field_array, parent);
+ for (i = 0; i < array->elements->len; i++) {
+ struct bt_ctf_field *member = array->elements->pdata[i];
+
+ if (!member) {
+ /*
+ * Array elements are lazily initialized; skip if
+ * this member has not been allocated yet.
+ */
+ continue;
+ }
+
+ ret = bt_ctf_field_reset(member);
+ if (ret) {
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+static
+int bt_ctf_field_sequence_reset(struct bt_ctf_field *field)
+{
+ size_t i;
+ int ret = 0;
+ struct bt_ctf_field_sequence *sequence;
+
+ if (!field) {
+ ret = -1;
+ goto end;
+ }
+
+ sequence = container_of(field, struct bt_ctf_field_sequence, parent);
+ for (i = 0; i < sequence->elements->len; i++) {
+ struct bt_ctf_field *member = sequence->elements->pdata[i];
+
+ if (!member) {
+ /*
+ * Sequence elements are lazily initialized; skip if
+ * this member has not been allocated yet.
+ */
+ continue;
+ }
+
+ ret = bt_ctf_field_reset(member);
+ if (ret) {
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+static
+int bt_ctf_field_string_reset(struct bt_ctf_field *field)
+{
+ int ret = 0;
+ struct bt_ctf_field_string *string;
+
+ if (!field) {
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_field_generic_reset(field);
+ if (ret) {
+ goto end;
+ }
+
+ string = container_of(field, struct bt_ctf_field_string, parent);
+ if (string->payload) {
+ g_string_truncate(string->payload, 0);
+ }
+end:
+ return ret;
+}
+
static
int bt_ctf_field_integer_serialize(struct bt_ctf_field *field,
struct ctf_stream_pos *pos)
return ret;
}
+static
+int bt_ctf_field_integer_copy(struct bt_ctf_field *src,
+ struct bt_ctf_field *dst)
+{
+ struct bt_ctf_field_integer *integer_src, *integer_dst;
+
+ integer_src = 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));
+ return 0;
+}
+
+static
+int bt_ctf_field_enumeration_copy(struct bt_ctf_field *src,
+ struct bt_ctf_field *dst)
+{
+ int ret = 0;
+ struct bt_ctf_field_enumeration *enum_src, *enum_dst;
+
+ enum_src = container_of(src, struct bt_ctf_field_enumeration, parent);
+ enum_dst = container_of(dst, struct bt_ctf_field_enumeration, parent);
+
+ if (enum_src->payload) {
+ enum_dst->payload = bt_ctf_field_copy(enum_src->payload);
+ if (!enum_dst->payload) {
+ ret = -1;
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+static
+int bt_ctf_field_floating_point_copy(
+ struct bt_ctf_field *src, struct bt_ctf_field *dst)
+{
+ struct bt_ctf_field_floating_point *float_src, *float_dst;
+
+ float_src = container_of(src, struct bt_ctf_field_floating_point,
+ parent);
+ float_dst = container_of(dst, struct bt_ctf_field_floating_point,
+ parent);
+
+ memcpy(&float_dst->definition, &float_src->definition,
+ sizeof(struct definition_float));
+ memcpy(&float_dst->sign, &float_src->sign,
+ sizeof(struct definition_integer));
+ memcpy(&float_dst->mantissa, &float_src->mantissa,
+ sizeof(struct definition_integer));
+ memcpy(&float_dst->exp, &float_src->exp,
+ sizeof(struct definition_integer));
+ return 0;
+}
+
+static
+int bt_ctf_field_structure_copy(struct bt_ctf_field *src,
+ struct bt_ctf_field *dst)
+{
+ 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;
+ 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));
+
+ if (!field_copy) {
+ ret = -1;
+ goto end;
+ }
+ g_ptr_array_index(struct_dst->fields, i) = field_copy;
+ }
+end:
+ return ret;
+}
+
+static
+int bt_ctf_field_variant_copy(struct bt_ctf_field *src,
+ struct bt_ctf_field *dst)
+{
+ int ret = 0;
+ struct bt_ctf_field_variant *variant_src, *variant_dst;
+
+ variant_src = container_of(src, struct bt_ctf_field_variant, parent);
+ variant_dst = container_of(dst, struct bt_ctf_field_variant, parent);
+
+ if (variant_src->tag) {
+ variant_dst->tag = bt_ctf_field_copy(variant_src->tag);
+ if (!variant_dst->tag) {
+ ret = -1;
+ goto end;
+ }
+ }
+ if (variant_src->payload) {
+ variant_dst->payload = bt_ctf_field_copy(variant_src->payload);
+ if (!variant_dst->payload) {
+ ret = -1;
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+static
+int bt_ctf_field_array_copy(struct bt_ctf_field *src,
+ struct bt_ctf_field *dst)
+{
+ int ret = 0, i;
+ struct bt_ctf_field_array *array_src, *array_dst;
+
+ array_src = container_of(src, struct bt_ctf_field_array, parent);
+ array_dst = container_of(dst, struct bt_ctf_field_array, parent);
+
+ 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));
+
+ if (!field_copy) {
+ ret = -1;
+ goto end;
+ }
+ g_ptr_array_index(array_dst->elements, i) = field_copy;
+ }
+end:
+ return ret;
+}
+
+static
+int bt_ctf_field_sequence_copy(struct bt_ctf_field *src,
+ struct bt_ctf_field *dst)
+{
+ int ret = 0, i;
+ struct bt_ctf_field_sequence *sequence_src, *sequence_dst;
+
+ 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);
+ 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));
+
+ if (!field_copy) {
+ ret = -1;
+ goto end;
+ }
+ g_ptr_array_index(sequence_dst->elements, i) = field_copy;
+ }
+end:
+ return ret;
+}
+
+static
+int bt_ctf_field_string_copy(struct bt_ctf_field *src,
+ struct bt_ctf_field *dst)
+{
+ int ret = 0;
+ struct bt_ctf_field_string *string_src, *string_dst;
+
+ string_src = container_of(src, struct bt_ctf_field_string, parent);
+ string_dst = container_of(dst, struct bt_ctf_field_string, parent);
+
+ if (string_src->payload) {
+ string_dst->payload = g_string_new(string_src->payload->str);
+ if (!string_dst->payload) {
+ ret = -1;
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
static
int increase_packet_size(struct ctf_stream_pos *pos)
{