lib: add internal object pool API and use it; adapt plugins/tests
[babeltrace.git] / lib / ctf-writer / fields.c
index 1a0526d2546fcd096ded90c75d59b7f00699bd1c..11baf31b76c4c7bf1ee3fc6cf90bec5947813c61 100644 (file)
@@ -42,7 +42,7 @@
 #include <stdlib.h>
 
 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;
+}
This page took 0.03653 seconds and 4 git commands to generate.