ret = -1;
goto end;
}
-
- if (type->declaration->alignment < field_type->declaration->alignment) {
- type->declaration->alignment =
- field_type->declaration->alignment;
- }
end:
return ret;
}
struct structure_field *field;
int ret = 0;
- if (!type || index < 0 || !field_name || !field_type ||
- (type->declaration->id != CTF_TYPE_STRUCT)) {
+ if (!type || index < 0 || (type->declaration->id != CTF_TYPE_STRUCT)) {
ret = -1;
goto end;
}
}
field = g_ptr_array_index(structure->fields, index);
- *field_type = field->type;
- bt_ctf_field_type_get(field->type);
- *field_name = g_quark_to_string(field->name);
+ if (field_type) {
+ *field_type = field->type;
+ bt_ctf_field_type_get(field->type);
+ }
+ if (field_name) {
+ *field_name = g_quark_to_string(field->name);
+ }
end:
return ret;
}
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)
struct structure_field *field;
int ret = 0;
- if (!type || index < 0 || !field_name || !field_type ||
- (type->declaration->id != CTF_TYPE_VARIANT)) {
+ if (!type || index < 0 || (type->declaration->id != CTF_TYPE_VARIANT)) {
ret = -1;
goto end;
}
}
field = g_ptr_array_index(variant->fields, index);
- *field_type = field->type;
- bt_ctf_field_type_get(field->type);
- *field_name = g_quark_to_string(field->name);
+ if (field_type) {
+ *field_type = field->type;
+ bt_ctf_field_type_get(field->type);
+ }
+ if (field_name) {
+ *field_name = g_quark_to_string(field->name);
+ }
end:
return ret;
}
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;
error:
return NULL;
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;
error:
return NULL;
int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
{
int ret;
+ enum ctf_type_id type_id;
if (!type) {
ret = -1;
goto end;
}
- ret = (int) type->declaration->alignment;
+ if (type->frozen) {
+ ret = (int) type->declaration->alignment;
+ goto end;
+ }
+
+ type_id = bt_ctf_field_type_get_type_id(type);
+ switch (type_id) {
+ case CTF_TYPE_SEQUENCE:
+ {
+ struct bt_ctf_field_type *element =
+ bt_ctf_field_type_sequence_get_element_type(type);
+
+ if (!element) {
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_field_type_get_alignment(element);
+ bt_ctf_field_type_put(element);
+ break;
+ }
+ case CTF_TYPE_ARRAY:
+ {
+ struct bt_ctf_field_type *element =
+ bt_ctf_field_type_array_get_element_type(type);
+
+ if (!element) {
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_field_type_get_alignment(element);
+ bt_ctf_field_type_put(element);
+ break;
+ }
+ case CTF_TYPE_STRUCT:
+ {
+ int i, element_count;
+
+ element_count = bt_ctf_field_type_structure_get_field_count(
+ type);
+ if (element_count < 0) {
+ ret = element_count;
+ goto end;
+ }
+
+ for (i = 0; i < element_count; i++) {
+ struct bt_ctf_field_type *field;
+ int field_alignment;
+
+ ret = bt_ctf_field_type_structure_get_field(type, NULL,
+ &field, i);
+ if (ret) {
+ goto end;
+ }
+
+ assert(field);
+ field_alignment = bt_ctf_field_type_get_alignment(
+ field);
+ bt_ctf_field_type_put(field);
+ if (field_alignment < 0) {
+ ret = field_alignment;
+ goto end;
+ }
+
+ type->declaration->alignment = MAX(field_alignment,
+ type->declaration->alignment);
+ }
+ ret = (int) type->declaration->alignment;
+ break;
+ }
+ case CTF_TYPE_UNKNOWN:
+ ret = -1;
+ break;
+ default:
+ ret = (int) type->declaration->alignment;
+ break;
+ }
end:
return ret;
}
unsigned int alignment)
{
int ret = 0;
+ enum ctf_type_id type_id;
/* Alignment must be bit-aligned (1) or byte aligned */
if (!type || type->frozen || (alignment != 1 && (alignment & 0x7))) {
goto end;
}
+ type_id = bt_ctf_field_type_get_type_id(type);
+ if (type_id == CTF_TYPE_UNKNOWN) {
+ ret = -1;
+ goto end;
+ }
+
if (type->declaration->id == CTF_TYPE_STRING &&
alignment != CHAR_BIT) {
ret = -1;
goto end;
}
+ if (type_id == CTF_TYPE_STRUCT || type_id == CTF_TYPE_VARIANT ||
+ type_id == CTF_TYPE_SEQUENCE || type_id == CTF_TYPE_ARRAY) {
+ /* Setting an alignment on these types makes no sense */
+ ret = -1;
+ goto end;
+ }
+
type->declaration->alignment = alignment;
ret = 0;
end:
goto end;
}
- type_id = type->declaration->id;
switch (byte_order) {
case BT_CTF_BYTE_ORDER_NATIVE:
/* Leave unset. Will be initialized by parent. */
goto end;
}
+ type_id = type->declaration->id;
if (set_byte_order_funcs[type_id]) {
set_byte_order_funcs[type_id](type, internal_byte_order, 0);
}
return copy;
}
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_path_create(void)
+{
+ struct bt_ctf_field_path *field_path = NULL;
+
+ field_path = g_new0(struct bt_ctf_field_path, 1);
+ if (!field_path) {
+ goto end;
+ }
+
+ 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;
+}
+
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_path_copy(
+ struct bt_ctf_field_path *path)
+{
+ struct bt_ctf_field_path *new_path = bt_ctf_field_path_create();
+
+ if (!new_path) {
+ goto end;
+ }
+
+ 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;
+}
+
+BT_HIDDEN
+void bt_ctf_field_path_destroy(struct bt_ctf_field_path *path)
+{
+ if (!path) {
+ return;
+ }
+
+ if (path->path_indexes) {
+ g_array_free(path->path_indexes, TRUE);
+ }
+ g_free(path);
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_structure_get_field_name_index(
+ struct bt_ctf_field_type *type, const char *name)
+{
+ int ret;
+ size_t index;
+ GQuark name_quark;
+ struct bt_ctf_field_type_structure *structure;
+
+ if (!type || !name ||
+ bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
+ ret = -1;
+ goto end;
+ }
+
+ 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;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_variant_get_field_name_index(
+ struct bt_ctf_field_type *type, const char *name)
+{
+ int ret;
+ size_t index;
+ GQuark name_quark;
+ struct bt_ctf_field_type_variant *variant;
+
+ if (!type || !name ||
+ bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
+ ret = -1;
+ goto end;
+ }
+
+ 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)
{
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);
}
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_structure *structure_type = container_of(
type, struct bt_ctf_field_type_structure, parent);
+ /* Cache the alignment */
+ type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
generic_field_type_freeze(type);
- g_ptr_array_foreach(structure_type->fields, (GFunc)freeze_structure_field,
- NULL);
+ g_ptr_array_foreach(structure_type->fields,
+ (GFunc) freeze_structure_field, NULL);
}
static
struct bt_ctf_field_type_variant *variant_type = container_of(
type, struct bt_ctf_field_type_variant, parent);
+ /* Cache the alignment */
+ type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
generic_field_type_freeze(type);
- g_ptr_array_foreach(variant_type->fields, (GFunc)freeze_structure_field,
- NULL);
+ g_ptr_array_foreach(variant_type->fields,
+ (GFunc) freeze_structure_field, NULL);
}
static
struct bt_ctf_field_type_array *array_type = container_of(
type, struct bt_ctf_field_type_array, parent);
+ /* Cache the alignment */
+ type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
generic_field_type_freeze(type);
bt_ctf_field_type_freeze(array_type->element_type);
}
struct bt_ctf_field_type_sequence *sequence_type = container_of(
type, struct bt_ctf_field_type_sequence, parent);
+ /* Cache the alignment */
+ type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
generic_field_type_freeze(type);
bt_ctf_field_type_freeze(sequence_type->element_type);
}
}
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);
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