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;
}
}
bt_ctf_field_type_init(&variant->parent);
+ /* A variant's alignment is undefined */
+ variant->parent.declaration->alignment = 0;
return &variant->parent;
error:
return NULL;
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:
return ret;
}
+BT_HIDDEN
+int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type,
+ struct bt_ctf_field_type *field, int index)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_structure *structure;
+
+ if (!type || !field ||
+ bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
+ ret = -1;
+ goto end;
+ }
+
+ structure = container_of(type, struct bt_ctf_field_type_structure,
+ parent);
+ if (index < 0 || index >= structure->fields->len) {
+ ret = -1;
+ goto end;
+ }
+
+ bt_ctf_field_type_get(field);
+ bt_ctf_field_type_put(((struct structure_field *)
+ g_ptr_array_index(structure->fields, index))->type);
+ ((struct structure_field *) structure->fields->pdata[index])->type =
+ field;
+end:
+ return ret;
+}
+
BT_HIDDEN
int bt_ctf_field_type_variant_get_field_name_index(
struct bt_ctf_field_type *type, const char *name)
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;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
+ struct bt_ctf_field_type *field, int index)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_variant *variant;
+
+ if (!type || !field ||
+ 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 (index < 0 || index >= variant->fields->len) {
+ ret = -1;
+ goto end;
+ }
+
+ bt_ctf_field_type_get(field);
+ bt_ctf_field_type_put(((struct structure_field *)
+ g_ptr_array_index(variant->fields, index))->type);
+ ((struct structure_field *) variant->fields->pdata[index])->type =
+ field;
+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