+#define BT_ASSERT_PRE_CTF_FIELD_IS_INT_OR_ENUM(_field, _name) \
+ BT_ASSERT_PRE((_field)->type->id == BT_CTF_FIELD_TYPE_ID_INTEGER || \
+ (_field)->type->id == BT_CTF_FIELD_TYPE_ID_ENUM, \
+ _name " is not an integer or an enumeration field: " \
+ "field-addr=%p", (_field))
+
+BT_HIDDEN
+struct bt_ctf_field_common *bt_ctf_field_common_copy(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common *copy = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT(field_type_common_has_known_id(field->type));
+ BT_ASSERT(field->methods->copy);
+ copy = field->methods->copy(field);
+ if (!copy) {
+ BT_LOGW("Cannot create field: ft-addr=%p", field->type);
+ goto end;
+ }
+
+ bt_ctf_field_common_set(copy, field->payload_set);
+
+end:
+ return copy;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_structure_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_ctf_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods,
+ bt_ctf_field_common_create_func field_create_func,
+ GDestroyNotify field_release_func)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_structure *structure_type =
+ BT_CTF_FROM_COMMON(type);
+ struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
+ size_t i;
+
+ BT_LOGD("Initializing common structure field object: ft-addr=%p", type);
+ bt_ctf_field_common_initialize(field, type, is_shared,
+ release_func, methods);
+ structure->fields = g_ptr_array_new_with_free_func(field_release_func);
+ g_ptr_array_set_size(structure->fields, structure_type->fields->len);
+
+ /* Create all fields contained in the structure field. */
+ for (i = 0; i < structure_type->fields->len; i++) {
+ struct bt_ctf_field_common *field;
+ struct bt_ctf_field_type_common_structure_field *struct_field =
+ BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
+ structure_type, i);
+ field = field_create_func(struct_field->type);
+ if (!field) {
+ BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
+ g_quark_to_string(struct_field->name), i);
+ ret = -1;
+ goto end;
+ }
+
+ g_ptr_array_index(structure->fields, i) = field;
+ }
+
+ BT_LOGD("Initialized common structure field object: addr=%p, ft-addr=%p",
+ field, type);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_variant_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_ctf_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods,
+ bt_ctf_field_common_create_func field_create_func,
+ GDestroyNotify field_release_func)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_variant *variant_type =
+ BT_CTF_FROM_COMMON(type);
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
+ size_t i;
+
+ BT_LOGD("Initializing common variant field object: ft-addr=%p", type);
+ bt_ctf_field_common_initialize(field, type, is_shared,
+ release_func, methods);
+ ret = bt_ctf_field_type_common_variant_update_choices(type);
+ if (ret) {
+ BT_LOGE("Cannot update common variant field type choices: "
+ "ret=%d", ret);
+ goto end;
+ }
+
+ variant->fields = g_ptr_array_new_with_free_func(field_release_func);
+ g_ptr_array_set_size(variant->fields, variant_type->choices->len);
+
+ /* Create all fields contained in the variant field. */
+ for (i = 0; i < variant_type->choices->len; i++) {
+ struct bt_ctf_field_common *field;
+ struct bt_ctf_field_type_common_variant_choice *var_choice =
+ BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
+ variant_type, i);
+
+ field = field_create_func(var_choice->type);
+ if (!field) {
+ BT_LOGE("Failed to create variant field's member: name=\"%s\", index=%zu",
+ g_quark_to_string(var_choice->name), i);
+ ret = -1;
+ goto end;
+ }
+
+ g_ptr_array_index(variant->fields, i) = field;
+ }
+
+ BT_LOGD("Initialized common variant field object: addr=%p, ft-addr=%p",
+ field, type);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_string_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_ctf_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods)
+{
+ int ret = 0;
+ struct bt_ctf_field_common_string *string = BT_CTF_FROM_COMMON(field);
+
+ BT_LOGD("Initializing common string field object: ft-addr=%p", type);
+ bt_ctf_field_common_initialize(field, type, is_shared,
+ release_func, methods);
+ string->buf = g_array_sized_new(FALSE, FALSE, sizeof(char), 1);
+ if (!string->buf) {
+ ret = -1;
+ goto end;
+ }
+
+ g_array_index(string->buf, char, 0) = '\0';
+ BT_LOGD("Initialized common string field object: addr=%p, ft-addr=%p",
+ field, type);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_array_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_ctf_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods,
+ bt_ctf_field_common_create_func field_create_func,
+ GDestroyNotify field_destroy_func)
+{
+ struct bt_ctf_field_type_common_array *array_type = BT_CTF_FROM_COMMON(type);
+ struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
+ unsigned int array_length;
+ int ret = 0;
+ uint64_t i;
+
+ BT_LOGD("Initializing common array field object: ft-addr=%p", type);
+ BT_ASSERT(type);
+ bt_ctf_field_common_initialize(field, type, is_shared,
+ release_func, methods);
+ array_length = array_type->length;
+ array->elements = g_ptr_array_sized_new(array_length);
+ if (!array->elements) {
+ ret = -1;
+ goto end;
+ }
+
+ g_ptr_array_set_free_func(array->elements, field_destroy_func);
+ g_ptr_array_set_size(array->elements, array_length);
+
+ for (i = 0; i < array_length; i++) {
+ array->elements->pdata[i] = field_create_func(
+ array_type->element_ft);
+ if (!array->elements->pdata[i]) {
+ ret = -1;
+ goto end;
+ }
+ }
+
+ BT_LOGD("Initialized common array field object: addr=%p, ft-addr=%p",
+ field, type);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_sequence_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_ctf_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods,
+ GDestroyNotify field_destroy_func)
+{
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
+ int ret = 0;
+
+ BT_LOGD("Initializing common sequence field object: ft-addr=%p", type);
+ BT_ASSERT(type);
+ bt_ctf_field_common_initialize(field, type, is_shared,
+ release_func, methods);
+ sequence->elements = g_ptr_array_new();
+ if (!sequence->elements) {
+ ret = -1;
+ goto end;
+ }
+
+ g_ptr_array_set_free_func(sequence->elements, field_destroy_func);
+ BT_LOGD("Initialized common sequence field object: addr=%p, ft-addr=%p",
+ field, type);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_generic_validate(struct bt_ctf_field_common *field)
+{
+ return (field && field->payload_set) ? 0 : -1;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_structure_validate_recursive(struct bt_ctf_field_common *field)
+{
+ int64_t i;
+ int ret = 0;
+ struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < structure->fields->len; i++) {
+ ret = bt_ctf_field_common_validate_recursive(
+ (void *) structure->fields->pdata[i]);
+
+ if (ret) {
+ int this_ret;
+ const char *name;
+
+ this_ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
+ field->type, &name, NULL, i);
+ BT_ASSERT(this_ret == 0);
+ BT_ASSERT_PRE_MSG("Invalid structure field's field: "
+ "struct-field-addr=%p, field-name=\"%s\", "
+ "index=%" PRId64 ", field-addr=%p",
+ field, name, i, structure->fields->pdata[i]);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_variant_validate_recursive(struct bt_ctf_field_common *field)
+{
+ int ret = 0;
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ if (!variant->current_field) {
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_field_common_validate_recursive(variant->current_field);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_array_validate_recursive(struct bt_ctf_field_common *field)
+{
+ int64_t i;
+ int ret = 0;
+ struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < array->elements->len; i++) {
+ ret = bt_ctf_field_common_validate_recursive((void *) array->elements->pdata[i]);
+ if (ret) {
+ BT_ASSERT_PRE_MSG("Invalid array field's element field: "
+ "array-field-addr=%p, " PRId64 ", "
+ "elem-field-addr=%p",
+ field, i, array->elements->pdata[i]);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_sequence_validate_recursive(struct bt_ctf_field_common *field)
+{
+ size_t i;
+ int ret = 0;
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < sequence->elements->len; i++) {
+ ret = bt_ctf_field_common_validate_recursive(
+ (void *) sequence->elements->pdata[i]);
+ if (ret) {
+ BT_ASSERT_PRE_MSG("Invalid sequence field's element field: "
+ "seq-field-addr=%p, " PRId64 ", "
+ "elem-field-addr=%p",
+ field, i, sequence->elements->pdata[i]);
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_generic_reset(struct bt_ctf_field_common *field)
+{
+ BT_ASSERT(field);
+ field->payload_set = false;
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_structure_reset_recursive(struct bt_ctf_field_common *field)
+{
+ int64_t i;
+ struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < structure->fields->len; i++) {
+ struct bt_ctf_field_common *member = structure->fields->pdata[i];
+
+ if (!member) {
+ /*
+ * Structure members are lazily initialized;
+ * skip if this member has not been allocated
+ * yet.
+ */
+ continue;
+ }
+
+ bt_ctf_field_common_reset_recursive(member);
+ }
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_variant_reset_recursive(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+ variant->current_field = NULL;
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_array_reset_recursive(struct bt_ctf_field_common *field)
+{
+ size_t i;
+ struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < array->elements->len; i++) {
+ struct bt_ctf_field_common *member = array->elements->pdata[i];
+
+ if (!member) {
+ /*
+ * Array elements are lazily initialized; skip
+ * if this member has not been allocated yet.
+ */
+ continue;
+ }
+
+ bt_ctf_field_common_reset_recursive(member);
+ }
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_sequence_reset_recursive(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
+ uint64_t i;
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < sequence->elements->len; i++) {
+ if (sequence->elements->pdata[i]) {
+ bt_ctf_field_common_reset_recursive(
+ sequence->elements->pdata[i]);
+ }
+ }
+
+ sequence->length = 0;
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_generic_set_is_frozen(struct bt_ctf_field_common *field,
+ bool is_frozen)
+{
+ field->frozen = is_frozen;
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_structure_set_is_frozen_recursive(
+ struct bt_ctf_field_common *field, bool is_frozen)
+{
+ uint64_t i;
+ struct bt_ctf_field_common_structure *structure_field =
+ BT_CTF_FROM_COMMON(field);
+
+ BT_LOGD("Freezing structure field object: addr=%p", field);
+
+ for (i = 0; i < structure_field->fields->len; i++) {
+ struct bt_ctf_field_common *struct_field =
+ g_ptr_array_index(structure_field->fields, i);
+
+ BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64,
+ struct_field, i);
+ bt_ctf_field_common_set_is_frozen_recursive(struct_field,
+ is_frozen);
+ }
+
+ bt_ctf_field_common_generic_set_is_frozen(field, is_frozen);
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_variant_set_is_frozen_recursive(
+ struct bt_ctf_field_common *field, bool is_frozen)
+{
+ uint64_t i;
+ struct bt_ctf_field_common_variant *variant_field = BT_CTF_FROM_COMMON(field);
+
+ BT_LOGD("Freezing variant field object: addr=%p", field);
+
+ for (i = 0; i < variant_field->fields->len; i++) {
+ struct bt_ctf_field_common *var_field =
+ g_ptr_array_index(variant_field->fields, i);
+
+ BT_LOGD("Freezing variant field's field: field-addr=%p, index=%" PRId64,
+ var_field, i);
+ bt_ctf_field_common_set_is_frozen_recursive(var_field, is_frozen);
+ }
+
+ bt_ctf_field_common_generic_set_is_frozen(field, is_frozen);
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_array_set_is_frozen_recursive(
+ struct bt_ctf_field_common *field, bool is_frozen)
+{
+ int64_t i;
+ struct bt_ctf_field_common_array *array_field = BT_CTF_FROM_COMMON(field);
+
+ BT_LOGD("Freezing array field object: addr=%p", field);
+
+ for (i = 0; i < array_field->elements->len; i++) {
+ struct bt_ctf_field_common *elem_field =
+ g_ptr_array_index(array_field->elements, i);
+
+ BT_LOGD("Freezing array field object's element field: "
+ "element-field-addr=%p, index=%" PRId64,
+ elem_field, i);
+ bt_ctf_field_common_set_is_frozen_recursive(elem_field, is_frozen);
+ }
+
+ bt_ctf_field_common_generic_set_is_frozen(field, is_frozen);
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_sequence_set_is_frozen_recursive(
+ struct bt_ctf_field_common *field, bool is_frozen)
+{
+ int64_t i;
+ struct bt_ctf_field_common_sequence *sequence_field =
+ BT_CTF_FROM_COMMON(field);
+
+ BT_LOGD("Freezing sequence field object: addr=%p", field);
+
+ for (i = 0; i < sequence_field->length; i++) {
+ struct bt_ctf_field_common *elem_field =
+ g_ptr_array_index(sequence_field->elements, i);
+
+ BT_LOGD("Freezing sequence field object's element field: "
+ "element-field-addr=%p, index=%" PRId64,
+ elem_field, i);
+ bt_ctf_field_common_set_is_frozen_recursive(elem_field, is_frozen);
+ }
+
+ bt_ctf_field_common_generic_set_is_frozen(field, is_frozen);
+}
+
+BT_HIDDEN
+void _bt_ctf_field_common_set_is_frozen_recursive(struct bt_ctf_field_common *field,
+ bool is_frozen)
+{
+ if (!field) {
+ goto end;
+ }
+
+ BT_LOGD("Setting field object's frozen state: addr=%p, is-frozen=%d",
+ field, is_frozen);
+ BT_ASSERT(field_type_common_has_known_id(field->type));
+ BT_ASSERT(field->methods->set_is_frozen);
+ field->methods->set_is_frozen(field, is_frozen);
+
+end:
+ return;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_generic_is_set(struct bt_ctf_field_common *field)
+{
+ return field && field->payload_set;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_structure_is_set_recursive(
+ struct bt_ctf_field_common *field)
+{
+ bt_bool is_set = BT_FALSE;
+ size_t i;
+ struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < structure->fields->len; i++) {
+ is_set = bt_ctf_field_common_is_set_recursive(
+ structure->fields->pdata[i]);
+ if (!is_set) {
+ goto end;
+ }
+ }
+
+end:
+ return is_set;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_variant_is_set_recursive(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
+ bt_bool is_set = BT_FALSE;
+
+ BT_ASSERT(field);
+
+ if (variant->current_field) {
+ is_set = bt_ctf_field_common_is_set_recursive(
+ variant->current_field);
+ }
+
+ return is_set;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_array_is_set_recursive(struct bt_ctf_field_common *field)
+{
+ size_t i;
+ bt_bool is_set = BT_FALSE;
+ struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < array->elements->len; i++) {
+ is_set = bt_ctf_field_common_is_set_recursive(array->elements->pdata[i]);
+ if (!is_set) {
+ goto end;
+ }
+ }
+
+end:
+ return is_set;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_sequence_is_set_recursive(struct bt_ctf_field_common *field)
+{
+ size_t i;
+ bt_bool is_set = BT_FALSE;
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ if (!sequence->elements) {
+ goto end;
+ }
+
+ for (i = 0; i < sequence->elements->len; i++) {
+ is_set = bt_ctf_field_common_is_set_recursive(
+ sequence->elements->pdata[i]);
+ if (!is_set) {
+ goto end;
+ }
+ }
+
+end:
+ return is_set;
+}
+
+static struct bt_ctf_field_common_methods bt_ctf_field_integer_methods = {
+ .set_is_frozen = bt_ctf_field_common_generic_set_is_frozen,
+ .validate = bt_ctf_field_common_generic_validate,