X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=lib%2Fctf-ir%2Ffield-types.c;h=11764121f76f6274996148d20ad4284f59be005a;hp=deb9c0ed296636d5e5403533a42bc920a83d404e;hb=312c056ae3d374b253fa0cfe5ed576c0b0e5e569;hpb=3dca22768a95bef664012559aa9ac977091de6ac diff --git a/lib/ctf-ir/field-types.c b/lib/ctf-ir/field-types.c index deb9c0ed..11764121 100644 --- a/lib/ctf-ir/field-types.c +++ b/lib/ctf-ir/field-types.c @@ -157,21 +157,6 @@ void destroy_enumeration_mapping(struct enumeration_mapping *mapping) g_free(mapping); } -static -void destroy_structure_field_common(struct structure_field_common *field) -{ - if (!field) { - return; - } - - BT_LOGD("Destroying structure/variant field type's field object: " - "addr=%p, field-ft-addr=%p, field-name=\"%s\"", - field, field->type, g_quark_to_string(field->name)); - BT_LOGD_STR("Putting field type."); - bt_put(field->type); - g_free(field); -} - BT_HIDDEN void bt_field_type_common_initialize(struct bt_field_type_common *ft, bool init_bo, bt_object_release_func release_func, @@ -282,8 +267,8 @@ void bt_field_type_common_structure_initialize( BT_LOGD_STR("Initializing common structure field type object."); ft->id = BT_FIELD_TYPE_ID_STRUCT; - struct_ft->fields = g_ptr_array_new_with_free_func( - (GDestroyNotify) destroy_structure_field_common); + struct_ft->fields = g_array_new(FALSE, TRUE, + sizeof(struct bt_field_type_common_structure_field)); struct_ft->field_name_to_index = g_hash_table_new(NULL, NULL); bt_field_type_common_initialize(ft, true, release_func, methods); BT_LOGD("Initialized common structure field type object: addr=%p", ft); @@ -349,9 +334,9 @@ void bt_field_type_common_variant_initialize( tag_ft, tag_name); ft->id = BT_FIELD_TYPE_ID_VARIANT; var_ft->tag_name = g_string_new(tag_name); - var_ft->field_name_to_index = g_hash_table_new(NULL, NULL); - var_ft->fields = g_ptr_array_new_with_free_func( - (GDestroyNotify) destroy_structure_field_common); + var_ft->choice_name_to_index = g_hash_table_new(NULL, NULL); + var_ft->choices = g_array_new(FALSE, TRUE, + sizeof(struct bt_field_type_common_variant_choice)); if (tag_ft) { var_ft->tag_ft = bt_get(tag_ft); @@ -422,19 +407,47 @@ void bt_field_type_common_string_destroy(struct bt_object *obj) g_free(ft); } +static +void bt_field_type_common_structure_field_finalize( + struct bt_field_type_common_structure_field *field) +{ + if (!field) { + return; + } + + BT_LOGD("Finalizing structure field type's field: " + "addr=%p, field-ft-addr=%p, field-name=\"%s\"", + field, field->type, g_quark_to_string(field->name)); + BT_LOGD_STR("Putting field type."); + bt_put(field->type); +} BT_HIDDEN void bt_field_type_common_structure_destroy_recursive(struct bt_object *obj) { struct bt_field_type_common_structure *ft = (void *) obj; + uint64_t i; if (!ft) { return; } BT_LOGD("Destroying structure field type object: addr=%p", ft); - g_ptr_array_free(ft->fields, TRUE); - g_hash_table_destroy(ft->field_name_to_index); + + if (ft->fields) { + for (i = 0; i < ft->fields->len; i++) { + bt_field_type_common_structure_field_finalize( + BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX( + ft, i)); + } + + g_array_free(ft->fields, TRUE); + } + + if (ft->field_name_to_index) { + g_hash_table_destroy(ft->field_name_to_index); + } + g_free(ft); } @@ -471,19 +484,55 @@ void bt_field_type_common_sequence_destroy_recursive(struct bt_object *obj) g_free(ft); } +static +void bt_field_type_common_variant_choice_finalize( + struct bt_field_type_common_variant_choice *choice) +{ + if (!choice) { + return; + } + + BT_LOGD("Finalizing variant field type's choice: " + "addr=%p, field-ft-addr=%p, field-name=\"%s\"", + choice, choice->type, g_quark_to_string(choice->name)); + BT_LOGD_STR("Putting field type."); + bt_put(choice->type); + + if (choice->ranges) { + g_array_free(choice->ranges, TRUE); + } +} + BT_HIDDEN void bt_field_type_common_variant_destroy_recursive(struct bt_object *obj) { struct bt_field_type_common_variant *ft = (void *) obj; + uint64_t i; if (!ft) { return; } BT_LOGD("Destroying variant field type object: addr=%p", ft); - g_ptr_array_free(ft->fields, TRUE); - g_hash_table_destroy(ft->field_name_to_index); - g_string_free(ft->tag_name, TRUE); + + if (ft->choices) { + for (i = 0; i < ft->choices->len; i++) { + bt_field_type_common_variant_choice_finalize( + BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX( + ft, i)); + } + + g_array_free(ft->choices, TRUE); + } + + if (ft->choice_name_to_index) { + g_hash_table_destroy(ft->choice_name_to_index); + } + + if (ft->tag_name) { + g_string_free(ft->tag_name, TRUE); + } + BT_LOGD_STR("Putting tag field type."); bt_put(ft->tag_ft); BT_LOGD_STR("Putting tag field path."); @@ -582,13 +631,15 @@ gint compare_enumeration_mappings_unsigned(struct enumeration_mapping **a, } static -int add_structure_field(GPtrArray *fields, +int add_structure_variant_member(GArray *members, GHashTable *field_name_to_index, - struct bt_field_type_common *field_type, const char *field_name) + struct bt_field_type_common *field_type, const char *field_name, + bool is_variant) { int ret = 0; GQuark name_quark = g_quark_from_string(field_name); - struct structure_field_common *field; + struct bt_field_type_common **member_ft; + GQuark *member_name; /* Make sure structure does not contain a field of the same name */ if (g_hash_table_lookup_extended(field_name_to_index, @@ -599,21 +650,38 @@ int add_structure_field(GPtrArray *fields, goto end; } - field = g_new0(struct structure_field_common, 1); - if (!field) { - BT_LOGE_STR("Failed to allocate one structure/variant field type field."); - ret = -1; - goto end; + g_array_set_size(members, members->len + 1); + + if (is_variant) { + struct bt_field_type_common_variant_choice *choice = + &g_array_index(members, + struct bt_field_type_common_variant_choice, + members->len - 1); + + member_ft = &choice->type; + member_name = &choice->name; + BT_ASSERT(!choice->ranges); + choice->ranges = g_array_new(FALSE, TRUE, + sizeof(struct bt_field_type_common_variant_choice_range)); + BT_ASSERT(choice->ranges); + } else { + struct bt_field_type_common_structure_field *field = + &g_array_index(members, + struct bt_field_type_common_structure_field, + members->len - 1); + + member_ft = &field->type; + member_name = &field->name; } - bt_get(field_type); - field->name = name_quark; - field->type = field_type; + *member_name = name_quark; + *member_ft = bt_get(field_type); g_hash_table_insert(field_name_to_index, - GUINT_TO_POINTER(name_quark), GUINT_TO_POINTER(fields->len)); - g_ptr_array_add(fields, field); - BT_LOGV("Added structure/variant field type field: field-ft-addr=%p, " - "field-name=\"%s\"", field_type, field_name); + GUINT_TO_POINTER(name_quark), + GUINT_TO_POINTER(members->len - 1)); + BT_LOGV("Added structure/variant field type member: member-ft-addr=%p, " + "member-name=\"%s\"", field_type, field_name); + end: return ret; } @@ -796,7 +864,7 @@ int bt_field_type_common_structure_validate_recursive( for (i = 0; i < field_count; ++i) { const char *field_name; - ret = bt_field_type_common_structure_get_field_by_index(ft, + ret = bt_field_type_common_structure_borrow_field_by_index(ft, &field_name, &child_ft, i); BT_ASSERT(ret == 0); ret = bt_field_type_common_validate(child_ft); @@ -808,12 +876,9 @@ int bt_field_type_common_structure_validate_recursive( ft, child_ft, field_name, i); goto end; } - - BT_PUT(child_ft); } end: - BT_PUT(child_ft); return ret; } @@ -888,7 +953,7 @@ int bt_field_type_common_variant_validate_recursive( for (i = 0; i < field_count; ++i) { const char *field_name; - ret = bt_field_type_common_variant_get_field_by_index(ft, + ret = bt_field_type_common_variant_borrow_field_by_index(ft, &field_name, &child_ft, i); BT_ASSERT(ret == 0); ret = bt_field_type_common_validate(child_ft); @@ -902,12 +967,9 @@ int bt_field_type_common_variant_validate_recursive( field_name, i); goto end; } - - BT_PUT(child_ft); } end: - BT_PUT(child_ft); return ret; } @@ -1244,7 +1306,7 @@ int bt_field_type_integer_set_encoding(struct bt_field_type *ft, } BT_HIDDEN -struct bt_clock_class *bt_field_type_common_integer_get_mapped_clock_class( +struct bt_clock_class *bt_field_type_common_integer_borrow_mapped_clock_class( struct bt_field_type_common *ft) { struct bt_field_type_common_integer *int_ft = BT_FROM_COMMON(ft); @@ -1252,13 +1314,14 @@ struct bt_clock_class *bt_field_type_common_integer_get_mapped_clock_class( BT_ASSERT_PRE_NON_NULL(ft, "Field type"); BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft, BT_FIELD_TYPE_ID_INTEGER, "Field type"); - return bt_get(int_ft->mapped_clock_class); + return int_ft->mapped_clock_class; } -struct bt_clock_class *bt_field_type_integer_get_mapped_clock_class( +struct bt_clock_class *bt_field_type_integer_borrow_mapped_clock_class( struct bt_field_type *ft) { - return bt_field_type_common_integer_get_mapped_clock_class((void *) ft); + return bt_field_type_common_integer_borrow_mapped_clock_class( + (void *) ft); } BT_HIDDEN @@ -1711,20 +1774,21 @@ end: } BT_HIDDEN -struct bt_field_type_common *bt_field_type_common_enumeration_get_container_field_type( +struct bt_field_type_common * +bt_field_type_common_enumeration_borrow_container_field_type( struct bt_field_type_common *ft) { struct bt_field_type_common_enumeration *enum_ft = BT_FROM_COMMON(ft); BT_ASSERT_PRE_NON_NULL(ft, "Field type"); BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft, BT_FIELD_TYPE_ID_ENUM, "Field type"); - return bt_get(enum_ft->container_ft); + return BT_TO_COMMON(enum_ft->container_ft); } -struct bt_field_type *bt_field_type_enumeration_get_container_field_type( +struct bt_field_type *bt_field_type_enumeration_borrow_container_field_type( struct bt_field_type *ft) { - return (void *) bt_field_type_common_enumeration_get_container_field_type( + return (void *) bt_field_type_common_enumeration_borrow_container_field_type( (void *) ft); } @@ -2153,8 +2217,8 @@ int bt_field_type_common_structure_replace_field( name_quark = g_quark_from_string(field_name); for (i = 0; i < struct_ft->fields->len; i++) { - struct structure_field_common *field = g_ptr_array_index( - struct_ft->fields, i); + struct bt_field_type_common_structure_field *field = + BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(ft, i); if (field->name == name_quark) { bt_put(field->type); @@ -2211,8 +2275,9 @@ int bt_field_type_common_structure_add_field(struct bt_field_type_common *ft, goto end; } - if (add_structure_field(struct_ft->fields, - struct_ft->field_name_to_index, field_type, field_name)) { + if (add_structure_variant_member(struct_ft->fields, + struct_ft->field_name_to_index, field_type, field_name, + false)) { BT_LOGW("Cannot add field to structure field type: " "struct-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"", ft, field_type, field_name); @@ -2254,13 +2319,13 @@ int64_t bt_field_type_structure_get_field_count(struct bt_field_type *ft) } BT_HIDDEN -int bt_field_type_common_structure_get_field_by_index( +int bt_field_type_common_structure_borrow_field_by_index( struct bt_field_type_common *ft, const char **field_name, struct bt_field_type_common **field_type, uint64_t index) { struct bt_field_type_common_structure *struct_ft = BT_FROM_COMMON(ft); - struct structure_field_common *field; + struct bt_field_type_common_structure_field *field; BT_ASSERT_PRE_NON_NULL(ft, "Field type"); BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCT, @@ -2269,11 +2334,10 @@ int bt_field_type_common_structure_get_field_by_index( "Index is out of bounds: index=%" PRIu64 ", " "count=%u, %![ft-]+_F", index, struct_ft->fields->len, ft); - field = g_ptr_array_index(struct_ft->fields, index); + field = BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(struct_ft, index); if (field_type) { *field_type = field->type; - bt_get(field->type); } if (field_name) { @@ -2284,22 +2348,23 @@ int bt_field_type_common_structure_get_field_by_index( return 0; } -int bt_field_type_structure_get_field_by_index( +int bt_field_type_structure_borrow_field_by_index( struct bt_field_type *ft, const char **field_name, struct bt_field_type **field_type, uint64_t index) { - return bt_field_type_common_structure_get_field_by_index( + return bt_field_type_common_structure_borrow_field_by_index( (void *) ft, field_name, (void *) field_type, index); } BT_HIDDEN -struct bt_field_type_common *bt_field_type_common_structure_get_field_type_by_name( +struct bt_field_type_common * +bt_field_type_common_structure_borrow_field_type_by_name( struct bt_field_type_common *ft, const char *name) { size_t index; GQuark name_quark; - struct structure_field_common *field; + struct bt_field_type_common_structure_field *field; struct bt_field_type_common_structure *struct_ft = BT_FROM_COMMON(ft); struct bt_field_type_common *field_type = NULL; @@ -2323,18 +2388,17 @@ struct bt_field_type_common *bt_field_type_common_structure_get_field_type_by_na goto end; } - field = struct_ft->fields->pdata[index]; + field = BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(ft, index); field_type = field->type; - bt_get(field_type); end: return field_type; } -struct bt_field_type *bt_field_type_structure_get_field_type_by_name( +struct bt_field_type *bt_field_type_structure_borrow_field_type_by_name( struct bt_field_type *ft, const char *name) { - return (void *) bt_field_type_common_structure_get_field_type_by_name( + return (void *) bt_field_type_common_structure_borrow_field_type_by_name( (void *) ft, name); } @@ -2377,7 +2441,8 @@ end: } BT_HIDDEN -struct bt_field_type_common *bt_field_type_common_variant_get_tag_field_type( +struct bt_field_type_common * +bt_field_type_common_variant_borrow_tag_field_type( struct bt_field_type_common *ft) { struct bt_field_type_common_variant *var_ft = BT_FROM_COMMON(ft); @@ -2393,16 +2458,16 @@ struct bt_field_type_common *bt_field_type_common_variant_get_tag_field_type( goto end; } - tag_ft = bt_get(var_ft->tag_ft); + tag_ft = BT_TO_COMMON(var_ft->tag_ft); end: return tag_ft; } -struct bt_field_type *bt_field_type_variant_get_tag_field_type( +struct bt_field_type *bt_field_type_variant_borrow_tag_field_type( struct bt_field_type *ft) { - return (void *) bt_field_type_common_variant_get_tag_field_type( + return (void *) bt_field_type_common_variant_borrow_tag_field_type( (void *) ft); } @@ -2553,8 +2618,9 @@ int bt_field_type_common_variant_add_field(struct bt_field_type_common *ft, } } - if (add_structure_field(var_ft->fields, var_ft->field_name_to_index, - field_type, field_name)) { + if (add_structure_variant_member(var_ft->choices, + var_ft->choice_name_to_index, field_type, + field_name, true)) { BT_LOGW("Cannot add field to variant field type: " "variant-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"", ft, field_type, field_name); @@ -2579,13 +2645,14 @@ int bt_field_type_variant_add_field(struct bt_field_type *ft, } BT_HIDDEN -struct bt_field_type_common *bt_field_type_common_variant_get_field_type_by_name( +struct bt_field_type_common * +bt_field_type_common_variant_borrow_field_type_by_name( struct bt_field_type_common *ft, const char *field_name) { size_t index; GQuark name_quark; - struct structure_field_common *field; + struct bt_field_type_common_variant_choice *choice; struct bt_field_type_common_variant *var_ft = BT_FROM_COMMON(ft); struct bt_field_type_common *field_type = NULL; @@ -2601,7 +2668,7 @@ struct bt_field_type_common *bt_field_type_common_variant_get_field_type_by_name goto end; } - if (!g_hash_table_lookup_extended(var_ft->field_name_to_index, + if (!g_hash_table_lookup_extended(var_ft->choice_name_to_index, GUINT_TO_POINTER(name_quark), NULL, (gpointer *) &index)) { BT_LOGV("No such variant field type field name: " "ft-addr=%p, field-name=\"%s\"", @@ -2609,71 +2676,21 @@ struct bt_field_type_common *bt_field_type_common_variant_get_field_type_by_name goto end; } - field = g_ptr_array_index(var_ft->fields, index); - field_type = field->type; - bt_get(field_type); + choice = BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft, index); + field_type = choice->type; end: return field_type; } -struct bt_field_type *bt_field_type_variant_get_field_type_by_name( +struct bt_field_type *bt_field_type_variant_borrow_field_type_by_name( struct bt_field_type *ft, const char *field_name) { - return (void *) bt_field_type_common_variant_get_field_type_by_name( + return (void *) bt_field_type_common_variant_borrow_field_type_by_name( (void *) ft, field_name); } -BT_HIDDEN -struct bt_field_type_common *bt_field_type_common_variant_get_field_type_from_tag( - struct bt_field_type_common *ft, - struct bt_field_common *tag_field, - bt_field_common_create_func field_create_func) -{ - int ret; - const char *enum_value; - struct bt_field_type_common *field_type = NULL; - struct bt_field_type_enumeration_mapping_iterator *iter = NULL; - - BT_ASSERT_PRE_NON_NULL(ft, "Variant field type"); - BT_ASSERT_PRE_NON_NULL(tag_field, "Tag field"); - BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, - "Field type"); - iter = bt_field_common_enumeration_get_mappings(tag_field, - field_create_func); - ret = bt_field_type_enumeration_mapping_iterator_next(iter); - if (!iter || ret) { - BT_LOGW("Cannot get enumeration field type mapping iterator from enumeration field: " - "enum-field-addr=%p", tag_field); - goto end; - } - - ret = bt_field_type_enumeration_mapping_iterator_signed_get(iter, - &enum_value, NULL, NULL); - if (ret) { - BT_LOGW("Cannot get enumeration field type mapping iterator's current mapping: " - "iter-addr=%p", iter); - goto end; - } - - field_type = bt_field_type_common_variant_get_field_type_by_name( - ft, enum_value); - -end: - bt_put(iter); - return field_type; -} - -struct bt_field_type *bt_field_type_variant_get_field_type_from_tag( - struct bt_field_type *ft, - struct bt_field *tag_field) -{ - return (void *) bt_field_type_common_variant_get_field_type_from_tag( - (void *) ft, (void *) tag_field, - (bt_field_common_create_func) bt_field_create); -} - BT_HIDDEN int64_t bt_field_type_common_variant_get_field_count( struct bt_field_type_common *ft) @@ -2683,7 +2700,7 @@ int64_t bt_field_type_common_variant_get_field_count( BT_ASSERT_PRE_NON_NULL(ft, "Variant field type"); BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type"); - return (int64_t) var_ft->fields->len; + return (int64_t) var_ft->choices->len; } int64_t bt_field_type_variant_get_field_count(struct bt_field_type *ft) @@ -2692,44 +2709,100 @@ int64_t bt_field_type_variant_get_field_count(struct bt_field_type *ft) } BT_HIDDEN -int bt_field_type_common_variant_get_field_by_index( +int bt_field_type_common_variant_borrow_field_by_index( struct bt_field_type_common *ft, const char **field_name, struct bt_field_type_common **field_type, uint64_t index) { struct bt_field_type_common_variant *var_ft = BT_FROM_COMMON(ft); - struct structure_field_common *field; + struct bt_field_type_common_variant_choice *choice; BT_ASSERT_PRE_NON_NULL(ft, "Field type"); BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type"); - BT_ASSERT_PRE(index < var_ft->fields->len, + BT_ASSERT_PRE(index < var_ft->choices->len, "Index is out of bounds: index=%" PRIu64 ", " "count=%u, %![ft-]+_F", - index, var_ft->fields->len, ft); - field = g_ptr_array_index(var_ft->fields, index); + index, var_ft->choices->len, ft); + choice = BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft, index); if (field_type) { - *field_type = field->type; - bt_get(field->type); + *field_type = choice->type; } if (field_name) { - *field_name = g_quark_to_string(field->name); + *field_name = g_quark_to_string(choice->name); BT_ASSERT(*field_name); } return 0; } -int bt_field_type_variant_get_field_by_index(struct bt_field_type *ft, +int bt_field_type_variant_borrow_field_by_index(struct bt_field_type *ft, const char **field_name, struct bt_field_type **field_type, uint64_t index) { - return bt_field_type_common_variant_get_field_by_index((void *) ft, + return bt_field_type_common_variant_borrow_field_by_index((void *) ft, field_name, (void *) field_type, index); } +BT_HIDDEN +int64_t bt_field_type_common_variant_find_choice_index( + struct bt_field_type_common *ft, uint64_t uval, + bool is_signed) +{ + int64_t ret; + uint64_t i; + struct bt_field_type_common_variant *var_ft = BT_FROM_COMMON(ft); + + BT_ASSERT(ft); + BT_ASSERT(ft->id == BT_FIELD_TYPE_ID_VARIANT); + + if (bt_field_type_common_variant_update_choices(ft)) { + ret = INT64_C(-1); + goto end; + } + + for (i = 0; i < var_ft->choices->len; i++) { + uint64_t range_i; + struct bt_field_type_common_variant_choice *choice = + BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX( + var_ft, i); + + for (range_i = 0; range_i < choice->ranges->len; range_i++) { + struct bt_field_type_common_variant_choice_range *range = + &g_array_index( + choice->ranges, + struct bt_field_type_common_variant_choice_range, + range_i); + + if (is_signed) { + int64_t tag_ival = (int64_t) uval; + + if (tag_ival >= range->lower.i && + tag_ival <= range->upper.i) { + goto found; + } + } else { + if (uval >= range->lower.u && + uval <= range->upper.u) { + goto found; + } + } + } + } + + /* Range not found */ + ret = INT64_C(-1); + goto end; + +found: + ret = (int64_t) i; + +end: + return ret; +} + struct bt_field_type *bt_field_type_array_create( struct bt_field_type *element_ft, unsigned int length) { @@ -2771,7 +2844,8 @@ end: } BT_HIDDEN -struct bt_field_type_common *bt_field_type_common_array_get_element_field_type( +struct bt_field_type_common * +bt_field_type_common_array_borrow_element_field_type( struct bt_field_type_common *ft) { struct bt_field_type_common_array *array_ft = BT_FROM_COMMON(ft); @@ -2780,13 +2854,13 @@ struct bt_field_type_common *bt_field_type_common_array_get_element_field_type( BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft, BT_FIELD_TYPE_ID_ARRAY, "Field type"); BT_ASSERT(array_ft && array_ft->element_ft); - return bt_get(array_ft->element_ft); + return array_ft->element_ft; } -struct bt_field_type *bt_field_type_array_get_element_field_type( +struct bt_field_type *bt_field_type_array_borrow_element_field_type( struct bt_field_type *ft) { - return (void *) bt_field_type_common_array_get_element_field_type( + return (void *) bt_field_type_common_array_borrow_element_field_type( (void *) ft); } @@ -2889,7 +2963,7 @@ end: } BT_HIDDEN -struct bt_field_type_common *bt_field_type_common_sequence_get_element_field_type( +struct bt_field_type_common *bt_field_type_common_sequence_borrow_element_field_type( struct bt_field_type_common *ft) { struct bt_field_type_common_sequence *seq_ft = BT_FROM_COMMON(ft); @@ -2897,13 +2971,13 @@ struct bt_field_type_common *bt_field_type_common_sequence_get_element_field_typ BT_ASSERT_PRE_NON_NULL(ft, "Field type"); BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft, BT_FIELD_TYPE_ID_SEQUENCE, "Field type"); - return bt_get(seq_ft->element_ft); + return seq_ft->element_ft; } -struct bt_field_type *bt_field_type_sequence_get_element_field_type( +struct bt_field_type *bt_field_type_sequence_borrow_element_field_type( struct bt_field_type *ft) { - return (void *) bt_field_type_common_sequence_get_element_field_type( + return (void *) bt_field_type_common_sequence_borrow_element_field_type( (void *) ft); } @@ -3065,21 +3139,19 @@ int bt_field_type_common_get_alignment(struct bt_field_type_common *ft) case BT_FIELD_TYPE_ID_SEQUENCE: { struct bt_field_type_common *element_ft = - bt_field_type_common_sequence_get_element_field_type(ft); + bt_field_type_common_sequence_borrow_element_field_type(ft); BT_ASSERT(element_ft); ret = bt_field_type_common_get_alignment(element_ft); - bt_put(element_ft); break; } case BT_FIELD_TYPE_ID_ARRAY: { struct bt_field_type_common *element_ft = - bt_field_type_common_array_get_element_field_type(ft); + bt_field_type_common_array_borrow_element_field_type(ft); BT_ASSERT(element_ft); ret = bt_field_type_common_get_alignment(element_ft); - bt_put(element_ft); break; } case BT_FIELD_TYPE_ID_STRUCT: @@ -3094,13 +3166,12 @@ int bt_field_type_common_get_alignment(struct bt_field_type_common *ft) struct bt_field_type_common *field = NULL; int field_alignment; - ret = bt_field_type_common_structure_get_field_by_index( + ret = bt_field_type_common_structure_borrow_field_by_index( ft, NULL, &field, i); BT_ASSERT(ret == 0); BT_ASSERT(field); field_alignment = bt_field_type_common_get_alignment( field); - bt_put(field); if (field_alignment < 0) { ret = field_alignment; goto end; @@ -3377,14 +3448,15 @@ void _bt_field_type_freeze(struct bt_field_type *ft) } BT_HIDDEN -struct bt_field_type_common *bt_field_type_common_variant_get_field_type_signed( +struct bt_field_type_common * +bt_field_type_common_variant_borrow_field_type_signed( struct bt_field_type_common_variant *var_ft, int64_t tag_value) { struct bt_field_type_common *field_type = NULL; GQuark field_name_quark; gpointer index; - struct structure_field_common *field_entry; + struct bt_field_type_common_variant_choice *choice; struct range_overlap_query query = { .range_start._signed = tag_value, .range_end._signed = tag_value, @@ -3399,27 +3471,29 @@ struct bt_field_type_common *bt_field_type_common_variant_get_field_type_signed( } field_name_quark = query.mapping_name; - if (!g_hash_table_lookup_extended(var_ft->field_name_to_index, + if (!g_hash_table_lookup_extended(var_ft->choice_name_to_index, GUINT_TO_POINTER(field_name_quark), NULL, &index)) { goto end; } - field_entry = g_ptr_array_index(var_ft->fields, (size_t) index); - field_type = field_entry->type; + choice = BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft, + (size_t) index); + field_type = choice->type; end: return field_type; } BT_HIDDEN -struct bt_field_type_common *bt_field_type_common_variant_get_field_type_unsigned( +struct bt_field_type_common * +bt_field_type_common_variant_borrow_field_type_unsigned( struct bt_field_type_common_variant *var_ft, uint64_t tag_value) { struct bt_field_type_common *field_type = NULL; GQuark field_name_quark; gpointer index; - struct structure_field_common *field_entry; + struct bt_field_type_common_variant_choice *choice; struct range_overlap_query query = { .range_start._unsigned = tag_value, .range_end._unsigned = tag_value, @@ -3434,13 +3508,15 @@ struct bt_field_type_common *bt_field_type_common_variant_get_field_type_unsigne } field_name_quark = query.mapping_name; - if (!g_hash_table_lookup_extended(var_ft->field_name_to_index, + if (!g_hash_table_lookup_extended(var_ft->choice_name_to_index, GUINT_TO_POINTER(field_name_quark), NULL, &index)) { goto end; } - field_entry = g_ptr_array_index(var_ft->fields, (size_t) index); - field_type = field_entry->type; + choice = BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft, + (size_t) index); + field_type = choice->type; + end: return field_type; } @@ -3531,7 +3607,7 @@ int bt_field_type_common_variant_get_field_name_index( goto end; } - if (!g_hash_table_lookup_extended(var_ft->field_name_to_index, + if (!g_hash_table_lookup_extended(var_ft->choice_name_to_index, GUINT_TO_POINTER(name_quark), NULL, (gpointer *) &index)) { BT_LOGV("No such variant field type field name: " @@ -3665,27 +3741,84 @@ void bt_field_type_common_enumeration_freeze_recursive( bt_field_type_common_freeze(BT_TO_COMMON(enum_ft->container_ft)); } -static -void freeze_structure_field(struct structure_field_common *field) -{ - BT_LOGD("Freezing structure/variant field type field: field-addr=%p, " - "field-ft-addr=%p, field-name=\"%s\"", field, - field->type, g_quark_to_string(field->name)); - bt_field_type_common_freeze(field->type); -} - BT_HIDDEN void bt_field_type_common_structure_freeze_recursive( struct bt_field_type_common *ft) { struct bt_field_type_common_structure *struct_ft = BT_FROM_COMMON(ft); + uint64_t i; /* Cache the alignment */ BT_LOGD("Freezing structure field type object: addr=%p", ft); ft->alignment = bt_field_type_common_get_alignment(ft); bt_field_type_common_generic_freeze(ft); - g_ptr_array_foreach(struct_ft->fields, - (GFunc) freeze_structure_field, NULL); + + for (i = 0; i < struct_ft->fields->len; i++) { + struct bt_field_type_common_structure_field *field = + BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(ft, i); + + BT_LOGD("Freezing structure field type field: " + "ft-addr=%p, name=\"%s\"", + field->type, g_quark_to_string(field->name)); + bt_field_type_common_freeze(field->type); + } +} + +BT_HIDDEN +int bt_field_type_common_variant_update_choices(struct bt_field_type_common *ft) +{ + struct bt_field_type_common_variant *var_ft = BT_FROM_COMMON(ft); + uint64_t i; + int ret = 0; + bool is_signed; + + if (ft->frozen && var_ft->choices_up_to_date) { + goto end; + } + + BT_ASSERT(var_ft->tag_ft); + is_signed = !!var_ft->tag_ft->container_ft->is_signed; + + for (i = 0; i < var_ft->choices->len; i++) { + struct bt_field_type_common_variant_choice *choice = + BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft, i); + const char *choice_name = g_quark_to_string(choice->name); + struct bt_field_type_enumeration_mapping_iterator *iter = + bt_field_type_common_enumeration_find_mappings_by_name( + BT_TO_COMMON(var_ft->tag_ft), choice_name); + + if (!iter) { + ret = -1; + goto end; + } + + BT_ASSERT(choice->ranges); + g_array_set_size(choice->ranges, 0); + + while (bt_field_type_enumeration_mapping_iterator_next(iter) == 0) { + struct bt_field_type_common_variant_choice_range range; + + if (is_signed) { + ret = bt_field_type_enumeration_mapping_iterator_signed_get( + iter, NULL, + &range.lower.i, &range.upper.i); + } else { + ret = bt_field_type_enumeration_mapping_iterator_unsigned_get( + iter, NULL, + &range.lower.u, &range.upper.u); + } + + BT_ASSERT(ret == 0); + g_array_append_val(choice->ranges, range); + } + + bt_put(iter); + } + + var_ft->choices_up_to_date = true; + +end: + return ret; } BT_HIDDEN @@ -3693,11 +3826,20 @@ void bt_field_type_common_variant_freeze_recursive( struct bt_field_type_common *ft) { struct bt_field_type_common_variant *var_ft = BT_FROM_COMMON(ft); + uint64_t i; BT_LOGD("Freezing variant field type object: addr=%p", ft); bt_field_type_common_generic_freeze(ft); - g_ptr_array_foreach(var_ft->fields, - (GFunc) freeze_structure_field, NULL); + + for (i = 0; i < var_ft->choices->len; i++) { + struct bt_field_type_common_variant_choice *choice = + BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft, i); + + BT_LOGD("Freezing variant field type member: " + "ft-addr=%p, name=\"%s\"", + choice->type, g_quark_to_string(choice->name)); + bt_field_type_common_freeze(choice->type); + } } BT_HIDDEN @@ -3767,8 +3909,9 @@ void bt_field_type_common_structure_set_byte_order_recursive( struct bt_field_type_common_structure *struct_ft = BT_FROM_COMMON(ft); for (i = 0; i < struct_ft->fields->len; i++) { - struct structure_field_common *field = g_ptr_array_index( - struct_ft->fields, i); + struct bt_field_type_common_structure_field *field = + BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX( + struct_ft, i); struct bt_field_type_common *field_type = field->type; bt_field_type_common_set_byte_order(field_type, byte_order); @@ -3783,10 +3926,11 @@ void bt_field_type_common_variant_set_byte_order_recursive( int i; struct bt_field_type_common_variant *var_ft = BT_FROM_COMMON(ft); - for (i = 0; i < var_ft->fields->len; i++) { - struct structure_field_common *field = g_ptr_array_index( - var_ft->fields, i); - struct bt_field_type_common *field_type = field->type; + for (i = 0; i < var_ft->choices->len; i++) { + struct bt_field_type_common_variant_choice *choice = + BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX( + var_ft, i); + struct bt_field_type_common *field_type = choice->type; bt_field_type_common_set_byte_order(field_type, byte_order); } @@ -4060,27 +4204,29 @@ end: } static -int compare_structure_fields(struct structure_field_common *field_a, - struct structure_field_common *field_b) +int compare_structure_variant_members( + struct bt_field_type_common *member_a_ft, + struct bt_field_type_common *member_b_ft, + GQuark member_a_name, GQuark member_b_name) { int ret = 1; /* Label */ - if (field_a->name != field_b->name) { + if (member_a_name != member_b_name) { BT_LOGV("Structure/variant field type fields differ: different names: " "field-a-name=%s, field-b-name=%s", - g_quark_to_string(field_a->name), - g_quark_to_string(field_b->name)); + g_quark_to_string(member_a_name), + g_quark_to_string(member_b_name)); goto end; } /* Type */ - ret = bt_field_type_common_compare(field_a->type, field_b->type); + ret = bt_field_type_common_compare(member_a_ft, member_b_ft); if (ret == 1) { BT_LOGV("Structure/variant field type fields differ: different field types: " "field-name=\"%s\", field-a-ft-addr=%p, field-b-ft-addr=%p", - g_quark_to_string(field_a->name), - field_a->type, field_b->type); + g_quark_to_string(member_a_name), + member_a_ft, member_b_ft); } end: @@ -4118,14 +4264,17 @@ int bt_field_type_common_structure_compare_recursive( } for (i = 0; i < struct_ft_a->fields->len; ++i) { - struct structure_field_common *field_a = - g_ptr_array_index(struct_ft_a->fields, i); - struct structure_field_common *field_b = - g_ptr_array_index(struct_ft_b->fields, i); - - ret = compare_structure_fields(field_a, field_b); + struct bt_field_type_common_structure_field *field_a = + BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX( + struct_ft_a, i); + struct bt_field_type_common_structure_field *field_b = + BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX( + struct_ft_b, i); + + ret = compare_structure_variant_members(field_a->type, + field_b->type, field_a->name, field_b->name); if (ret) { - /* compare_structure_fields() logs what differs */ + /* compare_structure_variant_members() logs what differs */ BT_LOGV_STR("Structure field types differ: different fields."); goto end; } @@ -4169,22 +4318,25 @@ int bt_field_type_common_variant_compare_recursive( ret = 1; /* Fields */ - if (var_ft_a->fields->len != var_ft_b->fields->len) { - BT_LOGV("Structure field types differ: different field counts: " + if (var_ft_a->choices->len != var_ft_b->choices->len) { + BT_LOGV("Variant field types differ: different field counts: " "ft-a-field-count=%u, ft-b-field-count=%u", - var_ft_a->fields->len, var_ft_b->fields->len); + var_ft_a->choices->len, var_ft_b->choices->len); goto end; } - for (i = 0; i < var_ft_a->fields->len; ++i) { - struct structure_field_common *field_a = - g_ptr_array_index(var_ft_a->fields, i); - struct structure_field_common *field_b = - g_ptr_array_index(var_ft_b->fields, i); + for (i = 0; i < var_ft_a->choices->len; ++i) { + struct bt_field_type_common_variant_choice *choice_a = + BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX( + var_ft_a, i); + struct bt_field_type_common_variant_choice *choice_b = + BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX( + var_ft_b, i); - ret = compare_structure_fields(field_a, field_b); + ret = compare_structure_variant_members(choice_a->type, + choice_b->type, choice_a->name, choice_b->name); if (ret) { - /* compare_structure_fields() logs what differs */ + /* compare_structure_variant_members() logs what differs */ BT_LOGV_STR("Variant field types differ: different fields."); goto end; } @@ -4351,7 +4503,7 @@ int64_t bt_field_type_common_get_field_count(struct bt_field_type_common *ft) } BT_HIDDEN -struct bt_field_type_common *bt_field_type_common_get_field_at_index( +struct bt_field_type_common *bt_field_type_common_borrow_field_at_index( struct bt_field_type_common *ft, int index) { struct bt_field_type_common *field_type = NULL; @@ -4359,7 +4511,7 @@ struct bt_field_type_common *bt_field_type_common_get_field_at_index( switch (ft->id) { case BT_FIELD_TYPE_ID_STRUCT: { - int ret = bt_field_type_common_structure_get_field_by_index( + int ret = bt_field_type_common_structure_borrow_field_by_index( ft, NULL, &field_type, index); if (ret) { field_type = NULL; @@ -4369,7 +4521,7 @@ struct bt_field_type_common *bt_field_type_common_get_field_at_index( } case BT_FIELD_TYPE_ID_VARIANT: { - int ret = bt_field_type_common_variant_get_field_by_index( + int ret = bt_field_type_common_variant_borrow_field_by_index( ft, NULL, &field_type, index); if (ret) { field_type = NULL; @@ -4378,10 +4530,12 @@ struct bt_field_type_common *bt_field_type_common_get_field_at_index( break; } case BT_FIELD_TYPE_ID_ARRAY: - field_type = bt_field_type_common_array_get_element_field_type(ft); + field_type = + bt_field_type_common_array_borrow_element_field_type(ft); break; case BT_FIELD_TYPE_ID_SEQUENCE: - field_type = bt_field_type_common_sequence_get_element_field_type(ft); + field_type = + bt_field_type_common_sequence_borrow_element_field_type(ft); break; default: break; @@ -4414,7 +4568,7 @@ int bt_field_type_common_get_field_index(struct bt_field_type_common *ft, } BT_HIDDEN -struct bt_field_path *bt_field_type_common_variant_get_tag_field_path( +struct bt_field_path *bt_field_type_common_variant_borrow_tag_field_path( struct bt_field_type_common *ft) { struct bt_field_type_common_variant *var_ft = BT_FROM_COMMON(ft); @@ -4422,17 +4576,17 @@ struct bt_field_path *bt_field_type_common_variant_get_tag_field_path( BT_ASSERT_PRE_NON_NULL(ft, "Field type"); BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type"); - return bt_get(var_ft->tag_field_path); + return var_ft->tag_field_path; } -struct bt_field_path *bt_field_type_variant_get_tag_field_path( +struct bt_field_path *bt_field_type_variant_borrow_tag_field_path( struct bt_field_type *ft) { - return bt_field_type_common_variant_get_tag_field_path((void *) ft); + return bt_field_type_common_variant_borrow_tag_field_path((void *) ft); } BT_HIDDEN -struct bt_field_path *bt_field_type_common_sequence_get_length_field_path( +struct bt_field_path *bt_field_type_common_sequence_borrow_length_field_path( struct bt_field_type_common *ft) { struct bt_field_type_common_sequence *seq_ft = BT_FROM_COMMON(ft); @@ -4440,13 +4594,14 @@ struct bt_field_path *bt_field_type_common_sequence_get_length_field_path( BT_ASSERT_PRE_NON_NULL(ft, "Field type"); BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft, BT_FIELD_TYPE_ID_SEQUENCE, "Field type"); - return bt_get(seq_ft->length_field_path); + return seq_ft->length_field_path; } -struct bt_field_path *bt_field_type_sequence_get_length_field_path( +struct bt_field_path *bt_field_type_sequence_borrow_length_field_path( struct bt_field_type *ft) { - return bt_field_type_common_sequence_get_length_field_path((void *) ft); + return bt_field_type_common_sequence_borrow_length_field_path( + (void *) ft); } BT_HIDDEN @@ -4466,7 +4621,7 @@ int bt_field_type_common_validate_single_clock_class( case BT_FIELD_TYPE_ID_INTEGER: { struct bt_clock_class *mapped_clock_class = - bt_field_type_common_integer_get_mapped_clock_class(ft); + bt_field_type_common_integer_borrow_mapped_clock_class(ft); if (!mapped_clock_class) { goto end; @@ -4474,7 +4629,7 @@ int bt_field_type_common_validate_single_clock_class( if (!*expected_clock_class) { /* Move reference to output parameter */ - *expected_clock_class = mapped_clock_class; + *expected_clock_class = bt_get(mapped_clock_class); mapped_clock_class = NULL; BT_LOGV("Setting expected clock class: " "expected-clock-class-addr=%p", @@ -4497,7 +4652,6 @@ int bt_field_type_common_validate_single_clock_class( } } - bt_put(mapped_clock_class); break; } case BT_FIELD_TYPE_ID_ENUM: @@ -4508,15 +4662,15 @@ int bt_field_type_common_validate_single_clock_class( switch (ft->id) { case BT_FIELD_TYPE_ID_ENUM: - sub_ft = bt_field_type_common_enumeration_get_container_field_type( + sub_ft = bt_field_type_common_enumeration_borrow_container_field_type( ft); break; case BT_FIELD_TYPE_ID_ARRAY: - sub_ft = bt_field_type_common_array_get_element_field_type( + sub_ft = bt_field_type_common_array_borrow_element_field_type( ft); break; case BT_FIELD_TYPE_ID_SEQUENCE: - sub_ft = bt_field_type_common_sequence_get_element_field_type( + sub_ft = bt_field_type_common_sequence_borrow_element_field_type( ft); break; default: @@ -4527,7 +4681,6 @@ int bt_field_type_common_validate_single_clock_class( BT_ASSERT(sub_ft); ret = bt_field_type_common_validate_single_clock_class(sub_ft, expected_clock_class); - bt_put(sub_ft); break; } case BT_FIELD_TYPE_ID_STRUCT: @@ -4540,12 +4693,11 @@ int bt_field_type_common_validate_single_clock_class( const char *name; struct bt_field_type_common *member_type; - ret = bt_field_type_common_structure_get_field_by_index( + ret = bt_field_type_common_structure_borrow_field_by_index( ft, &name, &member_type, i); BT_ASSERT(ret == 0); ret = bt_field_type_common_validate_single_clock_class( member_type, expected_clock_class); - bt_put(member_type); if (ret) { BT_LOGW("Structure field type's field's type " "is not recursively mapped to the " @@ -4567,12 +4719,11 @@ int bt_field_type_common_validate_single_clock_class( const char *name; struct bt_field_type_common *member_type; - ret = bt_field_type_common_variant_get_field_by_index( + ret = bt_field_type_common_variant_borrow_field_by_index( ft, &name, &member_type, i); BT_ASSERT(ret == 0); ret = bt_field_type_common_validate_single_clock_class( member_type, expected_clock_class); - bt_put(member_type); if (ret) { BT_LOGW("Variant field type's field's type " "is not recursively mapped to the " @@ -4599,10 +4750,10 @@ struct bt_field_type *bt_field_type_integer_copy( struct bt_field_type_common_integer *int_ft = (void *) ft; struct bt_field_type_common_integer *copy_ft; - BT_LOGD("Copying CTF writer integer field type's: addr=%p", ft); + BT_LOGD("Copying integer field type's: addr=%p", ft); copy_ft = (void *) bt_field_type_integer_create(int_ft->size); if (!copy_ft) { - BT_LOGE_STR("Cannot create CTF writer integer field type."); + BT_LOGE_STR("Cannot create integer field type."); goto end; } @@ -4612,7 +4763,7 @@ struct bt_field_type *bt_field_type_integer_copy( copy_ft->size = int_ft->size; copy_ft->base = int_ft->base; copy_ft->encoding = int_ft->encoding; - BT_LOGD("Copied CTF writer integer field type: original-ft-addr=%p, copy-ft-addr=%p", + BT_LOGD("Copied integer field type: original-ft-addr=%p, copy-ft-addr=%p", ft, copy_ft); end: @@ -4628,21 +4779,21 @@ struct bt_field_type *bt_field_type_enumeration_copy_recursive( struct bt_field_type_common_enumeration *copy_ft = NULL; struct bt_field_type_common_enumeration *container_copy_ft; - BT_LOGD("Copying CTF writer enumeration field type's: addr=%p", ft); + BT_LOGD("Copying enumeration field type's: addr=%p", ft); /* Copy the source enumeration's container */ - BT_LOGD_STR("Copying CTF writer enumeration field type's container field type."); + BT_LOGD_STR("Copying enumeration field type's container field type."); container_copy_ft = BT_FROM_COMMON(bt_field_type_common_copy( BT_TO_COMMON(enum_ft->container_ft))); if (!container_copy_ft) { - BT_LOGE_STR("Cannot copy CTF writer enumeration field type's container field type."); + BT_LOGE_STR("Cannot copy enumeration field type's container field type."); goto end; } copy_ft = (void *) bt_field_type_enumeration_create( (void *) container_copy_ft); if (!copy_ft) { - BT_LOGE_STR("Cannot create CTF writer enumeration field type."); + BT_LOGE_STR("Cannot create enumeration field type."); goto end; } @@ -4662,7 +4813,7 @@ struct bt_field_type *bt_field_type_enumeration_copy_recursive( g_ptr_array_add(copy_ft->entries, copy_mapping); } - BT_LOGD("Copied CTF writer enumeration field type: original-ft-addr=%p, copy-ft-addr=%p", + BT_LOGD("Copied enumeration field type: original-ft-addr=%p, copy-ft-addr=%p", ft, copy_ft); end: @@ -4682,17 +4833,17 @@ struct bt_field_type *bt_field_type_floating_point_copy( struct bt_field_type_common_floating_point *flt_ft = BT_FROM_COMMON(ft); struct bt_field_type_common_floating_point *copy_ft; - BT_LOGD("Copying CTF writer floating point number field type's: addr=%p", ft); + BT_LOGD("Copying floating point number field type's: addr=%p", ft); copy_ft = (void *) bt_field_type_floating_point_create(); if (!copy_ft) { - BT_LOGE_STR("Cannot create CTF writer floating point number field type."); + BT_LOGE_STR("Cannot create floating point number field type."); goto end; } copy_ft->user_byte_order = flt_ft->user_byte_order; copy_ft->exp_dig = flt_ft->exp_dig; copy_ft->mant_dig = flt_ft->mant_dig; - BT_LOGD("Copied CTF writer floating point number field type: original-ft-addr=%p, copy-ft-addr=%p", + BT_LOGD("Copied floating point number field type: original-ft-addr=%p, copy-ft-addr=%p", ft, copy_ft); end: @@ -4709,10 +4860,10 @@ struct bt_field_type *bt_field_type_structure_copy_recursive( struct bt_field_type_common_structure *struct_ft = (void *) ft; struct bt_field_type_common_structure *copy_ft; - BT_LOGD("Copying CTF writer structure field type's: addr=%p", ft); + BT_LOGD("Copying structure field type's: addr=%p", ft); copy_ft = (void *) bt_field_type_structure_create(); if (!copy_ft) { - BT_LOGE_STR("Cannot create CTF writer structure field type."); + BT_LOGE_STR("Cannot create structure field type."); goto end; } @@ -4723,38 +4874,36 @@ struct bt_field_type *bt_field_type_structure_copy_recursive( key, value); } + g_array_set_size(copy_ft->fields, struct_ft->fields->len); + for (i = 0; i < struct_ft->fields->len; i++) { - struct structure_field_common *entry, *copy_entry; + struct bt_field_type_common_structure_field *entry, *copy_entry; struct bt_field_type_common *field_ft_copy; - entry = g_ptr_array_index(struct_ft->fields, i); - BT_LOGD("Copying CTF writer structure field type's field: " + entry = BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX( + struct_ft, i); + copy_entry = BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX( + copy_ft, i); + BT_LOGD("Copying structure field type's field: " "index=%" PRId64 ", " "field-ft-addr=%p, field-name=\"%s\"", i, entry, g_quark_to_string(entry->name)); - copy_entry = g_new0(struct structure_field_common, 1); - if (!copy_entry) { - BT_LOGE_STR("Failed to allocate one structure field type field."); - goto error; - } field_ft_copy = (void *) bt_field_type_copy( (void *) entry->type); if (!field_ft_copy) { - BT_LOGE("Cannot copy CTF writer structure field type's field: " + BT_LOGE("Cannot copy structure field type's field: " "index=%" PRId64 ", " "field-ft-addr=%p, field-name=\"%s\"", i, entry, g_quark_to_string(entry->name)); - g_free(copy_entry); goto error; } copy_entry->name = entry->name; copy_entry->type = field_ft_copy; - g_ptr_array_add(copy_ft->fields, copy_entry); } - BT_LOGD("Copied CTF writer structure field type: original-ft-addr=%p, copy-ft-addr=%p", + BT_LOGD("Copied structure field type: original-ft-addr=%p, copy-ft-addr=%p", ft, copy_ft); end: @@ -4776,13 +4925,13 @@ struct bt_field_type *bt_field_type_variant_copy_recursive( struct bt_field_type_common_variant *var_ft = (void *) ft; struct bt_field_type_common_variant *copy_ft = NULL; - BT_LOGD("Copying CTF writer variant field type's: addr=%p", ft); + BT_LOGD("Copying variant field type's: addr=%p", ft); if (var_ft->tag_ft) { - BT_LOGD_STR("Copying CTF writer variant field type's tag field type."); + BT_LOGD_STR("Copying variant field type's tag field type."); tag_ft_copy = bt_field_type_common_copy( BT_TO_COMMON(var_ft->tag_ft)); if (!tag_ft_copy) { - BT_LOGE_STR("Cannot copy CTF writer variant field type's tag field type."); + BT_LOGE_STR("Cannot copy variant field type's tag field type."); goto end; } } @@ -4791,36 +4940,36 @@ struct bt_field_type *bt_field_type_variant_copy_recursive( (void *) tag_ft_copy, var_ft->tag_name->len ? var_ft->tag_name->str : NULL); if (!copy_ft) { - BT_LOGE_STR("Cannot create CTF writer variant field type."); + BT_LOGE_STR("Cannot create variant field type."); goto end; } /* Copy field_name_to_index */ - g_hash_table_iter_init(&iter, var_ft->field_name_to_index); + g_hash_table_iter_init(&iter, var_ft->choice_name_to_index); while (g_hash_table_iter_next(&iter, &key, &value)) { - g_hash_table_insert(copy_ft->field_name_to_index, + g_hash_table_insert(copy_ft->choice_name_to_index, key, value); } - for (i = 0; i < var_ft->fields->len; i++) { - struct structure_field_common *entry, *copy_entry; + g_array_set_size(copy_ft->choices, var_ft->choices->len); + + for (i = 0; i < var_ft->choices->len; i++) { + struct bt_field_type_common_variant_choice *entry, *copy_entry; struct bt_field_type_common *field_ft_copy; + uint64_t range_i; - entry = g_ptr_array_index(var_ft->fields, i); - BT_LOGD("Copying CTF writer variant field type's field: " + entry = BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft, i); + copy_entry = BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX( + copy_ft, i); + BT_LOGD("Copying variant field type's field: " "index=%" PRId64 ", " "field-ft-addr=%p, field-name=\"%s\"", i, entry, g_quark_to_string(entry->name)); - copy_entry = g_new0(struct structure_field_common, 1); - if (!copy_entry) { - BT_LOGE_STR("Failed to allocate one variant field type field."); - goto error; - } field_ft_copy = (void *) bt_field_type_copy( (void *) entry->type); if (!field_ft_copy) { - BT_LOGE("Cannot copy CTF writer variant field type's field: " + BT_LOGE("Cannot copy variant field type's field: " "index=%" PRId64 ", " "field-ft-addr=%p, field-name=\"%s\"", i, entry, g_quark_to_string(entry->name)); @@ -4830,19 +4979,29 @@ struct bt_field_type *bt_field_type_variant_copy_recursive( copy_entry->name = entry->name; copy_entry->type = field_ft_copy; - g_ptr_array_add(copy_ft->fields, copy_entry); + + /* Copy ranges */ + copy_entry->ranges = g_array_new(FALSE, TRUE, + sizeof(struct bt_field_type_common_variant_choice_range)); + BT_ASSERT(copy_entry->ranges); + g_array_set_size(copy_entry->ranges, entry->ranges->len); + + for (range_i = 0; range_i < entry->ranges->len; range_i++) { + copy_entry->ranges[range_i] = entry->ranges[range_i]; + } } if (var_ft->tag_field_path) { - BT_LOGD_STR("Copying CTF writer variant field type's tag field path."); + BT_LOGD_STR("Copying variant field type's tag field path."); copy_ft->tag_field_path = bt_field_path_copy( var_ft->tag_field_path); if (!copy_ft->tag_field_path) { - BT_LOGE_STR("Cannot copy CTF writer variant field type's tag field path."); + BT_LOGE_STR("Cannot copy variant field type's tag field path."); goto error; } } + copy_ft->choices_up_to_date = var_ft->choices_up_to_date; BT_LOGD("Copied variant field type: original-ft-addr=%p, copy-ft-addr=%p", ft, copy_ft); @@ -4864,22 +5023,22 @@ struct bt_field_type *bt_field_type_array_copy_recursive( struct bt_field_type_common_array *array_ft = (void *) ft; struct bt_field_type_common_array *copy_ft = NULL; - BT_LOGD("Copying CTF writer array field type's: addr=%p", ft); - BT_LOGD_STR("Copying CTF writer array field type's element field type."); + BT_LOGD("Copying array field type's: addr=%p", ft); + BT_LOGD_STR("Copying array field type's element field type."); container_ft_copy = bt_field_type_common_copy(array_ft->element_ft); if (!container_ft_copy) { - BT_LOGE_STR("Cannot copy CTF writer array field type's element field type."); + BT_LOGE_STR("Cannot copy array field type's element field type."); goto end; } copy_ft = (void *) bt_field_type_array_create( (void *) container_ft_copy, array_ft->length); if (!copy_ft) { - BT_LOGE_STR("Cannot create CTF writer array field type."); + BT_LOGE_STR("Cannot create array field type."); goto end; } - BT_LOGD("Copied CTF writer array field type: original-ft-addr=%p, copy-ft-addr=%p", + BT_LOGD("Copied array field type: original-ft-addr=%p, copy-ft-addr=%p", ft, copy_ft); end: @@ -4895,11 +5054,11 @@ struct bt_field_type *bt_field_type_sequence_copy_recursive( struct bt_field_type_common_sequence *seq_ft = (void *) ft; struct bt_field_type_common_sequence *copy_ft = NULL; - BT_LOGD("Copying CTF writer sequence field type's: addr=%p", ft); - BT_LOGD_STR("Copying CTF writer sequence field type's element field type."); + BT_LOGD("Copying sequence field type's: addr=%p", ft); + BT_LOGD_STR("Copying sequence field type's element field type."); container_ft_copy = bt_field_type_common_copy(seq_ft->element_ft); if (!container_ft_copy) { - BT_LOGE_STR("Cannot copy CTF writer sequence field type's element field type."); + BT_LOGE_STR("Cannot copy sequence field type's element field type."); goto end; } @@ -4908,21 +5067,21 @@ struct bt_field_type *bt_field_type_sequence_copy_recursive( seq_ft->length_field_name->len ? seq_ft->length_field_name->str : NULL); if (!copy_ft) { - BT_LOGE_STR("Cannot create CTF writer sequence field type."); + BT_LOGE_STR("Cannot create sequence field type."); goto end; } if (seq_ft->length_field_path) { - BT_LOGD_STR("Copying CTF writer sequence field type's length field path."); + BT_LOGD_STR("Copying sequence field type's length field path."); copy_ft->length_field_path = bt_field_path_copy( seq_ft->length_field_path); if (!copy_ft->length_field_path) { - BT_LOGE_STR("Cannot copy CTF writer sequence field type's length field path."); + BT_LOGE_STR("Cannot copy sequence field type's length field path."); goto error; } } - BT_LOGD("Copied CTF writer sequence field type: original-ft-addr=%p, copy-ft-addr=%p", + BT_LOGD("Copied sequence field type: original-ft-addr=%p, copy-ft-addr=%p", ft, copy_ft); end: @@ -4940,15 +5099,15 @@ struct bt_field_type *bt_field_type_string_copy(struct bt_field_type *ft) struct bt_field_type_common_string *string_ft = (void *) ft; struct bt_field_type_common_string *copy_ft = NULL; - BT_LOGD("Copying CTF writer string field type's: addr=%p", ft); + BT_LOGD("Copying string field type's: addr=%p", ft); copy_ft = (void *) bt_field_type_string_create(); if (!copy_ft) { - BT_LOGE_STR("Cannot create CTF writer string field type."); + BT_LOGE_STR("Cannot create string field type."); goto end; } copy_ft->encoding = string_ft->encoding; - BT_LOGD("Copied CTF writer string field type: original-ft-addr=%p, copy-ft-addr=%p", + BT_LOGD("Copied string field type: original-ft-addr=%p, copy-ft-addr=%p", ft, copy_ft); end: