#include <babeltrace/ctf-writer/event-types.h>
#include <babeltrace/ctf-ir/event-types-internal.h>
+#include <babeltrace/ctf-ir/utils.h>
+#include <babeltrace/ctf-ir/clock.h>
#include <babeltrace/ctf-writer/writer-internal.h>
#include <babeltrace/compiler.h>
#include <babeltrace/endian.h>
static
void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
- int byte_order);
+ int byte_order, int set_native);
+static
+void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type *,
+ int byte_order, int set_native);
static
void bt_ctf_field_type_floating_point_set_byte_order(
- struct bt_ctf_field_type *, int byte_order);
+ struct bt_ctf_field_type *, int byte_order, int set_native);
+static
+void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *,
+ int byte_order, int set_native);
+static
+void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *,
+ int byte_order, int set_native);
+static
+void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *,
+ int byte_order, int set_native);
+static
+void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *,
+ int byte_order, int set_native);
+/* The set_native flag only set the byte order if it is set to native */
static
void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
- int) = {
- [CTF_TYPE_INTEGER] =
- bt_ctf_field_type_integer_set_byte_order,
+ int byte_order, int set_native) = {
+ [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_set_byte_order,
+ [CTF_TYPE_ENUM] =
+ bt_ctf_field_type_enumeration_set_byte_order,
[CTF_TYPE_FLOAT] =
bt_ctf_field_type_floating_point_set_byte_order,
- [CTF_TYPE_ENUM ... CTF_TYPE_SEQUENCE] = NULL,
+ [CTF_TYPE_STRUCT] =
+ bt_ctf_field_type_structure_set_byte_order,
+ [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_set_byte_order,
+ [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_set_byte_order,
+ [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_set_byte_order,
+ [CTF_TYPE_STRING] = NULL,
+};
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
+ struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
+ struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
+ struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
+ struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
+ struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
+ struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
+ struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
+ struct bt_ctf_field_type *);
+
+static
+struct bt_ctf_field_type *(* const type_copy_funcs[])(
+ struct bt_ctf_field_type *) = {
+ [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_copy,
+ [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_copy,
+ [CTF_TYPE_FLOAT] = bt_ctf_field_type_floating_point_copy,
+ [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_copy,
+ [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_copy,
+ [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_copy,
+ [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_copy,
+ [CTF_TYPE_STRING] = bt_ctf_field_type_string_copy,
};
static
(gpointer) (unsigned long) name_quark,
(gpointer) (unsigned long) fields->len);
g_ptr_array_add(fields, field);
- bt_ctf_field_type_freeze(field_type);
end:
return ret;
}
return;
}
- if (type->alias_name) {
- g_string_free(type->alias_name, TRUE);
- }
type_destroy_funcs[type_id](ref);
}
goto end;
}
- if (type->declaration->id == CTF_TYPE_ENUM) {
+ switch (type->declaration->id) {
+ case CTF_TYPE_ENUM:
+ {
struct bt_ctf_field_type_enumeration *enumeration =
container_of(type, struct bt_ctf_field_type_enumeration,
parent);
+ /* Ensure enum has entries */
ret = enumeration->entries->len ? 0 : -1;
+ break;
+ }
+ case CTF_TYPE_SEQUENCE:
+ {
+ struct bt_ctf_field_type_sequence *sequence =
+ container_of(type, struct bt_ctf_field_type_sequence,
+ parent);
+
+ /* length field name should be set at this point */
+ ret = sequence->length_field_name->len ? 0 : -1;
+ break;
+ }
+ case CTF_TYPE_VARIANT:
+ {
+ struct bt_ctf_field_type_variant *variant =
+ container_of(type, struct bt_ctf_field_type_variant,
+ parent);
+
+ if (variant->tag_name->len == 0 || !variant->tag) {
+ ret = -1;
+ }
+ break;
+ }
+ default:
+ break;
}
end:
return ret;
struct bt_ctf_field_type_integer *integer =
g_new0(struct bt_ctf_field_type_integer, 1);
- if (!integer || size > 64) {
+ if (!integer || size == 0 || size > 64) {
return NULL;
}
}
integer = container_of(type, struct bt_ctf_field_type_integer, parent);
- if (is_signed && integer->declaration.len <= 1) {
- ret = -1;
- goto end;
- }
-
integer->declaration.signedness = !!is_signed;
end:
return ret;
return ret;
}
+struct bt_ctf_clock *bt_ctf_field_type_integer_get_mapped_clock(
+ struct bt_ctf_field_type *type)
+{
+ struct bt_ctf_field_type_integer *integer;
+ struct bt_ctf_clock *clock = NULL;
+
+ if (!type) {
+ goto end;
+ }
+
+ integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+ clock = integer->mapped_clock;
+ if (clock) {
+ bt_ctf_clock_get(clock);
+ }
+end:
+ return clock;
+}
+
+int bt_ctf_field_type_integer_set_mapped_clock(
+ struct bt_ctf_field_type *type,
+ struct bt_ctf_clock *clock)
+{
+ struct bt_ctf_field_type_integer *integer;
+ int ret = 0;
+
+ if (!type || type->frozen) {
+ ret = -1;
+ goto end;
+ }
+
+ integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+ if (integer->mapped_clock) {
+ bt_ctf_clock_put(integer->mapped_clock);
+ }
+
+ if (clock) {
+ bt_ctf_clock_get(clock);
+ }
+
+ integer->mapped_clock = clock;
+end:
+ return ret;
+}
+
struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
struct bt_ctf_field_type *integer_container_type)
{
structure->parent.declaration = &structure->declaration.p;
structure->parent.declaration->id = CTF_TYPE_STRUCT;
- bt_ctf_field_type_init(&structure->parent);
structure->fields = g_ptr_array_new_with_free_func(
(GDestroyNotify)destroy_structure_field);
structure->field_name_to_index = g_hash_table_new(NULL, NULL);
+ bt_ctf_field_type_init(&structure->parent);
return &structure->parent;
error:
return NULL;
struct bt_ctf_field_type_structure *structure;
if (!type || !field_type || type->frozen ||
- validate_identifier(field_name) ||
+ bt_ctf_validate_identifier(field_name) ||
(type->declaration->id != CTF_TYPE_STRUCT) ||
bt_ctf_field_type_validate(field_type)) {
ret = -1;
{
struct bt_ctf_field_type_variant *variant = NULL;
- if (!enum_tag || validate_identifier(tag_name) ||
- (enum_tag->declaration->id != CTF_TYPE_ENUM)) {
+ if (tag_name && bt_ctf_validate_identifier(tag_name)) {
goto error;
}
variant->parent.declaration = &variant->declaration.p;
variant->parent.declaration->id = CTF_TYPE_VARIANT;
variant->tag_name = g_string_new(tag_name);
- bt_ctf_field_type_init(&variant->parent);
variant->field_name_to_index = g_hash_table_new(NULL, NULL);
variant->fields = g_ptr_array_new_with_free_func(
(GDestroyNotify)destroy_structure_field);
- bt_ctf_field_type_get(enum_tag);
- variant->tag = container_of(enum_tag,
- struct bt_ctf_field_type_enumeration, parent);
+ if (enum_tag) {
+ bt_ctf_field_type_get(enum_tag);
+ variant->tag = container_of(enum_tag,
+ struct bt_ctf_field_type_enumeration, parent);
+ }
+
+ bt_ctf_field_type_init(&variant->parent);
return &variant->parent;
error:
return NULL;
}
variant = container_of(type, struct bt_ctf_field_type_variant, parent);
+ if (!variant->tag) {
+ goto end;
+ }
+
tag_type = &variant->tag->parent;
bt_ctf_field_type_get(tag_type);
end:
}
variant = container_of(type, struct bt_ctf_field_type_variant, parent);
+ if (variant->tag_name->len == 0) {
+ goto end;
+ }
+
tag_name = variant->tag_name->str;
end:
return tag_name;
}
+int bt_ctf_field_type_variant_set_tag_name(
+ struct bt_ctf_field_type *type, const char *name)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_variant *variant;
+
+ if (!type || type->frozen ||
+ (type->declaration->id != CTF_TYPE_VARIANT) ||
+ bt_ctf_validate_identifier(name)) {
+ ret = -1;
+ goto end;
+ }
+
+ variant = container_of(type, struct bt_ctf_field_type_variant, parent);
+ g_string_assign(variant->tag_name, name);
+end:
+ return ret;
+}
+
int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
struct bt_ctf_field_type *field_type,
const char *field_name)
{
size_t i;
int ret = 0;
- int name_found = 0;
struct bt_ctf_field_type_variant *variant;
GQuark field_name_quark = g_quark_from_string(field_name);
if (!type || !field_type || type->frozen ||
- validate_identifier(field_name) ||
+ bt_ctf_validate_identifier(field_name) ||
(type->declaration->id != CTF_TYPE_VARIANT) ||
bt_ctf_field_type_validate(field_type)) {
ret = -1;
}
variant = container_of(type, struct bt_ctf_field_type_variant, parent);
- /* Make sure this name is present in the enum tag */
- for (i = 0; i < variant->tag->entries->len; i++) {
- struct enumeration_mapping *mapping =
- g_ptr_array_index(variant->tag->entries, i);
- if (mapping->string == field_name_quark) {
- name_found = 1;
- break;
+ /* The user has explicitly provided a tag; validate against it. */
+ if (variant->tag) {
+ int name_found = 0;
+
+ /* Make sure this name is present in the enum tag */
+ for (i = 0; i < variant->tag->entries->len; i++) {
+ struct enumeration_mapping *mapping =
+ g_ptr_array_index(variant->tag->entries, i);
+
+ if (mapping->string == field_name_quark) {
+ name_found = 1;
+ break;
+ }
+ }
+
+ if (!name_found) {
+ /* Validation failed */
+ ret = -1;
+ goto end;
}
}
- if (!name_found || add_structure_field(variant->fields,
- variant->field_name_to_index, field_type, field_name)) {
+ if (add_structure_field(variant->fields, variant->field_name_to_index,
+ field_type, field_name)) {
ret = -1;
goto end;
}
array->parent.declaration = &array->declaration.p;
array->parent.declaration->id = CTF_TYPE_ARRAY;
- bt_ctf_field_type_init(&array->parent);
+
bt_ctf_field_type_get(element_type);
array->element_type = element_type;
array->length = length;
+ bt_ctf_field_type_init(&array->parent);
array->parent.declaration->alignment =
element_type->declaration->alignment;
return &array->parent;
{
struct bt_ctf_field_type_sequence *sequence = NULL;
- if (!element_type || validate_identifier(length_field_name) ||
+ if (!element_type || bt_ctf_validate_identifier(length_field_name) ||
bt_ctf_field_type_validate(element_type)) {
goto error;
}
sequence->parent.declaration = &sequence->declaration.p;
sequence->parent.declaration->id = CTF_TYPE_SEQUENCE;
- bt_ctf_field_type_init(&sequence->parent);
bt_ctf_field_type_get(element_type);
sequence->element_type = element_type;
sequence->length_field_name = g_string_new(length_field_name);
+ bt_ctf_field_type_init(&sequence->parent);
sequence->parent.declaration->alignment =
element_type->declaration->alignment;
return &sequence->parent;
struct bt_ctf_field_type *type)
{
enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
+ int internal_byte_order = -1;
if (!type) {
goto end;
{
struct bt_ctf_field_type_integer *integer = container_of(
type, struct bt_ctf_field_type_integer, parent);
- ret = integer->declaration.byte_order == LITTLE_ENDIAN ?
- BT_CTF_BYTE_ORDER_LITTLE_ENDIAN :
- BT_CTF_BYTE_ORDER_BIG_ENDIAN;
+ internal_byte_order = integer->declaration.byte_order;
break;
}
case CTF_TYPE_FLOAT:
container_of(type,
struct bt_ctf_field_type_floating_point,
parent);
- ret = floating_point->declaration.byte_order == LITTLE_ENDIAN ?
- BT_CTF_BYTE_ORDER_LITTLE_ENDIAN :
- BT_CTF_BYTE_ORDER_BIG_ENDIAN;
+ internal_byte_order = floating_point->declaration.byte_order;
break;
}
default:
+ goto end;
+ }
+
+ switch (internal_byte_order) {
+ case LITTLE_ENDIAN:
+ ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
+ break;
+ case BIG_ENDIAN:
+ ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
break;
+ case 0:
+ ret = BT_CTF_BYTE_ORDER_NATIVE;
+ break;
+ default:
+ ret = BT_CTF_BYTE_ORDER_UNKNOWN;
}
end:
return ret;
goto end;
}
- type_id = type->declaration->id;
switch (byte_order) {
case BT_CTF_BYTE_ORDER_NATIVE:
- internal_byte_order = (G_BYTE_ORDER == G_LITTLE_ENDIAN ?
- LITTLE_ENDIAN : BIG_ENDIAN);
+ /* Leave unset. Will be initialized by parent. */
+ internal_byte_order = 0;
break;
case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
internal_byte_order = LITTLE_ENDIAN;
goto end;
}
+ type_id = type->declaration->id;
if (set_byte_order_funcs[type_id]) {
- set_byte_order_funcs[type_id](type, internal_byte_order);
+ set_byte_order_funcs[type_id](type, internal_byte_order, 0);
}
end:
return ret;
return type->declaration->id;
}
-const char *bt_ctf_field_type_get_alias_name(
- struct bt_ctf_field_type *type)
-{
- const char *name = NULL;
-
- if (!type || !type->alias_name) {
- goto end;
- }
-
- name = type->alias_name->str;
-end:
- return name;
-}
-
void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
{
if (!type) {
return ret;
}
-static
-void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *ref)
+BT_HIDDEN
+void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
+ int byte_order)
{
- struct bt_ctf_field_type_integer *integer;
-
- if (!ref) {
+ if (!type) {
return;
}
- integer = container_of(
- container_of(ref, struct bt_ctf_field_type, ref_count),
- struct bt_ctf_field_type_integer, parent);
- g_free(integer);
+ assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
+ if (set_byte_order_funcs[type->declaration->id]) {
+ set_byte_order_funcs[type->declaration->id](type,
+ byte_order, 1);
+ }
}
-static
-void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref *ref)
+BT_HIDDEN
+struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
{
- struct bt_ctf_field_type_enumeration *enumeration;
+ struct bt_ctf_field_type *copy = NULL;
- if (!ref) {
- return;
+ if (!type) {
+ goto end;
}
- enumeration = container_of(
- container_of(ref, struct bt_ctf_field_type, ref_count),
- struct bt_ctf_field_type_enumeration, parent);
- g_ptr_array_free(enumeration->entries, TRUE);
- bt_ctf_field_type_put(enumeration->container);
- g_free(enumeration);
+ copy = type_copy_funcs[type->declaration->id](type);
+end:
+ return copy;
}
-static
-void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref *ref)
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_path_create(void)
{
- struct bt_ctf_field_type_floating_point *floating_point;
+ struct bt_ctf_field_path *field_path = NULL;
- if (!ref) {
- return;
+ field_path = g_new0(struct bt_ctf_field_path, 1);
+ if (!field_path) {
+ goto end;
}
- floating_point = container_of(
- container_of(ref, struct bt_ctf_field_type, ref_count),
- struct bt_ctf_field_type_floating_point, parent);
- g_free(floating_point);
+ field_path->root = CTF_NODE_UNKNOWN;
+ field_path->path_indexes = g_array_new(TRUE, FALSE, sizeof(int));
+ if (!field_path->path_indexes) {
+ bt_ctf_field_path_destroy(field_path);
+ field_path = NULL;
+ }
+end:
+ return field_path;
}
-static
-void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref *ref)
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_path_copy(
+ struct bt_ctf_field_path *path)
{
- struct bt_ctf_field_type_structure *structure;
+ struct bt_ctf_field_path *new_path = bt_ctf_field_path_create();
- if (!ref) {
- return;
+ if (!new_path) {
+ goto end;
}
- structure = container_of(
- container_of(ref, struct bt_ctf_field_type, ref_count),
- struct bt_ctf_field_type_structure, parent);
- g_ptr_array_free(structure->fields, TRUE);
- g_hash_table_destroy(structure->field_name_to_index);
- g_free(structure);
+ new_path->root = path->root;
+ g_array_insert_vals(new_path->path_indexes, 0,
+ path->path_indexes->data, path->path_indexes->len);
+end:
+ return new_path;
}
-static
-void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *ref)
+BT_HIDDEN
+void bt_ctf_field_path_destroy(struct bt_ctf_field_path *path)
{
- struct bt_ctf_field_type_variant *variant;
-
- if (!ref) {
+ if (!path) {
return;
}
- variant = container_of(
- container_of(ref, struct bt_ctf_field_type, ref_count),
- struct bt_ctf_field_type_variant, parent);
- g_ptr_array_free(variant->fields, TRUE);
- g_hash_table_destroy(variant->field_name_to_index);
- g_string_free(variant->tag_name, TRUE);
- bt_ctf_field_type_put(&variant->tag->parent);
- g_free(variant);
+ if (path->path_indexes) {
+ g_array_free(path->path_indexes, TRUE);
+ }
+ g_free(path);
}
-static
-void bt_ctf_field_type_array_destroy(struct bt_ctf_ref *ref)
+BT_HIDDEN
+int bt_ctf_field_type_structure_get_field_name_index(
+ struct bt_ctf_field_type *type, const char *name)
{
- struct bt_ctf_field_type_array *array;
+ int ret;
+ size_t index;
+ GQuark name_quark;
+ struct bt_ctf_field_type_structure *structure;
- if (!ref) {
- return;
+ if (!type || !name ||
+ bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
+ ret = -1;
+ goto end;
}
- array = container_of(
- container_of(ref, struct bt_ctf_field_type, ref_count),
- struct bt_ctf_field_type_array, parent);
- bt_ctf_field_type_put(array->element_type);
- g_free(array);
+ name_quark = g_quark_try_string(name);
+ if (!name_quark) {
+ ret = -1;
+ goto end;
+ }
+
+ structure = container_of(type, struct bt_ctf_field_type_structure,
+ parent);
+ if (!g_hash_table_lookup_extended(structure->field_name_to_index,
+ GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
+ ret = -1;
+ goto end;
+ }
+ ret = (int) index;
+end:
+ return ret;
}
-static
-void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *ref)
+BT_HIDDEN
+int bt_ctf_field_type_variant_get_field_name_index(
+ struct bt_ctf_field_type *type, const char *name)
{
- struct bt_ctf_field_type_sequence *sequence;
+ int ret;
+ size_t index;
+ GQuark name_quark;
+ struct bt_ctf_field_type_variant *variant;
- if (!ref) {
- return;
+ if (!type || !name ||
+ bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
+ ret = -1;
+ goto end;
}
- sequence = container_of(
- container_of(ref, struct bt_ctf_field_type, ref_count),
- struct bt_ctf_field_type_sequence, parent);
- bt_ctf_field_type_put(sequence->element_type);
+ name_quark = g_quark_try_string(name);
+ if (!name_quark) {
+ ret = -1;
+ goto end;
+ }
+
+ variant = container_of(type, struct bt_ctf_field_type_variant,
+ parent);
+ if (!g_hash_table_lookup_extended(variant->field_name_to_index,
+ GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
+ ret = -1;
+ goto end;
+ }
+ ret = (int) index;
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_sequence_set_length_field_path(
+ struct bt_ctf_field_type *type,
+ struct bt_ctf_field_path *path)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_sequence *sequence;
+
+ if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_SEQUENCE) {
+ ret = -1;
+ goto end;
+ }
+
+ sequence = container_of(type, struct bt_ctf_field_type_sequence,
+ parent);
+ if (sequence->length_field_path) {
+ bt_ctf_field_path_destroy(sequence->length_field_path);
+ }
+ sequence->length_field_path = path;
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
+ struct bt_ctf_field_path *path)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_variant *variant;
+
+ if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
+ ret = -1;
+ goto end;
+ }
+
+ variant = container_of(type, struct bt_ctf_field_type_variant,
+ parent);
+ if (variant->tag_path) {
+ bt_ctf_field_path_destroy(variant->tag_path);
+ }
+ variant->tag_path = path;
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_variant_set_tag(struct bt_ctf_field_type *type,
+ struct bt_ctf_field_type *tag)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_variant *variant;
+
+ if (!type || !tag || type->frozen ||
+ bt_ctf_field_type_get_type_id(tag) != CTF_TYPE_ENUM) {
+ ret = -1;
+ goto end;
+ }
+
+ variant = container_of(type, struct bt_ctf_field_type_variant,
+ parent);
+ bt_ctf_field_type_get(tag);
+ if (variant->tag) {
+ bt_ctf_field_type_put(&variant->tag->parent);
+ }
+ variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
+ parent);
+end:
+ return ret;
+}
+
+static
+void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *ref)
+{
+ struct bt_ctf_field_type_integer *integer;
+
+ if (!ref) {
+ return;
+ }
+
+ integer = container_of(
+ container_of(ref, struct bt_ctf_field_type, ref_count),
+ struct bt_ctf_field_type_integer, parent);
+ if (integer->mapped_clock) {
+ bt_ctf_clock_put(integer->mapped_clock);
+ }
+ g_free(integer);
+}
+
+static
+void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref *ref)
+{
+ struct bt_ctf_field_type_enumeration *enumeration;
+
+ if (!ref) {
+ return;
+ }
+
+ enumeration = container_of(
+ container_of(ref, struct bt_ctf_field_type, ref_count),
+ struct bt_ctf_field_type_enumeration, parent);
+ g_ptr_array_free(enumeration->entries, TRUE);
+ bt_ctf_field_type_put(enumeration->container);
+ g_free(enumeration);
+}
+
+static
+void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref *ref)
+{
+ struct bt_ctf_field_type_floating_point *floating_point;
+
+ if (!ref) {
+ return;
+ }
+
+ floating_point = container_of(
+ container_of(ref, struct bt_ctf_field_type, ref_count),
+ struct bt_ctf_field_type_floating_point, parent);
+ g_free(floating_point);
+}
+
+static
+void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref *ref)
+{
+ struct bt_ctf_field_type_structure *structure;
+
+ if (!ref) {
+ return;
+ }
+
+ structure = container_of(
+ container_of(ref, struct bt_ctf_field_type, ref_count),
+ struct bt_ctf_field_type_structure, parent);
+ g_ptr_array_free(structure->fields, TRUE);
+ g_hash_table_destroy(structure->field_name_to_index);
+ g_free(structure);
+}
+
+static
+void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *ref)
+{
+ struct bt_ctf_field_type_variant *variant;
+
+ if (!ref) {
+ return;
+ }
+
+ variant = container_of(
+ container_of(ref, struct bt_ctf_field_type, ref_count),
+ struct bt_ctf_field_type_variant, parent);
+ g_ptr_array_free(variant->fields, TRUE);
+ g_hash_table_destroy(variant->field_name_to_index);
+ g_string_free(variant->tag_name, TRUE);
+ bt_ctf_field_type_put(&variant->tag->parent);
+ bt_ctf_field_path_destroy(variant->tag_path);
+ g_free(variant);
+}
+
+static
+void bt_ctf_field_type_array_destroy(struct bt_ctf_ref *ref)
+{
+ struct bt_ctf_field_type_array *array;
+
+ if (!ref) {
+ return;
+ }
+
+ array = container_of(
+ container_of(ref, struct bt_ctf_field_type, ref_count),
+ struct bt_ctf_field_type_array, parent);
+ bt_ctf_field_type_put(array->element_type);
+ g_free(array);
+}
+
+static
+void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *ref)
+{
+ struct bt_ctf_field_type_sequence *sequence;
+
+ if (!ref) {
+ return;
+ }
+
+ sequence = container_of(
+ container_of(ref, struct bt_ctf_field_type, ref_count),
+ struct bt_ctf_field_type_sequence, parent);
+ bt_ctf_field_type_put(sequence->element_type);
g_string_free(sequence->length_field_name, TRUE);
+ bt_ctf_field_path_destroy(sequence->length_field_path);
g_free(sequence);
}
{
struct bt_ctf_field_type_integer *integer = container_of(type,
struct bt_ctf_field_type_integer, parent);
+ int ret = 0;
g_string_append_printf(context->string,
- "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s; }",
+ "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
integer->declaration.len, type->declaration->alignment,
(integer->declaration.signedness ? "true" : "false"),
get_encoding_string(integer->declaration.encoding),
get_integer_base_string(integer->declaration.base),
get_byte_order_string(integer->declaration.byte_order));
- return 0;
+ if (integer->mapped_clock) {
+ const char *clock_name = bt_ctf_clock_get_name(
+ integer->mapped_clock);
+
+ if (!clock_name) {
+ ret = -1;
+ goto end;
+ }
+
+ g_string_append_printf(context->string,
+ "; map = clock.%s.value", clock_name);
+ }
+
+ g_string_append(context->string, "; }");
+end:
+ return ret;
}
static
GString *variant_field_name = context->field_name;
context->field_name = g_string_new("");
- g_string_append_printf(context->string,
- "variant <%s> {\n", variant->tag_name->str);
+ if (variant->tag_name->len > 0) {
+ g_string_append_printf(context->string,
+ "variant <%s> {\n", variant->tag_name->str);
+ } else {
+ g_string_append(context->string, "variant {\n");
+ }
+
context->current_indentation_level++;
for (i = 0; i < variant->fields->len; i++) {
struct structure_field *field = variant->fields->pdata[i];
static
void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
- int byte_order)
+ int byte_order, int set_native)
{
struct bt_ctf_field_type_integer *integer_type = container_of(type,
struct bt_ctf_field_type_integer, parent);
- integer_type->declaration.byte_order = byte_order;
+ if (set_native) {
+ integer_type->declaration.byte_order =
+ integer_type->declaration.byte_order == 0 ?
+ byte_order : integer_type->declaration.byte_order;
+ } else {
+ integer_type->declaration.byte_order = byte_order;
+ }
+}
+
+static
+void bt_ctf_field_type_enumeration_set_byte_order(
+ struct bt_ctf_field_type *type, int byte_order, int set_native)
+{
+ struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
+ struct bt_ctf_field_type_enumeration, parent);
+
+ /* Safe to assume that container is an integer */
+ bt_ctf_field_type_integer_set_byte_order(enum_type->container,
+ byte_order, set_native);
}
static
void bt_ctf_field_type_floating_point_set_byte_order(
- struct bt_ctf_field_type *type, int byte_order)
+ struct bt_ctf_field_type *type, int byte_order, int set_native)
{
struct bt_ctf_field_type_floating_point *floating_point_type =
container_of(type, struct bt_ctf_field_type_floating_point,
parent);
- floating_point_type->declaration.byte_order = byte_order;
- floating_point_type->sign.byte_order = byte_order;
- floating_point_type->mantissa.byte_order = byte_order;
- floating_point_type->exp.byte_order = byte_order;
+ if (set_native) {
+ floating_point_type->declaration.byte_order =
+ floating_point_type->declaration.byte_order == 0 ?
+ byte_order :
+ floating_point_type->declaration.byte_order;
+ floating_point_type->sign.byte_order =
+ floating_point_type->sign.byte_order == 0 ?
+ byte_order : floating_point_type->sign.byte_order;
+ floating_point_type->mantissa.byte_order =
+ floating_point_type->mantissa.byte_order == 0 ?
+ byte_order : floating_point_type->mantissa.byte_order;
+ floating_point_type->exp.byte_order =
+ floating_point_type->exp.byte_order == 0 ?
+ byte_order : floating_point_type->exp.byte_order;
+ } else {
+ floating_point_type->declaration.byte_order = byte_order;
+ floating_point_type->sign.byte_order = byte_order;
+ floating_point_type->mantissa.byte_order = byte_order;
+ floating_point_type->exp.byte_order = byte_order;
+ }
+}
+
+static
+void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
+ int byte_order, int set_native)
+{
+ int i;
+ struct bt_ctf_field_type_structure *structure_type =
+ container_of(type, struct bt_ctf_field_type_structure,
+ parent);
+
+ for (i = 0; i < structure_type->fields->len; i++) {
+ struct structure_field *field = g_ptr_array_index(
+ structure_type->fields, i);
+ struct bt_ctf_field_type *field_type = field->type;
+
+ if (set_byte_order_funcs[field_type->declaration->id]) {
+ set_byte_order_funcs[field_type->declaration->id](
+ field_type, byte_order, set_native);
+ }
+ }
+}
+
+static
+void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
+ int byte_order, int set_native)
+{
+ int i;
+ struct bt_ctf_field_type_variant *variant_type =
+ container_of(type, struct bt_ctf_field_type_variant,
+ parent);
+
+ for (i = 0; i < variant_type->fields->len; i++) {
+ struct structure_field *field = g_ptr_array_index(
+ variant_type->fields, i);
+ struct bt_ctf_field_type *field_type = field->type;
+
+ if (set_byte_order_funcs[field_type->declaration->id]) {
+ set_byte_order_funcs[field_type->declaration->id](
+ field_type, byte_order, set_native);
+ }
+ }
+}
+
+static
+void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
+ int byte_order, int set_native)
+{
+ struct bt_ctf_field_type_array *array_type =
+ container_of(type, struct bt_ctf_field_type_array,
+ parent);
+
+ if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
+ set_byte_order_funcs[array_type->element_type->declaration->id](
+ array_type->element_type, byte_order, set_native);
+ }
+}
+
+static
+void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
+ int byte_order, int set_native)
+{
+ struct bt_ctf_field_type_sequence *sequence_type =
+ container_of(type, struct bt_ctf_field_type_sequence,
+ parent);
+
+ if (set_byte_order_funcs[
+ sequence_type->element_type->declaration->id]) {
+ set_byte_order_funcs[
+ sequence_type->element_type->declaration->id](
+ sequence_type->element_type, byte_order, set_native);
+ }
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
+ struct bt_ctf_field_type *type)
+{
+ struct bt_ctf_field_type *copy;
+ struct bt_ctf_field_type_integer *integer, *copy_integer;
+
+ integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+ copy = bt_ctf_field_type_integer_create(integer->declaration.len);
+ if (!copy) {
+ goto end;
+ }
+
+ copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
+ parent);
+ copy_integer->declaration = integer->declaration;
+ if (integer->mapped_clock) {
+ bt_ctf_clock_get(integer->mapped_clock);
+ copy_integer->mapped_clock = integer->mapped_clock;
+ }
+end:
+ return copy;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
+ struct bt_ctf_field_type *type)
+{
+ size_t i;
+ struct bt_ctf_field_type *copy = NULL, *copy_container;
+ struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
+
+ enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
+ parent);
+
+ /* Copy the source enumeration's container */
+ copy_container = bt_ctf_field_type_copy(enumeration->container);
+ if (!copy_container) {
+ goto end;
+ }
+
+ copy = bt_ctf_field_type_enumeration_create(copy_container);
+ if (!copy) {
+ goto end;
+ }
+ copy_enumeration = container_of(copy,
+ struct bt_ctf_field_type_enumeration, parent);
+
+ /* Copy all enumaration entries */
+ for (i = 0; i < enumeration->entries->len; i++) {
+ struct enumeration_mapping *mapping = g_ptr_array_index(
+ enumeration->entries, i);
+ struct enumeration_mapping* copy_mapping = g_new0(
+ struct enumeration_mapping, 1);
+
+ if (!copy_mapping) {
+ goto error;
+ }
+
+ *copy_mapping = *mapping;
+ g_ptr_array_add(copy_enumeration->entries, copy_mapping);
+ }
+
+ copy_enumeration->declaration = enumeration->declaration;
+end:
+ if (copy_container) {
+ bt_ctf_field_type_put(copy_container);
+ }
+ return copy;
+error:
+ if (copy_container) {
+ bt_ctf_field_type_put(copy_container);
+ }
+ bt_ctf_field_type_put(copy);
+ return NULL;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
+ struct bt_ctf_field_type *type)
+{
+ struct bt_ctf_field_type *copy;
+ struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
+
+ floating_point = container_of(type,
+ struct bt_ctf_field_type_floating_point, parent);
+ copy = bt_ctf_field_type_floating_point_create();
+ if (!copy) {
+ goto end;
+ }
+
+ copy_float = container_of(copy,
+ struct bt_ctf_field_type_floating_point, parent);
+ copy_float->declaration = floating_point->declaration;
+ copy_float->sign = floating_point->sign;
+ copy_float->mantissa = floating_point->mantissa;
+ copy_float->exp = floating_point->exp;
+end:
+ return copy;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
+ struct bt_ctf_field_type *type)
+{
+ int i;
+ GHashTableIter iter;
+ gpointer key, value;
+ struct bt_ctf_field_type *copy;
+ struct bt_ctf_field_type_structure *structure, *copy_structure;
+
+ structure = container_of(type, struct bt_ctf_field_type_structure,
+ parent);
+ copy = bt_ctf_field_type_structure_create();
+ if (!copy) {
+ goto end;
+ }
+
+ copy_structure = container_of(copy,
+ struct bt_ctf_field_type_structure, parent);
+
+ /* Copy field_name_to_index */
+ g_hash_table_iter_init(&iter, structure->field_name_to_index);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ g_hash_table_insert(copy_structure->field_name_to_index,
+ key, value);
+ }
+
+ for (i = 0; i < structure->fields->len; i++) {
+ struct structure_field *entry, *copy_entry;
+ struct bt_ctf_field_type *copy_field;
+
+ copy_entry = g_new0(struct structure_field, 1);
+ if (!copy_entry) {
+ goto error;
+ }
+
+ entry = g_ptr_array_index(structure->fields, i);
+ copy_field = bt_ctf_field_type_copy(entry->type);
+ if (!copy_field) {
+ g_free(copy_entry);
+ goto error;
+ }
+
+ copy_entry->name = entry->name;
+ copy_entry->type = copy_field;
+ g_ptr_array_add(copy_structure->fields, copy_entry);
+ }
+
+ copy_structure->declaration = structure->declaration;
+end:
+ return copy;
+error:
+ bt_ctf_field_type_put(copy);
+ return NULL;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
+ struct bt_ctf_field_type *type)
+{
+ int i;
+ GHashTableIter iter;
+ gpointer key, value;
+ struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
+ struct bt_ctf_field_type_variant *variant, *copy_variant;
+
+ variant = container_of(type, struct bt_ctf_field_type_variant,
+ parent);
+ if (variant->tag) {
+ copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
+ if (!copy_tag) {
+ goto end;
+ }
+ }
+
+ copy = bt_ctf_field_type_variant_create(copy_tag,
+ variant->tag_name->len ? variant->tag_name->str : NULL);
+ if (!copy) {
+ goto end;
+ }
+
+ copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
+ parent);
+
+ /* Copy field_name_to_index */
+ g_hash_table_iter_init(&iter, variant->field_name_to_index);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ g_hash_table_insert(copy_variant->field_name_to_index,
+ key, value);
+ }
+
+ for (i = 0; i < variant->fields->len; i++) {
+ struct structure_field *entry, *copy_entry;
+ struct bt_ctf_field_type *copy_field;
+
+ copy_entry = g_new0(struct structure_field, 1);
+ if (!copy_entry) {
+ goto error;
+ }
+
+ entry = g_ptr_array_index(variant->fields, i);
+ copy_field = bt_ctf_field_type_copy(entry->type);
+ if (!copy_field) {
+ g_free(copy_entry);
+ goto error;
+ }
+
+ copy_entry->name = entry->name;
+ copy_entry->type = copy_field;
+ g_ptr_array_add(copy_variant->fields, copy_entry);
+ }
+
+ copy_variant->declaration = variant->declaration;
+ if (variant->tag_path) {
+ copy_variant->tag_path = bt_ctf_field_path_copy(
+ variant->tag_path);
+ if (!copy_variant->tag_path) {
+ goto error;
+ }
+ }
+end:
+ if (copy_tag) {
+ bt_ctf_field_type_put(copy_tag);
+ }
+
+ return copy;
+error:
+ if (copy_tag) {
+ bt_ctf_field_type_put(copy_tag);
+ }
+
+ bt_ctf_field_type_put(copy);
+ return NULL;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
+ struct bt_ctf_field_type *type)
+{
+ struct bt_ctf_field_type *copy = NULL, *copy_element;
+ struct bt_ctf_field_type_array *array, *copy_array;
+
+ array = container_of(type, struct bt_ctf_field_type_array,
+ parent);
+ copy_element = bt_ctf_field_type_copy(array->element_type);
+ if (!copy_element) {
+ goto end;
+ }
+
+ copy = bt_ctf_field_type_array_create(copy_element, array->length);
+ if (!copy) {
+ goto end;
+ }
+
+ copy_array = container_of(copy, struct bt_ctf_field_type_array,
+ parent);
+ copy_array->declaration = array->declaration;
+end:
+ if (copy_element) {
+ bt_ctf_field_type_put(copy_element);
+ }
+
+ return copy;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
+ struct bt_ctf_field_type *type)
+{
+ struct bt_ctf_field_type *copy = NULL, *copy_element;
+ struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
+
+ sequence = container_of(type, struct bt_ctf_field_type_sequence,
+ parent);
+ copy_element = bt_ctf_field_type_copy(sequence->element_type);
+ if (!copy_element) {
+ goto end;
+ }
+
+ copy = bt_ctf_field_type_sequence_create(copy_element,
+ sequence->length_field_name->len ?
+ sequence->length_field_name->str : NULL);
+ if (!copy) {
+ goto end;
+ }
+
+ copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
+ parent);
+ copy_sequence->declaration = sequence->declaration;
+ if (sequence->length_field_path) {
+ copy_sequence->length_field_path = bt_ctf_field_path_copy(
+ sequence->length_field_path);
+ if (!copy_sequence->length_field_path) {
+ goto error;
+ }
+ }
+end:
+ if (copy_element) {
+ bt_ctf_field_type_put(copy_element);
+ }
+
+ return copy;
+error:
+ if (copy) {
+ bt_ctf_field_type_put(copy);
+ copy = NULL;
+ }
+ goto end;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
+ struct bt_ctf_field_type *type)
+{
+ struct bt_ctf_field_type *copy;
+ struct bt_ctf_field_type_string *string, *copy_string;
+
+ copy = bt_ctf_field_type_string_create();
+ if (!copy) {
+ goto end;
+ }
+
+ string = container_of(type, struct bt_ctf_field_type_string,
+ parent);
+ copy_string = container_of(type, struct bt_ctf_field_type_string,
+ parent);
+ copy_string->declaration = string->declaration;
+end:
+ return copy;
}