From b92ddaaaabecef22b73d6276d19a0f9ddc700720 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Fri, 16 May 2014 11:10:44 -0400 Subject: [PATCH] Implement CTF-IR field types getters MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémie Galarneau --- formats/ctf/ir/event-fields.c | 52 +- formats/ctf/ir/event-types.c | 940 ++++++++++++++++-- .../babeltrace/ctf-ir/event-types-internal.h | 32 +- include/babeltrace/ctf-ir/event-types.h | 408 +++++++- 4 files changed, 1304 insertions(+), 128 deletions(-) diff --git a/formats/ctf/ir/event-fields.c b/formats/ctf/ir/event-fields.c index ac77cfb7..17c597ac 100644 --- a/formats/ctf/ir/event-fields.c +++ b/formats/ctf/ir/event-fields.c @@ -305,8 +305,7 @@ struct bt_ctf_field *bt_ctf_field_structure_get_field( 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 || @@ -317,9 +316,9 @@ struct bt_ctf_field *bt_ctf_field_structure_get_field( 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; @@ -339,6 +338,9 @@ struct bt_ctf_field *bt_ctf_field_structure_get_field( end: bt_ctf_field_get(new_field); error: + if (field_type) { + bt_ctf_field_type_put(field_type); + } return new_field; } @@ -402,8 +404,7 @@ int bt_ctf_field_structure_set_field(struct bt_ctf_field *field, 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 || @@ -415,10 +416,9 @@ int bt_ctf_field_structure_set_field(struct bt_ctf_field *field, 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; @@ -436,6 +436,9 @@ int bt_ctf_field_structure_set_field(struct bt_ctf_field *field, 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; } @@ -443,9 +446,8 @@ struct bt_ctf_field *bt_ctf_field_array_get_field(struct bt_ctf_field *field, 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) { @@ -457,9 +459,7 @@ struct bt_ctf_field *bt_ctf_field_array_get_field(struct bt_ctf_field *field, 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; @@ -469,6 +469,9 @@ struct bt_ctf_field *bt_ctf_field_array_get_field(struct bt_ctf_field *field, 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; } @@ -476,9 +479,8 @@ struct bt_ctf_field *bt_ctf_field_sequence_get_field(struct bt_ctf_field *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) { @@ -490,9 +492,7 @@ struct bt_ctf_field *bt_ctf_field_sequence_get_field(struct bt_ctf_field *field, 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; @@ -502,6 +502,9 @@ struct bt_ctf_field *bt_ctf_field_sequence_get_field(struct bt_ctf_field *field, 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; } @@ -540,8 +543,8 @@ struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field, } 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; } @@ -568,7 +571,8 @@ struct bt_ctf_field *bt_ctf_field_enumeration_get_container( 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; } diff --git a/formats/ctf/ir/event-types.c b/formats/ctf/ir/event-types.c index 250d9595..48a2a746 100644 --- a/formats/ctf/ir/event-types.c +++ b/formats/ctf/ir/event-types.c @@ -36,7 +36,15 @@ #include struct range_overlap_query { - int64_t range_start, range_end; + union { + uint64_t _unsigned; + int64_t _signed; + } range_start; + + union { + uint64_t _unsigned; + int64_t _signed; + } range_end; int overlaps; GQuark mapping_name; }; @@ -154,7 +162,6 @@ void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *, [CTF_TYPE_ENUM ... CTF_TYPE_SEQUENCE] = NULL, }; - static void destroy_enumeration_mapping(struct enumeration_mapping *mapping) { @@ -177,8 +184,26 @@ void check_ranges_overlap(gpointer element, gpointer query) struct enumeration_mapping *mapping = element; struct range_overlap_query *overlap_query = query; - if (mapping->range_start <= overlap_query->range_end - && overlap_query->range_start <= mapping->range_end) { + if (mapping->range_start._signed <= overlap_query->range_end._signed + && overlap_query->range_start._signed <= + mapping->range_end._signed) { + overlap_query->overlaps = 1; + overlap_query->mapping_name = mapping->string; + } + + overlap_query->overlaps |= + mapping->string == overlap_query->mapping_name; +} + +static +void check_ranges_overlap_unsigned(gpointer element, gpointer query) +{ + struct enumeration_mapping *mapping = element; + struct range_overlap_query *overlap_query = query; + + if (mapping->range_start._unsigned <= overlap_query->range_end._unsigned + && overlap_query->range_start._unsigned <= + mapping->range_end._unsigned) { overlap_query->overlaps = 1; overlap_query->mapping_name = mapping->string; } @@ -187,6 +212,20 @@ void check_ranges_overlap(gpointer element, gpointer query) mapping->string == overlap_query->mapping_name; } +static +gint compare_enumeration_mappings_signed(struct enumeration_mapping **a, + struct enumeration_mapping **b) +{ + return ((*a)->range_start._signed < (*b)->range_start._signed) ? -1 : 1; +} + +static +gint compare_enumeration_mappings_unsigned(struct enumeration_mapping **a, + struct enumeration_mapping **b) +{ + return ((*a)->range_start._unsigned < (*b)->range_start._unsigned) ? -1 : 1; +} + static void bt_ctf_field_type_init(struct bt_ctf_field_type *type) { @@ -278,6 +317,38 @@ struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size) return &integer->parent; } +int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *type) +{ + int ret = 0; + struct bt_ctf_field_type_integer *integer; + + if (!type || type->declaration->id != CTF_TYPE_INTEGER) { + ret = -1; + goto end; + } + + integer = container_of(type, struct bt_ctf_field_type_integer, parent); + ret = (int) integer->declaration.len; +end: + return ret; +} + +int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type *type) +{ + int ret = 0; + struct bt_ctf_field_type_integer *integer; + + if (!type || type->declaration->id != CTF_TYPE_INTEGER) { + ret = -1; + goto end; + } + + integer = container_of(type, struct bt_ctf_field_type_integer, parent); + ret = integer->declaration.signedness; +end: + return ret; +} + int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type *type, int is_signed) { @@ -301,6 +372,22 @@ end: return ret; } +enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base( + struct bt_ctf_field_type *type) +{ + enum bt_ctf_integer_base ret = BT_CTF_INTEGER_BASE_UNKNOWN; + struct bt_ctf_field_type_integer *integer; + + if (!type || type->declaration->id != CTF_TYPE_INTEGER) { + goto end; + } + + integer = container_of(type, struct bt_ctf_field_type_integer, parent); + ret = integer->declaration.base; +end: + return ret; +} + int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *type, enum bt_ctf_integer_base base) { @@ -330,6 +417,22 @@ end: return ret; } +enum ctf_string_encoding bt_ctf_field_type_integer_get_encoding( + struct bt_ctf_field_type *type) +{ + enum ctf_string_encoding ret = CTF_STRING_UNKNOWN; + struct bt_ctf_field_type_integer *integer; + + if (!type || type->declaration->id != CTF_TYPE_INTEGER) { + goto end; + } + + integer = container_of(type, struct bt_ctf_field_type_integer, parent); + ret = integer->declaration.encoding; +end: + return ret; +} + int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *type, enum ctf_string_encoding encoding) { @@ -381,6 +484,28 @@ error: return NULL; } +struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type( + struct bt_ctf_field_type *type) +{ + struct bt_ctf_field_type *container_type = NULL; + struct bt_ctf_field_type_enumeration *enumeration_type; + + if (!type) { + goto end; + } + + if (type->declaration->id != CTF_TYPE_ENUM) { + goto end; + } + + enumeration_type = container_of(type, + struct bt_ctf_field_type_enumeration, parent); + container_type = enumeration_type->container; + bt_ctf_field_type_get(container_type); +end: + return container_type; +} + int bt_ctf_field_type_enumeration_add_mapping( struct bt_ctf_field_type *type, const char *string, int64_t range_start, int64_t range_end) @@ -411,8 +536,9 @@ int bt_ctf_field_type_enumeration_add_mapping( } mapping_name = g_quark_from_string(escaped_string); - query = (struct range_overlap_query) { .range_start = range_start, - .range_end = range_end, + query = (struct range_overlap_query) { + .range_start._signed = range_start, + .range_end._signed = range_end, .mapping_name = mapping_name, .overlaps = 0 }; enumeration = container_of(type, struct bt_ctf_field_type_enumeration, @@ -431,9 +557,76 @@ int bt_ctf_field_type_enumeration_add_mapping( goto error_free; } - *mapping = (struct enumeration_mapping) {.range_start = range_start, - .range_end = range_end, .string = mapping_name}; + *mapping = (struct enumeration_mapping) { + .range_start._signed = range_start, + .range_end._signed = range_end, .string = mapping_name}; g_ptr_array_add(enumeration->entries, mapping); + g_ptr_array_sort(enumeration->entries, + (GCompareFunc)compare_enumeration_mappings_signed); +error_free: + free(escaped_string); +end: + return ret; +} + +int bt_ctf_field_type_enumeration_add_mapping_unsigned( + struct bt_ctf_field_type *type, const char *string, + uint64_t range_start, uint64_t range_end) +{ + int ret = 0; + GQuark mapping_name; + struct enumeration_mapping *mapping; + struct bt_ctf_field_type_enumeration *enumeration; + struct range_overlap_query query; + char *escaped_string; + + if (!type || (type->declaration->id != CTF_TYPE_ENUM) || + type->frozen || + (range_end < range_start)) { + ret = -1; + goto end; + } + + if (!string || strlen(string) == 0) { + ret = -1; + goto end; + } + + escaped_string = g_strescape(string, NULL); + if (!escaped_string) { + ret = -1; + goto end; + } + + mapping_name = g_quark_from_string(escaped_string); + query = (struct range_overlap_query) { + .range_start._unsigned = range_start, + .range_end._unsigned = range_end, + .mapping_name = mapping_name, + .overlaps = 0 }; + enumeration = container_of(type, struct bt_ctf_field_type_enumeration, + parent); + + /* Check that the range does not overlap with one already present */ + g_ptr_array_foreach(enumeration->entries, check_ranges_overlap_unsigned, + &query); + if (query.overlaps) { + ret = -1; + goto error_free; + } + + mapping = g_new(struct enumeration_mapping, 1); + if (!mapping) { + ret = -1; + goto error_free; + } + + *mapping = (struct enumeration_mapping) { + .range_start._unsigned = range_start, + .range_end._unsigned = range_end, .string = mapping_name}; + g_ptr_array_add(enumeration->entries, mapping); + g_ptr_array_sort(enumeration->entries, + (GCompareFunc)compare_enumeration_mappings_unsigned); error_free: free(escaped_string); end: @@ -447,12 +640,12 @@ const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned( const char *name = NULL; struct range_overlap_query query = (struct range_overlap_query) { - /* FIXME: should not need a cast */ - .range_start = (int64_t) value, - .range_end = (int64_t) value, + .range_start._unsigned = value, + .range_end._unsigned = value, .overlaps = 0 }; - g_ptr_array_foreach(enumeration_type->entries, check_ranges_overlap, + g_ptr_array_foreach(enumeration_type->entries, + check_ranges_overlap_unsigned, &query); if (!query.overlaps) { goto end; @@ -470,8 +663,8 @@ const char *bt_ctf_field_type_enumeration_get_mapping_name_signed( const char *name = NULL; struct range_overlap_query query = (struct range_overlap_query) { - .range_start = value, - .range_end = value, + .range_start._signed = value, + .range_end._signed = value, .overlaps = 0 }; g_ptr_array_foreach(enumeration_type->entries, check_ranges_overlap, @@ -485,6 +678,194 @@ end: return name; } +int64_t bt_ctf_field_type_enumeration_get_mapping_count( + struct bt_ctf_field_type *type) +{ + int64_t ret = 0; + struct bt_ctf_field_type_enumeration *enumeration; + + if (!type || (type->declaration->id != CTF_TYPE_ENUM)) { + ret = -1; + goto end; + } + + enumeration = container_of(type, struct bt_ctf_field_type_enumeration, + parent); + ret = enumeration->entries->len; +end: + return ret; +} + +static inline +struct enumeration_mapping *get_enumeration_mapping( + struct bt_ctf_field_type *type, size_t index) +{ + struct enumeration_mapping *mapping = NULL; + struct bt_ctf_field_type_enumeration *enumeration; + + enumeration = container_of(type, struct bt_ctf_field_type_enumeration, + parent); + if (index >= enumeration->entries->len) { + goto end; + } + + mapping = g_ptr_array_index(enumeration->entries, index); +end: + return mapping; +} + +int bt_ctf_field_type_enumeration_get_mapping( + struct bt_ctf_field_type *type, size_t index, + const char **string, int64_t *range_start, int64_t *range_end) +{ + struct enumeration_mapping *mapping; + int ret = 0; + + if (!type || !string || !range_start || !range_end || + (type->declaration->id != CTF_TYPE_ENUM)) { + ret = -1; + goto end; + } + + mapping = get_enumeration_mapping(type, index); + if (!mapping) { + ret = -1; + goto end; + } + + *string = g_quark_to_string(mapping->string); + *range_start = mapping->range_start._signed; + *range_end = mapping->range_end._signed; +end: + return ret; +} + +int bt_ctf_field_type_enumeration_get_mapping_unsigned( + struct bt_ctf_field_type *type, size_t index, + const char **string, uint64_t *range_start, uint64_t *range_end) +{ + struct enumeration_mapping *mapping; + int ret = 0; + + if (!type || !string || !range_start || !range_end || + (type->declaration->id != CTF_TYPE_ENUM)) { + ret = -1; + goto end; + } + + mapping = get_enumeration_mapping(type, index); + if (!mapping) { + ret = -1; + goto end; + } + + *string = g_quark_to_string(mapping->string); + *range_start = mapping->range_start._unsigned; + *range_end = mapping->range_end._unsigned; +end: + return ret; +} + +int bt_ctf_field_type_enumeration_get_mapping_index_by_name( + struct bt_ctf_field_type *type, const char *name, + size_t *index) +{ + size_t i; + GQuark name_quark; + struct bt_ctf_field_type_enumeration *enumeration; + int ret = 0; + + if (!type || !name || !index || + (type->declaration->id != CTF_TYPE_ENUM)) { + ret = -1; + goto end; + } + + name_quark = g_quark_try_string(name); + if (!name_quark) { + ret = -1; + goto end; + } + + enumeration = container_of(type, + struct bt_ctf_field_type_enumeration, parent); + for (i = 0; i < enumeration->entries->len; i++) { + struct enumeration_mapping *mapping = + get_enumeration_mapping(type, i); + + if (mapping->string == name_quark) { + *index = i; + goto end; + } + } + + ret = -1; +end: + return ret; +} + +int bt_ctf_field_type_enumeration_get_mapping_index_by_value( + struct bt_ctf_field_type *type, int64_t value, + size_t *index) +{ + struct bt_ctf_field_type_enumeration *enumeration; + size_t i; + int ret = 0; + + if (!type || !index || (type->declaration->id != CTF_TYPE_ENUM)) { + ret = -1; + goto end; + } + + enumeration = container_of(type, + struct bt_ctf_field_type_enumeration, parent); + for (i = 0; i < enumeration->entries->len; i++) { + struct enumeration_mapping *mapping = + get_enumeration_mapping(type, i); + + if (value >= mapping->range_start._signed && + value <= mapping->range_end._signed) { + *index = i; + goto end; + } + } + + ret = -1; +end: + return ret; +} + +int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value( + struct bt_ctf_field_type *type, uint64_t value, + size_t *index) +{ + struct bt_ctf_field_type_enumeration *enumeration; + size_t i; + int ret = 0; + + if (!type || !index || (type->declaration->id != CTF_TYPE_ENUM)) { + ret = -1; + goto end; + } + + enumeration = container_of(type, + struct bt_ctf_field_type_enumeration, parent); + for (i = 0; i < enumeration->entries->len; i++) { + struct enumeration_mapping *mapping = + get_enumeration_mapping(type, i); + + if (value >= mapping->range_start._unsigned && + value <= mapping->range_end._unsigned) { + *index = i; + goto end; + } + } + + ret = -1; +end: + return ret; +} + struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void) { struct bt_ctf_field_type_floating_point *floating_point = @@ -512,6 +893,24 @@ end: return floating_point ? &floating_point->parent : NULL; } +int bt_ctf_field_type_floating_point_get_exponent_digits( + struct bt_ctf_field_type *type) +{ + int ret = 0; + struct bt_ctf_field_type_floating_point *floating_point; + + if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) { + ret = -1; + goto end; + } + + floating_point = container_of(type, + struct bt_ctf_field_type_floating_point, parent); + ret = (int) floating_point->declaration.exp->len; +end: + return ret; +} + int bt_ctf_field_type_floating_point_set_exponent_digits( struct bt_ctf_field_type *type, unsigned int exponent_digits) @@ -540,6 +939,24 @@ end: return ret; } +int bt_ctf_field_type_floating_point_get_mantissa_digits( + struct bt_ctf_field_type *type) +{ + int ret = 0; + struct bt_ctf_field_type_floating_point *floating_point; + + if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) { + ret = -1; + goto end; + } + + floating_point = container_of(type, + struct bt_ctf_field_type_floating_point, parent); + ret = (int) floating_point->mantissa.len + 1; +end: + return ret; +} + int bt_ctf_field_type_floating_point_set_mantissa_digits( struct bt_ctf_field_type *type, unsigned int mantissa_digits) @@ -610,12 +1027,92 @@ int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type, goto end; } - if (type->declaration->alignment < field_type->declaration->alignment) { - type->declaration->alignment = - field_type->declaration->alignment; + if (type->declaration->alignment < field_type->declaration->alignment) { + type->declaration->alignment = + field_type->declaration->alignment; + } +end: + return ret; +} + +int64_t bt_ctf_field_type_structure_get_field_count( + struct bt_ctf_field_type *type) +{ + int64_t ret = 0; + struct bt_ctf_field_type_structure *structure; + + if (!type || (type->declaration->id != CTF_TYPE_STRUCT)) { + ret = -1; + goto end; + } + + structure = container_of(type, struct bt_ctf_field_type_structure, + parent); + ret = structure->fields->len; +end: + return ret; +} + +int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type, + const char **field_name, struct bt_ctf_field_type **field_type, + size_t index) +{ + struct bt_ctf_field_type_structure *structure; + struct structure_field *field; + int ret = 0; + + if (!type || !field_name || !field_type || + (type->declaration->id != CTF_TYPE_STRUCT)) { + ret = -1; + goto end; + } + + structure = container_of(type, struct bt_ctf_field_type_structure, + parent); + if (index >= structure->fields->len) { + 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); +end: + return ret; +} + +struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name( + struct bt_ctf_field_type *type, + const char *name) +{ + size_t index; + GQuark name_quark; + struct structure_field *field; + struct bt_ctf_field_type_structure *structure; + struct bt_ctf_field_type *field_type = NULL; + + if (!type || !name) { + goto end; + } + + name_quark = g_quark_try_string(name); + if (!name_quark) { + 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)) { + goto end; } + + field = structure->fields->pdata[index]; + field_type = field->type; + bt_ctf_field_type_get(field_type); end: - return ret; + return field_type; } struct bt_ctf_field_type *bt_ctf_field_type_variant_create( @@ -648,6 +1145,39 @@ error: return NULL; } +struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type( + struct bt_ctf_field_type *type) +{ + struct bt_ctf_field_type_variant *variant; + struct bt_ctf_field_type *tag_type = NULL; + + if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) { + goto end; + } + + variant = container_of(type, struct bt_ctf_field_type_variant, parent); + tag_type = &variant->tag->parent; + bt_ctf_field_type_get(tag_type); +end: + return tag_type; +} + +const char *bt_ctf_field_type_variant_get_tag_name( + struct bt_ctf_field_type *type) +{ + struct bt_ctf_field_type_variant *variant; + const char *tag_name = NULL; + + if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) { + goto end; + } + + variant = container_of(type, struct bt_ctf_field_type_variant, parent); + tag_name = variant->tag_name->str; +end: + return tag_name; +} + 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) @@ -687,6 +1217,108 @@ end: return ret; } +struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name( + struct bt_ctf_field_type *type, + const char *field_name) +{ + size_t index; + GQuark name_quark; + struct structure_field *field; + struct bt_ctf_field_type_variant *variant; + struct bt_ctf_field_type *field_type = NULL; + + if (!type || !field_name) { + goto end; + } + + name_quark = g_quark_try_string(field_name); + if (!name_quark) { + 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)) { + goto end; + } + + field = g_ptr_array_index(variant->fields, index); + field_type = field->type; + bt_ctf_field_type_get(field_type); +end: + return field_type; +} + +struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag( + struct bt_ctf_field_type *type, + struct bt_ctf_field *tag) +{ + const char *enum_value; + struct bt_ctf_field_type *field_type = NULL; + + if (!type || !tag || type->declaration->id != CTF_TYPE_VARIANT) { + goto end; + } + + enum_value = bt_ctf_field_enumeration_get_mapping_name(tag); + if (!enum_value) { + goto end; + } + + /* Already increments field_type's reference count */ + field_type = bt_ctf_field_type_variant_get_field_type_by_name( + type, enum_value); +end: + return field_type; +} + +int64_t bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type) +{ + int64_t ret = 0; + struct bt_ctf_field_type_variant *variant; + + if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) { + ret = -1; + goto end; + } + + variant = container_of(type, struct bt_ctf_field_type_variant, + parent); + ret = variant->fields->len; +end: + return ret; + +} + +int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type, + const char **field_name, struct bt_ctf_field_type **field_type, + size_t index) +{ + struct bt_ctf_field_type_variant *variant; + struct structure_field *field; + int ret = 0; + + if (!type || !field_name || !field_type || + (type->declaration->id != CTF_TYPE_VARIANT)) { + ret = -1; + goto end; + } + + variant = container_of(type, struct bt_ctf_field_type_variant, + parent); + if (index >= variant->fields->len) { + 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); +end: + return ret; +} + struct bt_ctf_field_type *bt_ctf_field_type_array_create( struct bt_ctf_field_type *element_type, unsigned int length) @@ -716,6 +1348,39 @@ error: return NULL; } +struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type( + struct bt_ctf_field_type *type) +{ + struct bt_ctf_field_type *ret = NULL; + struct bt_ctf_field_type_array *array; + + if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) { + goto end; + } + + array = container_of(type, struct bt_ctf_field_type_array, parent); + ret = array->element_type; + bt_ctf_field_type_get(ret); +end: + return ret; +} + +int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type) +{ + int64_t ret; + struct bt_ctf_field_type_array *array; + + if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) { + ret = -1; + goto end; + } + + array = container_of(type, struct bt_ctf_field_type_array, parent); + ret = (int64_t) array->length; +end: + return ret; +} + struct bt_ctf_field_type *bt_ctf_field_type_sequence_create( struct bt_ctf_field_type *element_type, const char *length_field_name) @@ -745,6 +1410,41 @@ error: return NULL; } +struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type( + struct bt_ctf_field_type *type) +{ + struct bt_ctf_field_type *ret = NULL; + struct bt_ctf_field_type_sequence *sequence; + + if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) { + goto end; + } + + sequence = container_of(type, struct bt_ctf_field_type_sequence, + parent); + ret = sequence->element_type; + bt_ctf_field_type_get(ret); +end: + return ret; +} + +const char *bt_ctf_field_type_sequence_get_length_field_name( + struct bt_ctf_field_type *type) +{ + const char *ret = NULL; + struct bt_ctf_field_type_sequence *sequence; + + if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) { + goto end; + } + + sequence = container_of(type, struct bt_ctf_field_type_sequence, + parent); + ret = sequence->length_field_name->str; +end: + return ret; +} + struct bt_ctf_field_type *bt_ctf_field_type_string_create(void) { struct bt_ctf_field_type_string *string = @@ -762,8 +1462,24 @@ struct bt_ctf_field_type *bt_ctf_field_type_string_create(void) return &string->parent; } -int bt_ctf_field_type_string_set_encoding( - struct bt_ctf_field_type *type, +enum ctf_string_encoding bt_ctf_field_type_string_get_encoding( + struct bt_ctf_field_type *type) +{ + struct bt_ctf_field_type_string *string; + enum ctf_string_encoding ret = CTF_STRING_UNKNOWN; + + if (!type || (type->declaration->id != CTF_TYPE_STRING)) { + goto end; + } + + string = container_of(type, struct bt_ctf_field_type_string, + parent); + ret = string->declaration.encoding; +end: + return ret; +} + +int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type, enum ctf_string_encoding encoding) { int ret = 0; @@ -782,6 +1498,20 @@ end: return ret; } +int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type) +{ + int ret; + + if (!type) { + ret = -1; + goto end; + } + + ret = (int) type->declaration->alignment; +end: + return ret; +} + int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type, unsigned int alignment) { @@ -805,6 +1535,43 @@ end: return ret; } +enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order( + struct bt_ctf_field_type *type) +{ + enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN; + + if (!type) { + goto end; + } + + switch (type->declaration->id) { + case CTF_TYPE_INTEGER: + { + 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; + break; + } + case CTF_TYPE_FLOAT: + { + struct bt_ctf_field_type_floating_point *floating_point = + 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; + break; + } + default: + break; + } +end: + return ret; +} + int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type, enum bt_ctf_byte_order byte_order) { @@ -842,6 +1609,16 @@ end: return ret; } +enum ctf_type_id bt_ctf_field_type_get_type_id( + struct bt_ctf_field_type *type) +{ + if (!type) { + return CTF_TYPE_UNKNOWN; + } + + return type->declaration->id; +} + void bt_ctf_field_type_get(struct bt_ctf_field_type *type) { if (!type) { @@ -875,70 +1652,53 @@ void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type) } BT_HIDDEN -enum ctf_type_id bt_ctf_field_type_get_type_id( - struct bt_ctf_field_type *type) -{ - if (!type) { - return CTF_TYPE_UNKNOWN; - } - - return type->declaration->id; -} - -BT_HIDDEN -struct bt_ctf_field_type *bt_ctf_field_type_structure_get_type( - struct bt_ctf_field_type_structure *structure, - const char *name) +struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed( + struct bt_ctf_field_type_variant *variant, + int64_t tag_value) { struct bt_ctf_field_type *type = NULL; - struct structure_field *field; - GQuark name_quark = g_quark_try_string(name); - size_t index; + GQuark field_name_quark; + gpointer index; + struct structure_field *field_entry; + struct range_overlap_query query = { + .range_start._signed = tag_value, + .range_end._signed = tag_value, + .mapping_name = 0, .overlaps = 0}; - if (!name_quark) { + g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap, + &query); + if (!query.overlaps) { goto end; } - if (!g_hash_table_lookup_extended(structure->field_name_to_index, - GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) { + field_name_quark = query.mapping_name; + if (!g_hash_table_lookup_extended(variant->field_name_to_index, + GUINT_TO_POINTER(field_name_quark), NULL, &index)) { goto end; } - field = structure->fields->pdata[index]; - type = field->type; + field_entry = g_ptr_array_index(variant->fields, (size_t)index); + type = field_entry->type; end: return type; } BT_HIDDEN -struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type( - struct bt_ctf_field_type_array *array) -{ - assert(array); - return array->element_type; -} - -BT_HIDDEN -struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type( - struct bt_ctf_field_type_sequence *sequence) -{ - assert(sequence); - return sequence->element_type; -} - -BT_HIDDEN -struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type( +struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned( struct bt_ctf_field_type_variant *variant, - int64_t tag_value) + uint64_t tag_value) { struct bt_ctf_field_type *type = NULL; GQuark field_name_quark; gpointer index; struct structure_field *field_entry; - struct range_overlap_query query = {.range_start = tag_value, - .range_end = tag_value, .mapping_name = 0, .overlaps = 0}; + struct range_overlap_query query = { + .range_start._unsigned = tag_value, + .range_end._unsigned = tag_value, + .mapping_name = 0, .overlaps = 0}; - g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap, + g_ptr_array_foreach(variant->tag->entries, + check_ranges_overlap_unsigned, &query); if (!query.overlaps) { goto end; @@ -1241,16 +2001,30 @@ int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type, int ret; struct bt_ctf_field_type_enumeration *enumeration = container_of(type, struct bt_ctf_field_type_enumeration, parent); + struct bt_ctf_field_type *container_type; + int container_signed; ret = bt_ctf_field_type_validate(type); if (ret) { goto end; } + container_type = bt_ctf_field_type_enumeration_get_container_type(type); + if (!container_type) { + ret = -1; + goto end; + } + + container_signed = bt_ctf_field_type_integer_get_signed(container_type); + if (container_signed < 0) { + ret = container_signed; + goto error_put_container_type; + } + g_string_append(context->string, "enum : "); ret = bt_ctf_field_type_serialize(enumeration->container, context); if (ret) { - goto end; + goto error_put_container_type; } g_string_append(context->string, " { "); @@ -1258,16 +2032,34 @@ int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type, struct enumeration_mapping *mapping = enumeration->entries->pdata[entry]; - if (mapping->range_start == mapping->range_end) { - g_string_append_printf(context->string, - "\"%s\" = %" PRId64, - g_quark_to_string(mapping->string), - mapping->range_start); + if (container_signed) { + if (mapping->range_start._signed == + mapping->range_end._signed) { + g_string_append_printf(context->string, + "\"%s\" = %" PRId64, + g_quark_to_string(mapping->string), + mapping->range_start._signed); + } else { + g_string_append_printf(context->string, + "\"%s\" = %" PRId64 " ... %" PRId64, + g_quark_to_string(mapping->string), + mapping->range_start._signed, + mapping->range_end._signed); + } } else { - g_string_append_printf(context->string, - "\"%s\" = %" PRId64 " ... %" PRId64, - g_quark_to_string(mapping->string), - mapping->range_start, mapping->range_end); + if (mapping->range_start._unsigned == + mapping->range_end._unsigned) { + g_string_append_printf(context->string, + "\"%s\" = %" PRIu64, + g_quark_to_string(mapping->string), + mapping->range_start._unsigned); + } else { + g_string_append_printf(context->string, + "\"%s\" = %" PRIu64 " ... %" PRIu64, + g_quark_to_string(mapping->string), + mapping->range_start._unsigned, + mapping->range_end._unsigned); + } } g_string_append(context->string, @@ -1280,6 +2072,8 @@ int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type, context->field_name->str); g_string_assign(context->field_name, ""); } +error_put_container_type: + bt_ctf_field_type_put(container_type); end: return ret; } diff --git a/include/babeltrace/ctf-ir/event-types-internal.h b/include/babeltrace/ctf-ir/event-types-internal.h index 5471228a..8d0477b5 100644 --- a/include/babeltrace/ctf-ir/event-types-internal.h +++ b/include/babeltrace/ctf-ir/event-types-internal.h @@ -59,8 +59,15 @@ struct bt_ctf_field_type_integer { }; struct enumeration_mapping { - int64_t range_start; - int64_t range_end; + union { + uint64_t _unsigned; + int64_t _signed; + } range_start; + + union { + uint64_t _unsigned; + int64_t _signed; + } range_end; GQuark string; }; @@ -123,25 +130,12 @@ BT_HIDDEN void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type); BT_HIDDEN -enum ctf_type_id bt_ctf_field_type_get_type_id( - struct bt_ctf_field_type *type); - -BT_HIDDEN -struct bt_ctf_field_type *bt_ctf_field_type_structure_get_type( - struct bt_ctf_field_type_structure *structure, - const char *name); - -BT_HIDDEN -struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type( - struct bt_ctf_field_type_array *array); - -BT_HIDDEN -struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type( - struct bt_ctf_field_type_sequence *sequence); +struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed( + struct bt_ctf_field_type_variant *variant, int64_t tag_value); BT_HIDDEN -struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type( - struct bt_ctf_field_type_variant *variant, int64_t tag_value); +struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned( + struct bt_ctf_field_type_variant *variant, uint64_t tag_value); BT_HIDDEN int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type, diff --git a/include/babeltrace/ctf-ir/event-types.h b/include/babeltrace/ctf-ir/event-types.h index f51dde37..96200ce4 100644 --- a/include/babeltrace/ctf-ir/event-types.h +++ b/include/babeltrace/ctf-ir/event-types.h @@ -40,6 +40,7 @@ extern "C" { struct bt_ctf_event_class; struct bt_ctf_event; struct bt_ctf_field_type; +struct bt_ctf_field; enum bt_ctf_integer_base { BT_CTF_INTEGER_BASE_UNKNOWN = -1, @@ -50,6 +51,7 @@ enum bt_ctf_integer_base { }; enum bt_ctf_byte_order { + BT_CTF_BYTE_ORDER_UNKNOWN = -1, BT_CTF_BYTE_ORDER_NATIVE = 0, BT_CTF_BYTE_ORDER_LITTLE_ENDIAN, BT_CTF_BYTE_ORDER_BIG_ENDIAN, @@ -60,7 +62,7 @@ enum bt_ctf_byte_order { * bt_ctf_field_type_integer_create: create an integer field type. * * Allocate a new integer field type of the given size. The creation of a field - * type sets its reference count to 1. + * type sets its reference countto 1. * * @param size Integer field type size/length in bits. * @@ -69,6 +71,30 @@ enum bt_ctf_byte_order { extern struct bt_ctf_field_type *bt_ctf_field_type_integer_create( unsigned int size); +/* + * bt_ctf_field_type_integer_get_size: get an integer type's size. + * + * Get an integer type's size. + * + * @param integer Integer type. + * + * Returns the integer type's size, a negative value on error. + */ +extern int bt_ctf_field_type_integer_get_size( + struct bt_ctf_field_type *integer); + +/* + * bt_ctf_field_type_integer_get_signed: get an integer type's signedness. + * + * Get an integer type's signedness attribute. + * + * @param integer Integer type. + * + * Returns the integer's signedness, a negative value on error. + */ +extern int bt_ctf_field_type_integer_get_signed( + struct bt_ctf_field_type *integer); + /* * bt_ctf_field_type_integer_set_signed: set an integer type's signedness. * @@ -82,6 +108,19 @@ extern struct bt_ctf_field_type *bt_ctf_field_type_integer_create( extern int bt_ctf_field_type_integer_set_signed( struct bt_ctf_field_type *integer, int is_signed); +/* + * bt_ctf_field_type_integer_get_base: get an integer type's base. + * + * Get an integer type's base used to pretty-print the resulting trace. + * + * @param integer Integer type. + * + * Returns the integer type's base on success, BT_CTF_INTEGER_BASE_UNKNOWN on + * error. + */ +extern enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base( + struct bt_ctf_field_type *integer); + /* * bt_ctf_field_type_integer_set_base: set an integer type's base. * @@ -95,6 +134,16 @@ extern int bt_ctf_field_type_integer_set_signed( extern int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *integer, enum bt_ctf_integer_base base); +/* + * bt_ctf_field_type_integer_get_encoding: get an integer type's encoding. + * + * @param integer Integer type. + * + * Returns the string field's encoding on success, CTF_STRING_UNKNOWN on error. + */ +extern enum ctf_string_encoding bt_ctf_field_type_integer_get_encoding( + struct bt_ctf_field_type *integer); + /* * bt_ctf_field_type_integer_set_encoding: set an integer type's encoding. * @@ -126,22 +175,142 @@ extern int bt_ctf_field_type_integer_set_encoding( extern struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create( struct bt_ctf_field_type *integer_container_type); +/* + * bt_ctf_field_type_enumeration_get_container_type: get underlying container. + * + * Get the enumeration type's underlying integer container type. + * + * @param enumeration Enumeration type. + * + * Returns an allocated field type on success, NULL on error. + */ +extern +struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type( + struct bt_ctf_field_type *enumeration); + /* * bt_ctf_field_type_enumeration_add_mapping: add an enumeration mapping. * * Add a mapping to the enumeration. The range's values are inclusive. * * @param enumeration Enumeration type. - * @param string Enumeration mapping name (will be copied). + * @param name Enumeration mapping name (will be copied). * @param range_start Enumeration mapping range start. * @param range_end Enumeration mapping range end. * * Returns 0 on success, a negative value on error. */ extern int bt_ctf_field_type_enumeration_add_mapping( - struct bt_ctf_field_type *enumeration, const char *string, + struct bt_ctf_field_type *enumeration, const char *name, int64_t range_start, int64_t range_end); +/* + * bt_ctf_field_type_enumeration_add_mapping_unsigned: add an enumeration + * mapping. + * + * Add a mapping to the enumeration. The range's values are inclusive. + * + * @param enumeration Enumeration type. + * @param name Enumeration mapping name (will be copied). + * @param range_start Enumeration mapping range start. + * @param range_end Enumeration mapping range end. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_field_type_enumeration_add_mapping_unsigned( + struct bt_ctf_field_type *enumeration, const char *name, + uint64_t range_start, uint64_t range_end); + +/* + * bt_ctf_field_type_enumeration_get_mapping_count: Get the number of mappings + * defined in the enumeration. + * + * @param enumeration Enumeration type. + * + * Returns the mapping count on success, a negative value on error. + */ +extern int64_t bt_ctf_field_type_enumeration_get_mapping_count( + struct bt_ctf_field_type *enumeration); + +/* + * bt_ctf_field_type_enumeration_get_mapping: get an enumeration mapping. + * + * @param enumeration Enumeration type. + * @param index Index of mapping. + * @param name Pointer where the mapping's name will be returned (valid for + * the lifetime of the enumeration). + * @param range_start Pointer where the enumeration mapping's range start will + * be returned. + * @param range_end Pointer where the enumeration mapping's range end will + * be returned. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_field_type_enumeration_get_mapping( + struct bt_ctf_field_type *enumeration, size_t index, + const char **name, int64_t *range_start, int64_t *range_end); + +/* + * bt_ctf_field_type_enumeration_get_mapping_unsigned: get a mapping. + * + * @param enumeration Enumeration type. + * @param index Index of mapping. + * @param name Pointer where the mapping's name will be returned (valid for + * the lifetime of the enumeration). + * @param range_start Pointer where the enumeration mapping's range start will + * be returned. + * @param range_end Pointer where the enumeration mapping's range end will + * be returned. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_field_type_enumeration_get_mapping_unsigned( + struct bt_ctf_field_type *enumeration, size_t index, + const char **name, uint64_t *range_start, + uint64_t *range_end); + +/* + * bt_ctf_field_type_enumeration_get_mapping_index_by_name: get an enumerations' + * mapping index by name. + * + * @param enumeration Enumeration type. + * @param name Mapping name. + * @param index Pointer where the enumeration's mapping index will be returned. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_field_type_enumeration_get_mapping_index_by_name( + struct bt_ctf_field_type *enumeration, const char *name, + size_t *index); + +/* + * bt_ctf_field_type_enumeration_get_mapping_index_by_value: get an + * enumerations' mapping index by value. + * + * @param enumeration Enumeration type. + * @param value Value. + * @param index Pointer where the enumeration's mapping index will be returned. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_field_type_enumeration_get_mapping_index_by_value( + struct bt_ctf_field_type *enumeration, int64_t value, + size_t *index); + +/* + * bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value: get an + * enumerations' mapping index by value. + * + * @param enumeration Enumeration type. + * @param value Value. + * @param index Pointer where the enumeration's mapping index will be returned. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value( + struct bt_ctf_field_type *enumeration, uint64_t value, + size_t *index); + /* * bt_ctf_field_type_floating_point_create: create a floating point field type. * @@ -152,9 +321,20 @@ extern int bt_ctf_field_type_enumeration_add_mapping( */ extern struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void); +/* + * bt_ctf_field_type_floating_point_get_exponent_digits: get exponent digit + * count. + * + * @param floating_point Floating point type. + * + * Returns the exponent digit count on success, a negative value on error. + */ +extern int bt_ctf_field_type_floating_point_get_exponent_digits( + struct bt_ctf_field_type *floating_point); + /* * bt_ctf_field_type_floating_point_set_exponent_digits: set exponent digit - * count. + * count. * * Set the number of exponent digits to use to store the floating point field. * The only values currently supported are FLT_EXP_DIG and DBL_EXP_DIG. @@ -170,9 +350,20 @@ extern int bt_ctf_field_type_floating_point_set_exponent_digits( unsigned int exponent_digits); /* - * bt_ctf_field_type_floating_point_set_mantissa_digits: set mantissa digit + * bt_ctf_field_type_floating_point_get_mantissa_digits: get mantissa digit * count. * + * @param floating_point Floating point type. + * + * Returns the mantissa digit count on success, a negative value on error. + */ +extern int bt_ctf_field_type_floating_point_get_mantissa_digits( + struct bt_ctf_field_type *floating_point); + +/* + * bt_ctf_field_type_floating_point_set_mantissa_digits: set mantissa digit + * count. + * * Set the number of mantissa digits to use to store the floating point field. * The only values currently supported are FLT_MANT_DIG and DBL_MANT_DIG. * @@ -213,6 +404,47 @@ extern int bt_ctf_field_type_structure_add_field( struct bt_ctf_field_type *field_type, const char *field_name); +/* + * bt_ctf_field_type_structure_get_field_count: Get the number of fields defined + * in the structure. + * + * @param structure Structure type. + * + * Returns the field count on success, a negative value on error. + */ +extern int64_t bt_ctf_field_type_structure_get_field_count( + struct bt_ctf_field_type *structure); + +/* + * bt_ctf_field_type_structure_get_field: get a structure's field type and name. + * + * @param structure Structure type. + * @param field_type Pointer to a const char* where the field's name will + * be returned. + * @param field_type Pointer to a bt_ctf_field_type* where the field's type will + * be returned. + * @param index Index of field. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_field_type_structure_get_field( + struct bt_ctf_field_type *structure, + const char **field_name, struct bt_ctf_field_type **field_type, + size_t index); + +/* + * bt_ctf_field_type_structure_get_field_type_by_name: get a structure field's + * type by name. + * + * @param structure Structure type. + * @param field_name Name of the structure's field. + * + * Returns a field type instance on success, NULL on error. + */ +extern +struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name( + struct bt_ctf_field_type *structure, const char *field_name); + /* * bt_ctf_field_type_variant_create: create a variant field type. * @@ -226,13 +458,32 @@ extern int bt_ctf_field_type_structure_add_field( * Returns an allocated field type on success, NULL on error. */ extern struct bt_ctf_field_type *bt_ctf_field_type_variant_create( - struct bt_ctf_field_type *enum_tag, - const char *tag_name); + struct bt_ctf_field_type *enum_tag, const char *tag_name); + +/* + * bt_ctf_field_type_variant_get_tag_type: get a variant's tag type. + * + * @param variant Variant type. + * + * Returns a field type instance on success, NULL on error. + */ +extern struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type( + struct bt_ctf_field_type *variant); + +/* + * bt_ctf_field_type_variant_get_tag_name: get a variant's tag name. + * + * @param variant Variant type. + * + * Returns the tag field's name, NULL on error. + */ +extern const char *bt_ctf_field_type_variant_get_tag_name( + struct bt_ctf_field_type *variant); /* * bt_ctf_field_type_variant_add_field: add a field to a variant. * - * Add a field of type "field_type" to the variant.The variant will share + * Add a field of type "field_type" to the variant. The variant will share * field_type's ownership by increasing its reference count. The "field_name" * will be copied. field_name must match a mapping in the tag/selector * enumeration. @@ -248,6 +499,57 @@ extern int bt_ctf_field_type_variant_add_field( struct bt_ctf_field_type *field_type, const char *field_name); +/* + * bt_ctf_field_type_variant_get_field_type_by_name: get variant field's type. + * + * @param structure Variant type. + * @param field_name Name of the variant's field. + * + * Returns a field type instance on success, NULL on error. + */ +extern +struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name( + struct bt_ctf_field_type *variant, const char *field_name); + +/* + * bt_ctf_field_type_variant_get_field_type_from_tag: get variant field's type. + * + * @param variant Variant type. + * @param tag Type tag (enum). + * + * Returns a field type instance on success, NULL on error. + */ +extern +struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag( + struct bt_ctf_field_type *variant, struct bt_ctf_field *tag); + +/* + * bt_ctf_field_type_variant_get_field_count: Get the number of fields defined + * in the variant. + * + * @param variant Variant type. + * + * Returns the field count on success, a negative value on error. + */ +extern int64_t bt_ctf_field_type_variant_get_field_count( + struct bt_ctf_field_type *variant); + +/* + * bt_ctf_field_type_variant_get_field: get a variant's field name and type. + * + * @param variant Variant type. + * @param field_type Pointer to a const char* where the field's name will + * be returned. + * @param field_type Pointer to a bt_ctf_field_type* where the field's type will + * be returned. + * @param index Index of field. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_field_type_variant_get_field( + struct bt_ctf_field_type *variant, const char **field_name, + struct bt_ctf_field_type **field_type, size_t index); + /* * bt_ctf_field_type_array_create: create an array field type. * @@ -260,8 +562,27 @@ extern int bt_ctf_field_type_variant_add_field( * Returns an allocated field type on success, NULL on error. */ extern struct bt_ctf_field_type *bt_ctf_field_type_array_create( - struct bt_ctf_field_type *element_type, - unsigned int length); + struct bt_ctf_field_type *element_type, unsigned int length); + +/* + * bt_ctf_field_type_array_get_element_type: get an array's element type. + * + * @param array Array type. + * + * Returns a field type instance on success, NULL on error. + */ +extern struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type( + struct bt_ctf_field_type *array); + +/* + * bt_ctf_field_type_array_get_length: get an array's length. + * + * @param array Array type. + * + * Returns the array's length on success, a negative value on error. + */ +extern int64_t bt_ctf_field_type_array_get_length( + struct bt_ctf_field_type *array); /* * bt_ctf_field_type_sequence_create: create a sequence field type. @@ -280,6 +601,26 @@ extern struct bt_ctf_field_type *bt_ctf_field_type_sequence_create( struct bt_ctf_field_type *element_type, const char *length_field_name); +/* + * bt_ctf_field_type_sequence_get_element_type: get a sequence's element type. + * + * @param sequence Sequence type. + * + * Returns a field type instance on success, NULL on error. + */ +extern struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type( + struct bt_ctf_field_type *sequence); + +/* + * bt_ctf_field_type_sequence_get_length_field_name: get length field name. + * + * @param sequence Sequence type. + * + * Returns the sequence's length field on success, NULL on error. + */ +extern const char *bt_ctf_field_type_sequence_get_length_field_name( + struct bt_ctf_field_type *sequence); + /* * bt_ctf_field_type_string_create: create a string field type. * @@ -290,21 +631,44 @@ extern struct bt_ctf_field_type *bt_ctf_field_type_sequence_create( */ extern struct bt_ctf_field_type *bt_ctf_field_type_string_create(void); +/* + * bt_ctf_field_type_string_get_encoding: get a string type's encoding. + * + * Get the string type's encoding. + * + * @param string_type String type. + * + * Returns the string's encoding on success, a CTF_STRING_UNKNOWN on error. + */ +extern enum ctf_string_encoding bt_ctf_field_type_string_get_encoding( + struct bt_ctf_field_type *string_type); + /* * bt_ctf_field_type_string_set_encoding: set a string type's encoding. * * Set the string type's encoding. * - * @param string String type. + * @param string_type String type. * @param encoding String field encoding, default CTF_STRING_ENCODING_ASCII. * Valid values are CTF_STRING_ENCODING_ASCII and CTF_STRING_ENCODING_UTF8. * * Returns 0 on success, a negative value on error. */ extern int bt_ctf_field_type_string_set_encoding( - struct bt_ctf_field_type *string, + struct bt_ctf_field_type *string_type, enum ctf_string_encoding encoding); +/* + * bt_ctf_field_type_get_alignment: get a field type's alignment. + * + * Get the field type's alignment. + * + * @param type Field type. + * + * Returns the field type's alignment on success, a negative value on error. + */ +extern int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type); + /* * bt_ctf_field_type_set_alignment: set a field type's alignment. * @@ -320,6 +684,16 @@ extern int bt_ctf_field_type_string_set_encoding( extern int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type, unsigned int alignment); +/* + * bt_ctf_field_type_get_byte_order: get a field type's byte order. + * + * @param type Field type. + * + * Returns the field type's byte order on success, a negative value on error. + */ +extern enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order( + struct bt_ctf_field_type *type); + /* * bt_ctf_field_type_set_byte_order: set a field type's byte order. * @@ -334,6 +708,16 @@ extern int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type, extern int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type, enum bt_ctf_byte_order byte_order); +/* + * bt_ctf_field_type_get_type_id: get a field type's ctf_type_id. + * + * @param type Field type. + * + * Returns the field type's ctf_type_id, CTF_TYPE_UNKNOWN on error. + */ +extern enum ctf_type_id bt_ctf_field_type_get_type_id( + struct bt_ctf_field_type *type); + /* * bt_ctf_field_type_get and bt_ctf_field_type_put: increment and decrement * the field type's reference count. -- 2.34.1