X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=lib%2Fctf-writer%2Ffields.c;fp=lib%2Fctf-writer%2Ffields.c;h=11baf31b76c4c7bf1ee3fc6cf90bec5947813c61;hb=312c056ae3d374b253fa0cfe5ed576c0b0e5e569;hp=1a0526d2546fcd096ded90c75d59b7f00699bd1c;hpb=d1e4683534e67cc8643ad27536f64f6cc54bc5dc;p=babeltrace.git diff --git a/lib/ctf-writer/fields.c b/lib/ctf-writer/fields.c index 1a0526d2..11baf31b 100644 --- a/lib/ctf-writer/fields.c +++ b/lib/ctf-writer/fields.c @@ -42,7 +42,7 @@ #include static struct bt_field_common_methods bt_ctf_field_integer_methods = { - .freeze = bt_field_common_generic_freeze, + .set_is_frozen = bt_field_common_generic_set_is_frozen, .validate = bt_field_common_generic_validate, .copy = NULL, .is_set = bt_field_common_generic_is_set, @@ -50,23 +50,37 @@ static struct bt_field_common_methods bt_ctf_field_integer_methods = { }; static struct bt_field_common_methods bt_ctf_field_floating_point_methods = { - .freeze = bt_field_common_generic_freeze, + .set_is_frozen = bt_field_common_generic_set_is_frozen, .validate = bt_field_common_generic_validate, .copy = NULL, .is_set = bt_field_common_generic_is_set, .reset = bt_field_common_generic_reset, }; +static +void bt_ctf_field_enumeration_set_is_frozen_recursive( + struct bt_field_common *field, bool is_frozen); + +static +int bt_ctf_field_enumeration_validate_recursive(struct bt_field_common *field); + +static +bt_bool bt_ctf_field_enumeration_is_set_recursive( + struct bt_field_common *field); + +static +void bt_ctf_field_enumeration_reset_recursive(struct bt_field_common *field); + static struct bt_field_common_methods bt_ctf_field_enumeration_methods = { - .freeze = bt_field_common_enumeration_freeze_recursive, - .validate = bt_field_common_enumeration_validate_recursive, + .set_is_frozen = bt_ctf_field_enumeration_set_is_frozen_recursive, + .validate = bt_ctf_field_enumeration_validate_recursive, .copy = NULL, - .is_set = bt_field_common_enumeration_is_set_recursive, - .reset = bt_field_common_enumeration_reset_recursive, + .is_set = bt_ctf_field_enumeration_is_set_recursive, + .reset = bt_ctf_field_enumeration_reset_recursive, }; static struct bt_field_common_methods bt_ctf_field_string_methods = { - .freeze = bt_field_common_generic_freeze, + .set_is_frozen = bt_field_common_generic_set_is_frozen, .validate = bt_field_common_generic_validate, .copy = NULL, .is_set = bt_field_common_generic_is_set, @@ -74,7 +88,7 @@ static struct bt_field_common_methods bt_ctf_field_string_methods = { }; static struct bt_field_common_methods bt_ctf_field_structure_methods = { - .freeze = bt_field_common_structure_freeze_recursive, + .set_is_frozen = bt_field_common_structure_set_is_frozen_recursive, .validate = bt_field_common_structure_validate_recursive, .copy = NULL, .is_set = bt_field_common_structure_is_set_recursive, @@ -82,7 +96,7 @@ static struct bt_field_common_methods bt_ctf_field_structure_methods = { }; static struct bt_field_common_methods bt_ctf_field_sequence_methods = { - .freeze = bt_field_common_sequence_freeze_recursive, + .set_is_frozen = bt_field_common_sequence_set_is_frozen_recursive, .validate = bt_field_common_sequence_validate_recursive, .copy = NULL, .is_set = bt_field_common_sequence_is_set_recursive, @@ -90,19 +104,32 @@ static struct bt_field_common_methods bt_ctf_field_sequence_methods = { }; static struct bt_field_common_methods bt_ctf_field_array_methods = { - .freeze = bt_field_common_array_freeze_recursive, + .set_is_frozen = bt_field_common_array_set_is_frozen_recursive, .validate = bt_field_common_array_validate_recursive, .copy = NULL, .is_set = bt_field_common_array_is_set_recursive, .reset = bt_field_common_array_reset_recursive, }; +static +void bt_ctf_field_variant_set_is_frozen_recursive(struct bt_field_common *field, + bool is_frozen); + +static +int bt_ctf_field_variant_validate_recursive(struct bt_field_common *field); + +static +bt_bool bt_ctf_field_variant_is_set_recursive(struct bt_field_common *field); + +static +void bt_ctf_field_variant_reset_recursive(struct bt_field_common *field); + static struct bt_field_common_methods bt_ctf_field_variant_methods = { - .freeze = bt_field_common_variant_freeze_recursive, - .validate = bt_field_common_variant_validate_recursive, + .set_is_frozen = bt_ctf_field_variant_set_is_frozen_recursive, + .validate = bt_ctf_field_variant_validate_recursive, .copy = NULL, - .is_set = bt_field_common_variant_is_set_recursive, - .reset = bt_field_common_variant_reset_recursive, + .is_set = bt_ctf_field_variant_is_set_recursive, + .reset = bt_ctf_field_variant_reset_recursive, }; static @@ -145,6 +172,80 @@ typedef int (*bt_ctf_field_serialize_recursive_func)( struct bt_field_common *, struct bt_ctf_stream_pos *, enum bt_ctf_byte_order); +static +void bt_ctf_field_integer_destroy(struct bt_ctf_field *field) +{ + BT_LOGD("Destroying CTF writer integer field object: addr=%p", field); + bt_field_common_integer_finalize((void *) field); + g_free(field); +} + +static +void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *field) +{ + BT_LOGD("Destroying CTF writer floating point field object: addr=%p", + field); + bt_field_common_floating_point_finalize((void *) field); + g_free(field); +} + +static +void bt_ctf_field_enumeration_destroy_recursive(struct bt_ctf_field *field) +{ + struct bt_ctf_field_enumeration *enumeration = BT_FROM_COMMON(field); + + BT_LOGD("Destroying CTF writer enumeration field object: addr=%p", + field); + BT_LOGD_STR("Putting container field."); + bt_put(enumeration->container); + bt_field_common_finalize((void *) field); + g_free(field); +} + +static +void bt_ctf_field_structure_destroy_recursive(struct bt_ctf_field *field) +{ + BT_LOGD("Destroying CTF writer structure field object: addr=%p", field); + bt_field_common_structure_finalize_recursive((void *) field); + g_free(field); +} + +static +void bt_ctf_field_variant_destroy_recursive(struct bt_ctf_field *field) +{ + struct bt_ctf_field_variant *variant = BT_FROM_COMMON(field); + + BT_LOGD("Destroying CTF writer variant field object: addr=%p", field); + BT_LOGD_STR("Putting tag field."); + bt_put(variant->tag); + bt_field_common_variant_finalize_recursive((void *) field); + g_free(field); +} + +static +void bt_ctf_field_array_destroy_recursive(struct bt_ctf_field *field) +{ + BT_LOGD("Destroying CTF writer array field object: addr=%p", field); + bt_field_common_array_finalize_recursive((void *) field); + g_free(field); +} + +static +void bt_ctf_field_sequence_destroy_recursive(struct bt_ctf_field *field) +{ + BT_LOGD("Destroying CTF writer sequence field object: addr=%p", field); + bt_field_common_sequence_finalize_recursive((void *) field); + g_free(field); +} + +static +void bt_ctf_field_string_destroy(struct bt_ctf_field *field) +{ + BT_LOGD("Destroying CTF writer string field object: addr=%p", field); + bt_field_common_string_finalize((void *) field); + g_free(field); +} + BT_HIDDEN int bt_ctf_field_serialize_recursive(struct bt_ctf_field *field, struct bt_ctf_stream_pos *pos, @@ -243,14 +344,14 @@ int bt_ctf_field_enumeration_serialize_recursive(struct bt_field_common *field, struct bt_ctf_stream_pos *pos, enum bt_ctf_byte_order native_byte_order) { - struct bt_field_common_enumeration *enumeration = BT_FROM_COMMON(field); + struct bt_ctf_field_enumeration *enumeration = (void *) field; BT_LOGV("Serializing enumeration field: addr=%p, pos-offset=%" PRId64 ", " "native-bo=%s", field, pos->offset, bt_common_byte_order_string((int) native_byte_order)); BT_LOGV_STR("Serializing enumeration field's payload field."); - return bt_ctf_field_serialize_recursive((void *) enumeration->payload, - pos, native_byte_order); + return bt_ctf_field_serialize_recursive( + (void *) enumeration->container, pos, native_byte_order); } static @@ -365,7 +466,7 @@ int bt_ctf_field_variant_serialize_recursive(struct bt_field_common *field, bt_common_byte_order_string((int) native_byte_order)); BT_LOGV_STR("Serializing variant field's payload field."); return bt_ctf_field_serialize_recursive( - (void *) variant->payload, pos, native_byte_order); + (void *) variant->current_field, pos, native_byte_order); } static @@ -513,17 +614,31 @@ enum bt_ctf_field_type_id bt_ctf_field_get_type_id(struct bt_ctf_field *field) return (int) field_common->type->id; } -struct bt_ctf_field *bt_ctf_field_sequence_get_length( - struct bt_ctf_field *field) -{ - return bt_get(bt_field_common_sequence_borrow_length((void *) field)); -} - int bt_ctf_field_sequence_set_length(struct bt_ctf_field *field, struct bt_ctf_field *length_field) { + int ret; + struct bt_field_common *common_length_field = (void *) length_field; + uint64_t length; + + BT_ASSERT_PRE_NON_NULL(length_field, "Length field"); + BT_ASSERT_PRE_FIELD_COMMON_IS_SET((void *) length_field, "Length field"); + BT_ASSERT_PRE(common_length_field->type->id == BT_CTF_FIELD_TYPE_ID_INTEGER || + common_length_field->type->id == BT_CTF_FIELD_TYPE_ID_ENUM, + "Length field must be an integer or enumeration field: %!+wf", + length_field); + + if (common_length_field->type->id == BT_CTF_FIELD_TYPE_ID_ENUM) { + struct bt_ctf_field_enumeration *enumeration = (void *) + length_field; + + length_field = (void *) enumeration->container; + } + + ret = bt_ctf_field_integer_unsigned_get_value(length_field, &length); + BT_ASSERT(ret == 0); return bt_field_common_sequence_set_length((void *) field, - (void *) length_field); + length, (bt_field_common_create_func) bt_ctf_field_create); } struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index( @@ -540,33 +655,78 @@ struct bt_ctf_field *bt_ctf_field_structure_get_field_by_name( (void *) field, name)); } -int bt_ctf_field_structure_set_field_by_name(struct bt_ctf_field *field, - const char *name, struct bt_ctf_field *value) -{ - return bt_field_common_structure_set_field_by_name((void *) field, - name, (void *) value); -} - struct bt_ctf_field *bt_ctf_field_array_get_field( struct bt_ctf_field *field, uint64_t index) { - return bt_get(bt_field_common_array_borrow_field((void *) field, index, - (bt_field_common_create_func) bt_ctf_field_create)); + return bt_get( + bt_field_common_array_borrow_field((void *) field, index)); } struct bt_ctf_field *bt_ctf_field_sequence_get_field( struct bt_ctf_field *field, uint64_t index) { - return bt_get(bt_field_common_sequence_borrow_field((void *) field, - index, (bt_field_common_create_func) bt_ctf_field_create)); + return bt_get( + bt_field_common_sequence_borrow_field((void *) field, index)); } struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field, struct bt_ctf_field *tag_field) { - return bt_get(bt_field_common_variant_borrow_field((void *) field, - (void *) tag_field, - (bt_field_common_create_func) bt_ctf_field_create)); + struct bt_ctf_field_variant *variant_field = (void *) field; + struct bt_ctf_field_enumeration *enum_field = (void *) tag_field; + struct bt_field_type_common_variant *variant_ft; + struct bt_field_type_common_enumeration *tag_ft; + struct bt_ctf_field *current_field = NULL; + bt_bool is_signed; + uint64_t tag_uval; + int ret; + + BT_ASSERT_PRE_NON_NULL(field, "Variant field"); + BT_ASSERT_PRE_NON_NULL(tag_field, "Tag field"); + BT_ASSERT_PRE_FIELD_COMMON_IS_SET((void *) tag_field, "Tag field"); + BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID( + (struct bt_field_common *) tag_field, + BT_FIELD_TYPE_ID_ENUM, "Tag field"); + BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID( + (struct bt_field_common *) field, + BT_FIELD_TYPE_ID_VARIANT, "Field"); + BT_ASSERT_PRE( + bt_field_common_validate_recursive((void *) tag_field) == 0, + "Tag field is invalid: %!+wf", tag_field); + variant_ft = BT_FROM_COMMON(variant_field->common.common.type); + BT_ASSERT_PRE(bt_field_type_common_compare( + BT_TO_COMMON(variant_ft->tag_ft), enum_field->common.type) == 0, + "Unexpected tag field's type: %![expected-ft-]+wF, " + "%![tag-ft-]+wF", variant_ft->tag_ft, + enum_field->common.type); + tag_ft = BT_FROM_COMMON(enum_field->common.type); + is_signed = tag_ft->container_ft->is_signed; + + if (is_signed) { + int64_t tag_ival; + + ret = bt_ctf_field_integer_signed_get_value( + (void *) enum_field->container, &tag_ival); + tag_uval = (uint64_t) tag_ival; + } else { + ret = bt_ctf_field_integer_unsigned_get_value( + (void *) enum_field->container, &tag_uval); + } + + BT_ASSERT(ret == 0); + ret = bt_field_variant_common_set_tag((void *) field, tag_uval, + is_signed); + if (ret) { + goto end; + } + + bt_put(variant_field->tag); + variant_field->tag = bt_get(tag_field); + current_field = bt_ctf_field_variant_get_current_field(field); + BT_ASSERT(current_field); + +end: + return current_field; } struct bt_ctf_field *bt_ctf_field_variant_get_current_field( @@ -576,41 +736,102 @@ struct bt_ctf_field *bt_ctf_field_variant_get_current_field( (void *) variant_field)); } -struct bt_ctf_field *bt_ctf_field_variant_get_tag( - struct bt_ctf_field *variant_field) +BT_HIDDEN +struct bt_ctf_field *bt_ctf_field_enumeration_borrow_container( + struct bt_ctf_field *field) { - return bt_get(bt_field_common_variant_borrow_tag( - (void *) variant_field)); + struct bt_ctf_field_enumeration *enumeration = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Enumeration field"); + BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID((struct bt_field_common *) field, + BT_CTF_FIELD_TYPE_ID_ENUM, "Field"); + BT_ASSERT(enumeration->container); + return (void *) enumeration->container; } -struct bt_ctf_field *bt_ctf_field_enumeration_get_container(struct bt_ctf_field *field) +struct bt_ctf_field *bt_ctf_field_enumeration_get_container( + struct bt_ctf_field *field) { - return bt_get(bt_field_common_enumeration_borrow_container( - (void *) field, - (bt_field_common_create_func) bt_ctf_field_create)); + return bt_get(bt_ctf_field_enumeration_borrow_container(field)); } -int bt_ctf_field_integer_signed_get_value(struct bt_ctf_field *field, int64_t *value) +int bt_ctf_field_integer_signed_get_value(struct bt_ctf_field *field, + int64_t *value) { - return bt_field_common_integer_signed_get_value((void *) field, value); + struct bt_field_common_integer *integer = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Integer field"); + BT_ASSERT_PRE_NON_NULL(value, "Value"); + BT_ASSERT_PRE_FIELD_COMMON_IS_SET(BT_TO_COMMON(integer), "Integer field"); + BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(BT_TO_COMMON(integer), + BT_FIELD_TYPE_ID_INTEGER, "Field"); + BT_ASSERT_PRE(bt_field_type_common_integer_is_signed( + integer->common.type), + "Field's type is unsigned: %!+_f", field); + *value = integer->payload.signd; + return 0; } int bt_ctf_field_integer_signed_set_value(struct bt_ctf_field *field, int64_t value) { - return bt_field_common_integer_signed_set_value((void *) field, value); + int ret = 0; + struct bt_field_common_integer *integer = (void *) field; + struct bt_field_type_common_integer *integer_type; + + BT_ASSERT_PRE_NON_NULL(field, "Integer field"); + BT_ASSERT_PRE_FIELD_COMMON_HOT(BT_TO_COMMON(integer), "Integer field"); + BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(BT_TO_COMMON(integer), + BT_FIELD_TYPE_ID_INTEGER, "Field"); + integer_type = BT_FROM_COMMON(integer->common.type); + BT_ASSERT_PRE( + bt_field_type_common_integer_is_signed(integer->common.type), + "Field's type is unsigned: %!+wf", field); + BT_ASSERT_PRE(value_is_in_range_signed(integer_type->size, value), + "Value is out of bounds: value=%" PRId64 ", %![field-]+wf", + value, field); + integer->payload.signd = value; + bt_field_common_set(BT_TO_COMMON(integer), true); + return ret; } int bt_ctf_field_integer_unsigned_get_value(struct bt_ctf_field *field, uint64_t *value) { - return bt_field_common_integer_unsigned_get_value((void *) field, - value); + struct bt_field_common_integer *integer = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Integer field"); + BT_ASSERT_PRE_NON_NULL(value, "Value"); + BT_ASSERT_PRE_FIELD_COMMON_IS_SET(BT_TO_COMMON(integer), "Integer field"); + BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(BT_TO_COMMON(integer), + BT_FIELD_TYPE_ID_INTEGER, "Field"); + BT_ASSERT_PRE( + !bt_field_type_common_integer_is_signed(integer->common.type), + "Field's type is signed: %!+wf", field); + *value = integer->payload.unsignd; + return 0; } -int bt_ctf_field_integer_unsigned_set_value(struct bt_ctf_field *field, uint64_t value) +int bt_ctf_field_integer_unsigned_set_value(struct bt_ctf_field *field, + uint64_t value) { - return bt_field_common_integer_unsigned_set_value((void *) field, value); + struct bt_field_common_integer *integer = (void *) field; + struct bt_field_type_common_integer *integer_type; + + BT_ASSERT_PRE_NON_NULL(field, "Integer field"); + BT_ASSERT_PRE_FIELD_COMMON_HOT(BT_TO_COMMON(integer), "Integer field"); + BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(BT_TO_COMMON(integer), + BT_FIELD_TYPE_ID_INTEGER, "Field"); + integer_type = BT_FROM_COMMON(integer->common.type); + BT_ASSERT_PRE( + !bt_field_type_common_integer_is_signed(integer->common.type), + "Field's type is signed: %!+wf", field); + BT_ASSERT_PRE(value_is_in_range_unsigned(integer_type->size, value), + "Value is out of bounds: value=%" PRIu64 ", %![field-]+wf", + value, field); + integer->payload.unsignd = value; + bt_field_common_set(BT_TO_COMMON(integer), true); + return 0; } int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field, @@ -661,7 +882,7 @@ struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type) if (integer) { bt_field_common_initialize(BT_TO_COMMON(integer), (void *) type, - bt_field_common_integer_destroy, + (bt_object_release_func) bt_ctf_field_integer_destroy, &bt_ctf_field_integer_methods); integer->common.spec.writer.serialize_func = (bt_ctf_field_serialize_recursive_func) bt_ctf_field_integer_serialize; @@ -678,24 +899,36 @@ static struct bt_ctf_field *bt_ctf_field_enumeration_create( struct bt_ctf_field_type *type) { - struct bt_field_common_enumeration *enumeration = g_new0( - struct bt_field_common_enumeration, 1); + struct bt_field_type_common_enumeration *enum_ft = (void *) type; + struct bt_ctf_field_enumeration *enumeration = g_new0( + struct bt_ctf_field_enumeration, 1); BT_LOGD("Creating CTF writer enumeration field object: ft-addr=%p", type); - if (enumeration) { - bt_field_common_initialize(BT_TO_COMMON(enumeration), - (void *) type, - bt_field_common_enumeration_destroy_recursive, - &bt_ctf_field_enumeration_methods); - enumeration->common.spec.writer.serialize_func = - (bt_ctf_field_serialize_recursive_func) bt_ctf_field_enumeration_serialize_recursive; - BT_LOGD("Created CTF writer enumeration field object: addr=%p, ft-addr=%p", - enumeration, type); - } else { + if (!enumeration) { BT_LOGE_STR("Failed to allocate one enumeration field."); + goto end; } + bt_field_common_initialize(BT_TO_COMMON(enumeration), + (void *) type, + (bt_object_release_func) + bt_ctf_field_enumeration_destroy_recursive, + &bt_ctf_field_enumeration_methods); + enumeration->container = (void *) bt_ctf_field_create( + BT_FROM_COMMON(enum_ft->container_ft)); + if (!enumeration->container) { + BT_PUT(enumeration); + goto end; + } + + enumeration->common.spec.writer.serialize_func = + (bt_ctf_field_serialize_recursive_func) + bt_ctf_field_enumeration_serialize_recursive; + BT_LOGD("Created CTF writer enumeration field object: addr=%p, ft-addr=%p", + enumeration, type); + +end: return (void *) enumeration; } @@ -711,7 +944,8 @@ struct bt_ctf_field *bt_ctf_field_floating_point_create( if (floating_point) { bt_field_common_initialize(BT_TO_COMMON(floating_point), (void *) type, - bt_field_common_floating_point_destroy, + (bt_object_release_func) + bt_ctf_field_floating_point_destroy, &bt_ctf_field_floating_point_methods); floating_point->common.spec.writer.serialize_func = (bt_ctf_field_serialize_recursive_func) bt_ctf_field_floating_point_serialize; @@ -740,9 +974,12 @@ struct bt_ctf_field *bt_ctf_field_structure_create( } iret = bt_field_common_structure_initialize(BT_TO_COMMON(structure), - (void *) type, bt_field_common_structure_destroy_recursive, + (void *) type, + (bt_object_release_func) + bt_ctf_field_structure_destroy_recursive, &bt_ctf_field_structure_methods, - (bt_field_common_create_func) bt_ctf_field_create); + (bt_field_common_create_func) bt_ctf_field_create, + (GDestroyNotify) bt_put); structure->common.spec.writer.serialize_func = (bt_ctf_field_serialize_recursive_func) bt_ctf_field_structure_serialize_recursive; if (iret) { @@ -760,24 +997,32 @@ end: static struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *type) { - struct bt_field_common_variant *variant = g_new0( - struct bt_field_common_variant, 1); + struct bt_field_type_common_variant *var_ft = (void *) type; + struct bt_ctf_field_variant *variant = g_new0( + struct bt_ctf_field_variant, 1); BT_LOGD("Creating CTF writer variant field object: ft-addr=%p", type); - if (variant) { - bt_field_common_initialize(BT_TO_COMMON(variant), - (void *) type, - bt_field_common_variant_destroy_recursive, - &bt_ctf_field_variant_methods); - variant->common.spec.writer.serialize_func = - (bt_ctf_field_serialize_recursive_func) bt_ctf_field_variant_serialize_recursive; - BT_LOGD("Created CTF writer variant field object: addr=%p, ft-addr=%p", - variant, type); - } else { + if (!variant) { BT_LOGE_STR("Failed to allocate one variant field."); + goto end; } + bt_field_common_variant_initialize(BT_TO_COMMON(BT_TO_COMMON(variant)), + (void *) type, + (bt_object_release_func) + bt_ctf_field_variant_destroy_recursive, + &bt_ctf_field_variant_methods, + (bt_field_common_create_func) bt_ctf_field_create, + (GDestroyNotify) bt_put); + variant->tag = (void *) bt_ctf_field_create( + BT_FROM_COMMON(var_ft->tag_ft)); + variant->common.common.spec.writer.serialize_func = + (bt_ctf_field_serialize_recursive_func) bt_ctf_field_variant_serialize_recursive; + BT_LOGD("Created CTF writer variant field object: addr=%p, ft-addr=%p", + variant, type); + +end: return (void *) variant; } @@ -798,8 +1043,11 @@ struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *type) ret = bt_field_common_array_initialize(BT_TO_COMMON(array), (void *) type, - bt_field_common_array_destroy_recursive, - &bt_ctf_field_array_methods); + (bt_object_release_func) + bt_ctf_field_array_destroy_recursive, + &bt_ctf_field_array_methods, + (bt_field_common_create_func) bt_ctf_field_create, + (GDestroyNotify) bt_put); array->common.spec.writer.serialize_func = (bt_ctf_field_serialize_recursive_func) bt_ctf_field_array_serialize_recursive; if (ret) { @@ -823,10 +1071,12 @@ struct bt_ctf_field *bt_ctf_field_sequence_create(struct bt_ctf_field_type *type BT_LOGD("Creating CTF writer sequence field object: ft-addr=%p", type); if (sequence) { - bt_field_common_initialize(BT_TO_COMMON(sequence), + bt_field_common_sequence_initialize(BT_TO_COMMON(sequence), (void *) type, - bt_field_common_sequence_destroy_recursive, - &bt_ctf_field_sequence_methods); + (bt_object_release_func) + bt_ctf_field_sequence_destroy_recursive, + &bt_ctf_field_sequence_methods, + (GDestroyNotify) bt_put); sequence->common.spec.writer.serialize_func = (bt_ctf_field_serialize_recursive_func) bt_ctf_field_sequence_serialize_recursive; BT_LOGD("Created CTF writer sequence field object: addr=%p, ft-addr=%p", @@ -849,7 +1099,8 @@ struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type) if (string) { bt_field_common_initialize(BT_TO_COMMON(string), (void *) type, - bt_field_common_string_destroy, + (bt_object_release_func) + bt_ctf_field_string_destroy, &bt_ctf_field_string_methods); string->common.spec.writer.serialize_func = (bt_ctf_field_serialize_recursive_func) bt_ctf_field_string_serialize; @@ -861,3 +1112,192 @@ struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type) return (void *) string; } + +static +void bt_ctf_field_enumeration_set_is_frozen_recursive( + struct bt_field_common *field, bool is_frozen) +{ + struct bt_ctf_field_enumeration *enumeration = (void *) field; + + if (enumeration->container) { + bt_field_common_set_is_frozen_recursive( + (void *) enumeration->container, is_frozen); + } + + bt_field_common_generic_set_is_frozen((void *) field, is_frozen); +} + +static +int bt_ctf_field_enumeration_validate_recursive(struct bt_field_common *field) +{ + int ret = -1; + struct bt_ctf_field_enumeration *enumeration = (void *) field; + + if (enumeration->container) { + ret = bt_field_common_validate_recursive( + (void *) enumeration->container); + } + + return ret; +} + +static +bt_bool bt_ctf_field_enumeration_is_set_recursive(struct bt_field_common *field) +{ + bt_bool is_set = BT_FALSE; + struct bt_ctf_field_enumeration *enumeration = (void *) field; + + if (enumeration->container) { + is_set = bt_field_common_is_set_recursive( + (void *) enumeration->container); + } + + return is_set; +} + +static +void bt_ctf_field_enumeration_reset_recursive(struct bt_field_common *field) +{ + struct bt_ctf_field_enumeration *enumeration = (void *) field; + + if (enumeration->container) { + bt_field_common_reset_recursive( + (void *) enumeration->container); + } + + bt_field_common_generic_reset((void *) field); +} + +static +void bt_ctf_field_variant_set_is_frozen_recursive( + struct bt_field_common *field, bool is_frozen) +{ + struct bt_ctf_field_variant *variant = (void *) field; + + if (variant->tag) { + bt_field_common_set_is_frozen_recursive( + (void *) variant->tag, is_frozen); + } + + bt_field_common_variant_set_is_frozen_recursive((void *) field, + is_frozen); +} + +static +int bt_ctf_field_variant_validate_recursive(struct bt_field_common *field) +{ + int ret; + struct bt_ctf_field_variant *variant = (void *) field; + + if (variant->tag) { + ret = bt_field_common_validate_recursive( + (void *) variant->tag); + if (ret) { + goto end; + } + } + + ret = bt_field_common_variant_validate_recursive((void *) field); + +end: + return ret; +} + +static +bt_bool bt_ctf_field_variant_is_set_recursive(struct bt_field_common *field) +{ + bt_bool is_set; + struct bt_ctf_field_variant *variant = (void *) field; + + if (variant->tag) { + is_set = bt_field_common_is_set_recursive( + (void *) variant->tag); + if (is_set) { + goto end; + } + } + + is_set = bt_field_common_variant_is_set_recursive((void *) field); + +end: + return is_set; +} + +static +void bt_ctf_field_variant_reset_recursive(struct bt_field_common *field) +{ + struct bt_ctf_field_variant *variant = (void *) field; + + if (variant->tag) { + bt_field_common_reset_recursive( + (void *) variant->tag); + } + + bt_field_common_variant_reset_recursive((void *) field); +} + +BT_ASSERT_PRE_FUNC +static inline bool field_to_set_has_expected_type( + struct bt_field_common *struct_field, + const char *name, struct bt_field_common *value) +{ + bool ret = true; + struct bt_field_type_common *expected_field_type = NULL; + + expected_field_type = + bt_field_type_common_structure_borrow_field_type_by_name( + struct_field->type, name); + + if (bt_field_type_common_compare(expected_field_type, value->type)) { + BT_ASSERT_PRE_MSG("Value field's type is different from the expected field type: " + "%![value-ft-]+_F, %![expected-ft-]+_F", value->type, + expected_field_type); + ret = false; + goto end; + } + +end: + return ret; +} + +BT_HIDDEN +int bt_ctf_field_structure_set_field_by_name(struct bt_ctf_field *field, + const char *name, struct bt_ctf_field *value) +{ + int ret = 0; + GQuark field_quark; + struct bt_field_common *common_field = (void *) field; + struct bt_field_common_structure *structure = + BT_FROM_COMMON(common_field); + struct bt_field_common *common_value = (void *) value; + size_t index; + GHashTable *field_name_to_index; + struct bt_field_type_common_structure *structure_ft; + + BT_ASSERT_PRE_NON_NULL(field, "Parent field"); + BT_ASSERT_PRE_NON_NULL(name, "Field name"); + BT_ASSERT_PRE_NON_NULL(value, "Value field"); + BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(common_field, + BT_FIELD_TYPE_ID_STRUCT, "Parent field"); + BT_ASSERT_PRE(field_to_set_has_expected_type(common_field, + name, common_value), + "Value field's type is different from the expected field type."); + field_quark = g_quark_from_string(name); + structure_ft = BT_FROM_COMMON(common_field->type); + field_name_to_index = structure_ft->field_name_to_index; + if (!g_hash_table_lookup_extended(field_name_to_index, + GUINT_TO_POINTER(field_quark), NULL, + (gpointer *) &index)) { + BT_LOGV("Invalid parameter: no such field in structure field's type: " + "struct-field-addr=%p, struct-ft-addr=%p, " + "field-ft-addr=%p, name=\"%s\"", + field, common_field->type, common_value->type, name); + ret = -1; + goto end; + } + bt_get(value); + BT_MOVE(structure->fields->pdata[index], value); + +end: + return ret; +}