X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=lib%2Fctf-ir%2Ffields.c;h=3ebe6ebf18b25805bf9bf23393e63e599b8c5f00;hb=cb6f1f7dfb7938a4738a7f3ca3886334fbceb1a3;hp=bd5e1bda51f504350f7bab75b7bd45626dc7f615;hpb=094ff7c009937bb23c056333baffe734308a6b06;p=babeltrace.git diff --git a/lib/ctf-ir/fields.c b/lib/ctf-ir/fields.c index bd5e1bda..3ebe6ebf 100644 --- a/lib/ctf-ir/fields.c +++ b/lib/ctf-ir/fields.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -40,98 +41,132 @@ #include #include +#define BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(_field, _name) \ + BT_ASSERT_PRE((_field)->type->id == BT_FIELD_TYPE_ID_INTEGER || \ + (_field)->type->id == BT_FIELD_TYPE_ID_ENUM, \ + _name " is not an integer or an enumeration field: " \ + "%!+f", (_field)) + +static +int bt_field_generic_validate(struct bt_field *field); + +static +int bt_field_structure_validate_recursive(struct bt_field *field); + +static +int bt_field_variant_validate_recursive(struct bt_field *field); + +static +int bt_field_array_validate_recursive(struct bt_field *field); + +static +int bt_field_sequence_validate_recursive(struct bt_field *field); + +static +void bt_field_generic_reset(struct bt_field *field); + +static +void bt_field_structure_reset_recursive(struct bt_field *field); + +static +void bt_field_variant_reset_recursive(struct bt_field *field); + +static +void bt_field_array_reset_recursive(struct bt_field *field); + +static +void bt_field_sequence_reset_recursive(struct bt_field *field); + +static +void bt_field_generic_set_is_frozen(struct bt_field *field, + bool is_frozen); + +static +void bt_field_structure_set_is_frozen_recursive( + struct bt_field *field, bool is_frozen); + static -struct bt_field_common *bt_field_integer_copy(struct bt_field_common *src); +void bt_field_variant_set_is_frozen_recursive( + struct bt_field *field, bool is_frozen); static -struct bt_field_common *bt_field_enumeration_copy_recursive( - struct bt_field_common *src); +void bt_field_array_set_is_frozen_recursive( + struct bt_field *field, bool is_frozen); static -struct bt_field_common *bt_field_floating_point_copy( - struct bt_field_common *src); +void bt_field_sequence_set_is_frozen_recursive( + struct bt_field *field, bool is_frozen); static -struct bt_field_common *bt_field_structure_copy_recursive( - struct bt_field_common *src); +bt_bool bt_field_generic_is_set(struct bt_field *field); static -struct bt_field_common *bt_field_variant_copy_recursive( - struct bt_field_common *src); +bt_bool bt_field_structure_is_set_recursive( + struct bt_field *field); static -struct bt_field_common *bt_field_array_copy_recursive( - struct bt_field_common *src); +bt_bool bt_field_variant_is_set_recursive(struct bt_field *field); static -struct bt_field_common *bt_field_sequence_copy_recursive( - struct bt_field_common *src); +bt_bool bt_field_array_is_set_recursive(struct bt_field *field); static -struct bt_field_common *bt_field_string_copy(struct bt_field_common *src); +bt_bool bt_field_sequence_is_set_recursive(struct bt_field *field); -static struct bt_field_common_methods bt_field_integer_methods = { - .freeze = bt_field_common_generic_freeze, - .validate = bt_field_common_generic_validate, - .copy = bt_field_integer_copy, - .is_set = bt_field_common_generic_is_set, - .reset = bt_field_common_generic_reset, +static struct bt_field_methods bt_field_integer_methods = { + .set_is_frozen = bt_field_generic_set_is_frozen, + .validate = bt_field_generic_validate, + .is_set = bt_field_generic_is_set, + .reset = bt_field_generic_reset, }; -static struct bt_field_common_methods bt_field_floating_point_methods = { - .freeze = bt_field_common_generic_freeze, - .validate = bt_field_common_generic_validate, - .copy = bt_field_floating_point_copy, - .is_set = bt_field_common_generic_is_set, - .reset = bt_field_common_generic_reset, +static struct bt_field_methods bt_field_floating_point_methods = { + .set_is_frozen = bt_field_generic_set_is_frozen, + .validate = bt_field_generic_validate, + .is_set = bt_field_generic_is_set, + .reset = bt_field_generic_reset, }; -static struct bt_field_common_methods bt_field_enumeration_methods = { - .freeze = bt_field_common_enumeration_freeze_recursive, - .validate = bt_field_common_enumeration_validate_recursive, - .copy = bt_field_enumeration_copy_recursive, - .is_set = bt_field_common_enumeration_is_set_recursive, - .reset = bt_field_common_enumeration_reset_recursive, +static struct bt_field_methods bt_field_enumeration_methods = { + .set_is_frozen = bt_field_generic_set_is_frozen, + .validate = bt_field_generic_validate, + .is_set = bt_field_generic_is_set, + .reset = bt_field_generic_reset, }; -static struct bt_field_common_methods bt_field_string_methods = { - .freeze = bt_field_common_generic_freeze, - .validate = bt_field_common_generic_validate, - .copy = bt_field_string_copy, - .is_set = bt_field_common_generic_is_set, - .reset = bt_field_common_string_reset, +static struct bt_field_methods bt_field_string_methods = { + .set_is_frozen = bt_field_generic_set_is_frozen, + .validate = bt_field_generic_validate, + .is_set = bt_field_generic_is_set, + .reset = bt_field_generic_reset, }; -static struct bt_field_common_methods bt_field_structure_methods = { - .freeze = bt_field_common_structure_freeze_recursive, - .validate = bt_field_common_structure_validate_recursive, - .copy = bt_field_structure_copy_recursive, - .is_set = bt_field_common_structure_is_set_recursive, - .reset = bt_field_common_structure_reset_recursive, +static struct bt_field_methods bt_field_structure_methods = { + .set_is_frozen = bt_field_structure_set_is_frozen_recursive, + .validate = bt_field_structure_validate_recursive, + .is_set = bt_field_structure_is_set_recursive, + .reset = bt_field_structure_reset_recursive, }; -static struct bt_field_common_methods bt_field_sequence_methods = { - .freeze = bt_field_common_sequence_freeze_recursive, - .validate = bt_field_common_sequence_validate_recursive, - .copy = bt_field_sequence_copy_recursive, - .is_set = bt_field_common_sequence_is_set_recursive, - .reset = bt_field_common_sequence_reset_recursive, +static struct bt_field_methods bt_field_sequence_methods = { + .set_is_frozen = bt_field_sequence_set_is_frozen_recursive, + .validate = bt_field_sequence_validate_recursive, + .is_set = bt_field_sequence_is_set_recursive, + .reset = bt_field_sequence_reset_recursive, }; -static struct bt_field_common_methods bt_field_array_methods = { - .freeze = bt_field_common_array_freeze_recursive, - .validate = bt_field_common_array_validate_recursive, - .copy = bt_field_array_copy_recursive, - .is_set = bt_field_common_array_is_set_recursive, - .reset = bt_field_common_array_reset_recursive, +static struct bt_field_methods bt_field_array_methods = { + .set_is_frozen = bt_field_array_set_is_frozen_recursive, + .validate = bt_field_array_validate_recursive, + .is_set = bt_field_array_is_set_recursive, + .reset = bt_field_array_reset_recursive, }; -static struct bt_field_common_methods bt_field_variant_methods = { - .freeze = bt_field_common_variant_freeze_recursive, - .validate = bt_field_common_variant_validate_recursive, - .copy = bt_field_variant_copy_recursive, - .is_set = bt_field_common_variant_is_set_recursive, - .reset = bt_field_common_variant_reset_recursive, +static struct bt_field_methods bt_field_variant_methods = { + .set_is_frozen = bt_field_variant_set_is_frozen_recursive, + .validate = bt_field_variant_validate_recursive, + .is_set = bt_field_variant_is_set_recursive, + .reset = bt_field_variant_reset_recursive, }; static @@ -170,14 +205,86 @@ struct bt_field *(* const field_create_funcs[])(struct bt_field_type *) = { [BT_FIELD_TYPE_ID_STRING] = bt_field_string_create, }; -struct bt_field *bt_field_create(struct bt_field_type *type) +static +void bt_field_integer_destroy(struct bt_field *field); + +static +void bt_field_enumeration_destroy(struct bt_field *field); + +static +void bt_field_floating_point_destroy(struct bt_field *field); + +static +void bt_field_structure_destroy_recursive(struct bt_field *field); + +static +void bt_field_variant_destroy_recursive(struct bt_field *field); + +static +void bt_field_array_destroy_recursive(struct bt_field *field); + +static +void bt_field_sequence_destroy_recursive(struct bt_field *field); + +static +void bt_field_string_destroy(struct bt_field *field); + +static +void (* const field_destroy_funcs[])(struct bt_field *) = { + [BT_FIELD_TYPE_ID_INTEGER] = bt_field_integer_destroy, + [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_destroy, + [BT_FIELD_TYPE_ID_FLOAT] = bt_field_floating_point_destroy, + [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_destroy_recursive, + [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_destroy_recursive, + [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_destroy_recursive, + [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_destroy_recursive, + [BT_FIELD_TYPE_ID_STRING] = bt_field_string_destroy, +}; + +BT_ASSERT_PRE_FUNC +static inline bool value_is_in_range_signed(unsigned int size, int64_t value) +{ + bool ret = true; + int64_t min_value, max_value; + + min_value = -(1ULL << (size - 1)); + max_value = (1ULL << (size - 1)) - 1; + if (value < min_value || value > max_value) { + BT_LOGF("Value is out of bounds: value=%" PRId64 ", " + "min-value=%" PRId64 ", max-value=%" PRId64, + value, min_value, max_value); + ret = false; + } + + return ret; +} + +BT_ASSERT_PRE_FUNC +static inline bool value_is_in_range_unsigned(unsigned int size, uint64_t value) +{ + bool ret = true; + int64_t max_value; + + max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1; + if (value > max_value) { + BT_LOGF("Value is out of bounds: value=%" PRIu64 ", " + "max-value=%" PRIu64, + value, max_value); + ret = false; + } + + return ret; +} + +BT_HIDDEN +struct bt_field *bt_field_create_recursive(struct bt_field_type *type) { struct bt_field *field = NULL; enum bt_field_type_id type_id; BT_ASSERT_PRE_NON_NULL(type, "Field type"); - BT_ASSERT(field_type_common_has_known_id((void *) type)); - BT_ASSERT_PRE(bt_field_type_common_validate((void *) type) == 0, + BT_ASSERT(bt_field_type_has_known_id((void *) type)); + BT_ASSERT_PRE(bt_field_type_validate((void *) type) == 0, "Field type is invalid: %!+F", type); type_id = bt_field_type_get_type_id(type); field = field_create_funcs[type_id](type); @@ -193,352 +300,606 @@ end: struct bt_field_type *bt_field_borrow_type(struct bt_field *field) { - return (void *) bt_field_common_borrow_type((void *) field); + struct bt_field_type *ret = NULL; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + ret = field->type; + return ret; } enum bt_field_type_id bt_field_get_type_id(struct bt_field *field) { - struct bt_field_common *field_common = (void *) field; - BT_ASSERT_PRE_NON_NULL(field, "Field"); - return field_common->type->id; + return field->type->id; } -bt_bool bt_field_is_integer(struct bt_field *field) +int64_t bt_field_sequence_get_length(struct bt_field *field) { - return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_INTEGER; -} + struct bt_field_sequence *sequence = (void *) field; -bt_bool bt_field_is_floating_point(struct bt_field *field) -{ - return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_FLOAT; + BT_ASSERT_PRE_NON_NULL(field, "Sequence field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_SEQUENCE, + "Field"); + return (int64_t) sequence->length; } -bt_bool bt_field_is_enumeration(struct bt_field *field) +int bt_field_sequence_set_length(struct bt_field *field, uint64_t length) { - return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_ENUM; -} + int ret = 0; + struct bt_field_sequence *sequence = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Sequence field"); + BT_ASSERT_PRE(((int64_t) length) >= 0, + "Invalid sequence length (too large): length=%" PRId64, + length); + BT_ASSERT_PRE_FIELD_HOT(field, "Sequence field"); + + if (unlikely(length > sequence->elements->len)) { + /* Make more room */ + struct bt_field_type_sequence *sequence_ft; + uint64_t cur_len = sequence->elements->len; + uint64_t i; + + g_ptr_array_set_size(sequence->elements, length); + sequence_ft = (void *) sequence->common.type; + + for (i = cur_len; i < sequence->elements->len; i++) { + struct bt_field *elem_field = + bt_field_create_recursive( + sequence_ft->element_ft); + + if (!elem_field) { + ret = -1; + goto end; + } -bt_bool bt_field_is_string(struct bt_field *field) -{ - return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_STRING; -} + BT_ASSERT(!sequence->elements->pdata[i]); + sequence->elements->pdata[i] = elem_field; + } + } -bt_bool bt_field_is_structure(struct bt_field *field) -{ - return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_STRUCT; -} + sequence->length = length; -bt_bool bt_field_is_array(struct bt_field *field) -{ - return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_ARRAY; +end: + return ret; } -bt_bool bt_field_is_sequence(struct bt_field *field) +struct bt_field *bt_field_structure_borrow_field_by_index( + struct bt_field *field, uint64_t index) { - return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_SEQUENCE; -} + struct bt_field_structure *structure = (void *) field; -bt_bool bt_field_is_variant(struct bt_field *field) -{ - return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_VARIANT; + BT_ASSERT_PRE_NON_NULL(field, "Structure field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, + BT_FIELD_TYPE_ID_STRUCT, "Field"); + BT_ASSERT_PRE(index < structure->fields->len, + "Index is out of bound: %![struct-field-]+f, " + "index=%" PRIu64 ", count=%u", field, index, + structure->fields->len); + return structure->fields->pdata[index]; } -BT_HIDDEN -int64_t bt_field_sequence_get_int_length(struct bt_field *field) +struct bt_field *bt_field_structure_borrow_field_by_name( + struct bt_field *field, const char *name) { - return bt_field_common_sequence_get_int_length((void *) field); -} + struct bt_field *ret = NULL; + GQuark field_quark; + struct bt_field_type_structure *structure_ft; + struct bt_field_structure *structure = (void *) field; + size_t index; + GHashTable *field_name_to_index; + + BT_ASSERT_PRE_NON_NULL(field, "Structure field"); + BT_ASSERT_PRE_NON_NULL(name, "Field name"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, + BT_FIELD_TYPE_ID_STRUCT, "Field"); + structure_ft = (void *) field->type; + field_name_to_index = structure_ft->field_name_to_index; + field_quark = g_quark_from_string(name); + 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, name=\"%s\"", + field, field->type, name); + goto error; + } -struct bt_field *bt_field_sequence_borrow_length(struct bt_field *field) -{ - return (void *) bt_field_common_sequence_borrow_length((void *) field); -} + ret = structure->fields->pdata[index]; + BT_ASSERT(ret); -int bt_field_sequence_set_length(struct bt_field *field, - struct bt_field *length_field) -{ - return bt_field_common_sequence_set_length((void *) field, - (void *) length_field); +error: + return ret; } -struct bt_field *bt_field_structure_borrow_field_by_index( +struct bt_field *bt_field_array_borrow_field( struct bt_field *field, uint64_t index) { - return (void *) bt_field_common_structure_borrow_field_by_index( - (void *) field, index); -} + struct bt_field_array *array = (void *) field; -struct bt_field *bt_field_structure_borrow_field_by_name( - struct bt_field *field, const char *name) -{ - return (void *) bt_field_common_structure_borrow_field_by_name( - (void *) field, name); + BT_ASSERT_PRE_NON_NULL(field, "Array field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_ARRAY, + "Field"); + BT_ASSERT_PRE(index < array->elements->len, + "Index is out of bound: %![array-field-]+f, " + "index=%" PRIu64 ", count=%u", field, + index, array->elements->len); + return array->elements->pdata[(size_t) index]; } -int bt_field_structure_set_field_by_name(struct bt_field_common *field, - const char *name, struct bt_field_common *value) +struct bt_field *bt_field_sequence_borrow_field( + struct bt_field *field, uint64_t index) { - return bt_field_common_structure_set_field_by_name((void *) field, - name, (void *) value); + struct bt_field_sequence *sequence = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Sequence field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_SEQUENCE, + "Field"); + BT_ASSERT_PRE(index < sequence->length, + "Index is out of bound: %![seq-field-]+f, " + "index=%" PRIu64 ", count=%u", field, index, + sequence->elements->len); + return sequence->elements->pdata[(size_t) index]; } -struct bt_field *bt_field_array_borrow_field( - struct bt_field *field, uint64_t index) +struct bt_field *bt_field_variant_borrow_current_field( + struct bt_field *field) { - return (void *) bt_field_common_array_borrow_field((void *) field, - index, (bt_field_common_create_func) bt_field_create); + struct bt_field_variant *variant = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Variant field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, + BT_FIELD_TYPE_ID_VARIANT, "Field"); + BT_ASSERT_PRE(variant->current_field, + "Variant field has no current field: %!+f", field); + return variant->current_field; } -struct bt_field *bt_field_sequence_borrow_field( - struct bt_field *field, uint64_t index) +static inline +int bt_field_variant_set_tag(struct bt_field *field, + uint64_t tag_uval, bool is_signed) { - return (void *) bt_field_common_sequence_borrow_field((void *) field, - index, (bt_field_common_create_func) bt_field_create); + int ret = 0; + int64_t choice_index; + struct bt_field_variant *variant = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Variant field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, + BT_FIELD_TYPE_ID_VARIANT, "Field"); + + /* Find matching index in variant field's type */ + choice_index = bt_field_type_variant_find_choice_index( + field->type, tag_uval, is_signed); + if (choice_index < 0) { + ret = -1; + goto end; + } + + /* Select corresponding field */ + BT_ASSERT(choice_index < variant->fields->len); + variant->current_field = variant->fields->pdata[choice_index]; + variant->tag_value.u = tag_uval; + +end: + return ret; } -struct bt_field *bt_field_variant_borrow_field(struct bt_field *field, - struct bt_field *tag_field) +int bt_field_variant_set_tag_signed(struct bt_field *variant_field, + int64_t tag) { - return (void *) bt_field_common_variant_borrow_field((void *) field, - (void *) tag_field, - (bt_field_common_create_func) bt_field_create); + return bt_field_variant_set_tag((void *) variant_field, + (uint64_t) tag, true); } -struct bt_field *bt_field_variant_borrow_current_field( - struct bt_field *variant_field) +int bt_field_variant_set_tag_unsigned(struct bt_field *variant_field, + uint64_t tag) { - return (void *) bt_field_common_variant_borrow_current_field( - (void *) variant_field); + return bt_field_variant_set_tag((void *) variant_field, + (uint64_t) tag, false); } -struct bt_field_common *bt_field_variant_borrow_tag( - struct bt_field_common *variant_field) +int bt_field_variant_get_tag_signed(struct bt_field *field, + int64_t *tag) { - return (void *) bt_field_common_variant_borrow_tag( - (void *) variant_field); + struct bt_field_variant *variant = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Variant field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, + BT_FIELD_TYPE_ID_VARIANT, "Field"); + BT_ASSERT_PRE(variant->current_field, + "Variant field has no current field: %!+f", field); + *tag = variant->tag_value.i; + return 0; } -struct bt_field *bt_field_enumeration_borrow_container(struct bt_field *field) +int bt_field_variant_get_tag_unsigned(struct bt_field *field, + uint64_t *tag) { - return (void *) bt_field_common_enumeration_borrow_container( - (void *) field, (bt_field_common_create_func) bt_field_create); + struct bt_field_variant *variant = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Variant field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, + BT_FIELD_TYPE_ID_VARIANT, "Field"); + BT_ASSERT_PRE(variant->current_field, + "Variant field has no current field: %!+f", field); + *tag = variant->tag_value.u; + return 0; } struct bt_field_type_enumeration_mapping_iterator * bt_field_enumeration_get_mappings(struct bt_field *field) { - return bt_field_common_enumeration_get_mappings((void *) field, - (bt_field_common_create_func) bt_field_create); + struct bt_field_enumeration *enum_field = (void *) field; + struct bt_field_type_enumeration *enum_type = NULL; + struct bt_field_type_integer *integer_type = NULL; + struct bt_field_type_enumeration_mapping_iterator *iter = NULL; + + BT_ASSERT(field); + BT_ASSERT(field->type->id == BT_FIELD_TYPE_ID_ENUM); + BT_ASSERT(field->payload_set); + BT_ASSERT_PRE_NON_NULL(field, "Enumeration field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID((struct bt_field *) field, + BT_FIELD_TYPE_ID_ENUM, "Field"); + BT_ASSERT_PRE_FIELD_IS_SET((struct bt_field *) field, + "Enumeration field"); + enum_type = (void *) field->type; + integer_type = enum_type->container_ft; + + if (!integer_type->is_signed) { + iter = bt_field_type_enumeration_unsigned_find_mappings_by_value( + field->type, + enum_field->common.payload.unsignd); + } else { + iter = bt_field_type_enumeration_signed_find_mappings_by_value( + field->type, + enum_field->common.payload.signd); + } + + return iter; +} + +BT_ASSERT_PRE_FUNC +static inline +struct bt_field_type_integer *get_int_enum_int_ft( + struct bt_field *field) +{ + struct bt_field_integer *int_field = (void *) field; + struct bt_field_type_integer *int_ft = NULL; + + if (int_field->common.type->id == BT_FIELD_TYPE_ID_INTEGER) { + int_ft = (void *) int_field->common.type; + } else if (int_field->common.type->id == BT_FIELD_TYPE_ID_ENUM) { + struct bt_field_type_enumeration *enum_ft = + (void *) int_field->common.type; + int_ft = enum_ft->container_ft; + } else { + abort(); + } + + BT_ASSERT(int_ft); + return int_ft; } int bt_field_integer_signed_get_value(struct bt_field *field, int64_t *value) { - return bt_field_common_integer_signed_get_value((void *) field, value); + struct bt_field_integer *integer = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Integer/enumeration field"); + BT_ASSERT_PRE_NON_NULL(value, "Value"); + BT_ASSERT_PRE_FIELD_IS_SET(field, + "Integer/enumeration field"); + BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(field, "Field"); + BT_ASSERT_PRE(bt_field_type_integer_is_signed( + (void *) get_int_enum_int_ft(field)), + "Field's type is unsigned: %!+f", field); + *value = integer->payload.signd; + return 0; } -int bt_field_integer_signed_set_value(struct bt_field *field, - int64_t value) +int bt_field_integer_signed_set_value(struct bt_field *field, int64_t value) { - return bt_field_common_integer_signed_set_value((void *) field, value); + int ret = 0; + struct bt_field_integer *integer = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Integer field"); + BT_ASSERT_PRE_FIELD_HOT(field, "Integer field"); + BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(field, "Field"); + BT_ASSERT_PRE(bt_field_type_integer_is_signed( + (void *) get_int_enum_int_ft(field)), + "Field's type is unsigned: %!+f", field); + BT_ASSERT_PRE(value_is_in_range_signed( + get_int_enum_int_ft(field)->size, value), + "Value is out of bounds: value=%" PRId64 ", %![field-]+f", + value, field); + integer->payload.signd = value; + bt_field_set(field, true); + return ret; } -int bt_field_integer_unsigned_get_value(struct bt_field *field, - uint64_t *value) +int bt_field_integer_unsigned_get_value(struct bt_field *field, uint64_t *value) { - return bt_field_common_integer_unsigned_get_value((void *) field, - value); + struct bt_field_integer *integer = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Integer field"); + BT_ASSERT_PRE_NON_NULL(value, "Value"); + BT_ASSERT_PRE_FIELD_IS_SET(field, "Integer field"); + BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(field, "Field"); + BT_ASSERT_PRE(!bt_field_type_integer_is_signed( + (void *) get_int_enum_int_ft(field)), + "Field's type is signed: %!+f", field); + *value = integer->payload.unsignd; + return 0; } -int bt_field_integer_unsigned_set_value(struct bt_field *field, uint64_t value) +int bt_field_integer_unsigned_set_value(struct bt_field *field, + uint64_t value) { - return bt_field_common_integer_unsigned_set_value((void *) field, value); + struct bt_field_integer *integer = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Integer field"); + BT_ASSERT_PRE_FIELD_HOT(field, "Integer field"); + BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(field, "Field"); + BT_ASSERT_PRE(!bt_field_type_integer_is_signed( + (void *) get_int_enum_int_ft(field)), + "Field's type is signed: %!+f", field); + BT_ASSERT_PRE(value_is_in_range_unsigned( + get_int_enum_int_ft(field)->size, value), + "Value is out of bounds: value=%" PRIu64 ", %![field-]+f", + value, field); + integer->payload.unsignd = value; + bt_field_set(field, true); + return 0; } int bt_field_floating_point_get_value(struct bt_field *field, double *value) { - return bt_field_common_floating_point_get_value((void *) field, value); + struct bt_field_floating_point *floating_point = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Floating point number field"); + BT_ASSERT_PRE_NON_NULL(value, "Value"); + BT_ASSERT_PRE_FIELD_IS_SET(field, "Floating point number field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, + BT_FIELD_TYPE_ID_FLOAT, "Field"); + *value = floating_point->payload; + return 0; } int bt_field_floating_point_set_value(struct bt_field *field, double value) { - return bt_field_common_floating_point_set_value((void *) field, value); + struct bt_field_floating_point *floating_point = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Floating point number field"); + BT_ASSERT_PRE_FIELD_HOT(field, "Floating point number field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, + BT_FIELD_TYPE_ID_FLOAT, "Field"); + floating_point->payload = value; + bt_field_set(field, true); + return 0; } const char *bt_field_string_get_value(struct bt_field *field) { - return bt_field_common_string_get_value((void *) field); + struct bt_field_string *string = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "String field"); + BT_ASSERT_PRE_FIELD_IS_SET(field, "String field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, + BT_FIELD_TYPE_ID_STRING, "Field"); + return (const char *) string->buf->data; } int bt_field_string_set_value(struct bt_field *field, const char *value) { - return bt_field_common_string_set_value((void *) field, value); + BT_ASSERT_PRE_NON_NULL(field, "String field"); + BT_ASSERT_PRE_NON_NULL(value, "Value"); + BT_ASSERT_PRE_FIELD_HOT(field, "String field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, + BT_FIELD_TYPE_ID_STRING, "Field"); + bt_field_string_clear(field); + return bt_field_string_append_len(field, + value, strlen(value)); } int bt_field_string_append(struct bt_field *field, const char *value) { - return bt_field_common_string_append((void *) field, value); + BT_ASSERT_PRE_NON_NULL(value, "Value"); + return bt_field_string_append_len(field, value, + strlen(value)); } int bt_field_string_append_len(struct bt_field *field, const char *value, unsigned int length) { - return bt_field_common_string_append_len((void *) field, value, length); -} + struct bt_field_string *string_field = (void *) field; + char *data; + size_t new_size; -BT_HIDDEN -struct bt_field_common *bt_field_common_copy(struct bt_field_common *field) -{ - struct bt_field_common *copy = NULL; + BT_ASSERT_PRE_NON_NULL(field, "String field"); + BT_ASSERT_PRE_NON_NULL(value, "Value"); + BT_ASSERT_PRE_FIELD_HOT(field, "String field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, + BT_FIELD_TYPE_ID_STRING, "Field"); - 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; - } + /* Make sure no null bytes are appended */ + BT_ASSERT_PRE(memchr(value, '\0', length) == NULL, + "String value to append contains a null character: " + "partial-value=\"%.32s\", length=%u", value, length); - bt_field_common_set(copy, field->payload_set); + new_size = string_field->size + length; -end: - return copy; + if (unlikely(new_size + 1 > string_field->buf->len)) { + g_array_set_size(string_field->buf, new_size + 1); + } + + data = string_field->buf->data; + memcpy(data + string_field->size, value, length); + ((char *) string_field->buf->data)[new_size] = '\0'; + string_field->size = new_size; + bt_field_set(field, true); + return 0; } -struct bt_field *bt_field_copy(struct bt_field *field) +int bt_field_string_clear(struct bt_field *field) { - return (void *) bt_field_common_copy((void *) field); + struct bt_field_string *string_field = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "String field"); + BT_ASSERT_PRE_FIELD_HOT(field, "String field"); + BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, + BT_FIELD_TYPE_ID_STRING, "Field"); + string_field->size = 0; + bt_field_set(field, true); + return 0; } -static void bt_field_common_finalize(struct bt_field_common *field) +static inline +void bt_field_finalize(struct bt_field *field) { BT_ASSERT(field); BT_LOGD_STR("Putting field's type."); bt_put(field->type); } -BT_HIDDEN -void bt_field_common_integer_destroy(struct bt_object *obj) +static +void bt_field_integer_destroy(struct bt_field *field) { - struct bt_field_common_integer *integer = (void *) obj; - - BT_ASSERT(obj); - bt_field_common_finalize(BT_TO_COMMON(integer)); - BT_LOGD("Destroying integer field object: addr=%p", obj); - g_free(obj); + BT_ASSERT(field); + BT_LOGD("Destroying integer field object: addr=%p", field); + bt_field_finalize(field); + g_free(field); } -BT_HIDDEN -void bt_field_common_enumeration_destroy_recursive(struct bt_object *obj) +static +void bt_field_floating_point_destroy(struct bt_field *field) { - struct bt_field_common_enumeration *enumeration = (void *) obj; - - BT_ASSERT(enumeration); - bt_field_common_finalize(BT_TO_COMMON(enumeration)); - BT_LOGD("Destroying enumeration field object: addr=%p", obj); - BT_LOGD_STR("Putting payload field."); - bt_put(enumeration->payload); - g_free(enumeration); + BT_ASSERT(field); + BT_LOGD("Destroying floating point field object: addr=%p", field); + bt_field_finalize(field); + g_free(field); } -BT_HIDDEN -void bt_field_common_floating_point_destroy(struct bt_object *obj) +static +void bt_field_enumeration_destroy(struct bt_field *field) { - struct bt_field_common_floating_point *floating_point = (void *) obj; - - BT_ASSERT(obj); - bt_field_common_finalize(BT_TO_COMMON(floating_point)); - BT_LOGD("Destroying floating point number field object: addr=%p", obj); - g_free(obj); + BT_LOGD("Destroying enumeration field object: addr=%p", field); + bt_field_finalize((void *) field); + g_free(field); } -BT_HIDDEN -void bt_field_common_structure_destroy_recursive(struct bt_object *obj) +static +void bt_field_structure_destroy_recursive(struct bt_field *field) { - struct bt_field_common_structure *structure = (void *) obj; + struct bt_field_structure *structure = (void *) field; + + BT_ASSERT(field); + BT_LOGD("Destroying structure field object: addr=%p", field); + bt_field_finalize(field); + + if (structure->fields) { + g_ptr_array_free(structure->fields, TRUE); + } - BT_ASSERT(obj); - bt_field_common_finalize(BT_TO_COMMON(structure)); - BT_LOGD("Destroying structure field object: addr=%p", obj); - g_ptr_array_free(structure->fields, TRUE); - g_free(structure); + g_free(field); } -BT_HIDDEN -void bt_field_common_variant_destroy_recursive(struct bt_object *obj) +static +void bt_field_variant_destroy_recursive(struct bt_field *field) { - struct bt_field_common_variant *variant = (void *) obj; + struct bt_field_variant *variant = (void *) field; + + BT_ASSERT(field); + BT_LOGD("Destroying variant field object: addr=%p", field); + bt_field_finalize(field); + + if (variant->fields) { + g_ptr_array_free(variant->fields, TRUE); + } - BT_ASSERT(obj); - bt_field_common_finalize(BT_TO_COMMON(variant)); - BT_LOGD("Destroying variant field object: addr=%p", obj); - BT_LOGD_STR("Putting tag field."); - bt_put(variant->tag); - BT_LOGD_STR("Putting payload field."); - bt_put(variant->payload); - g_free(variant); + g_free(field); } -BT_HIDDEN -void bt_field_common_array_destroy_recursive(struct bt_object *obj) +static +void bt_field_array_destroy_recursive(struct bt_field *field) { - struct bt_field_common_array *array = (void *) obj; + struct bt_field_array *array = (void *) field; + + BT_ASSERT(field); + BT_LOGD("Destroying array field object: addr=%p", field); + bt_field_finalize(field); + + if (array->elements) { + g_ptr_array_free(array->elements, TRUE); + } - BT_ASSERT(obj); - bt_field_common_finalize(BT_TO_COMMON(array)); - BT_LOGD("Destroying array field object: addr=%p", obj); - g_ptr_array_free(array->elements, TRUE); - g_free(array); + g_free(field); } -BT_HIDDEN -void bt_field_common_sequence_destroy_recursive(struct bt_object *obj) +static +void bt_field_sequence_destroy_recursive(struct bt_field *field) { - struct bt_field_common_sequence *sequence = (void *) obj; + struct bt_field_sequence *sequence = (void *) field; - BT_ASSERT(obj); - bt_field_common_finalize(BT_TO_COMMON(sequence)); - BT_LOGD("Destroying sequence field object: addr=%p", obj); + BT_ASSERT(field); + BT_LOGD("Destroying sequence field object: addr=%p", field); + bt_field_finalize(field); if (sequence->elements) { g_ptr_array_free(sequence->elements, TRUE); } - - BT_LOGD_STR("Putting length field."); - bt_put(sequence->length); - g_free(sequence); + g_free(field); } -BT_HIDDEN -void bt_field_common_string_destroy(struct bt_object *obj) +static +void bt_field_string_destroy(struct bt_field *field) { - struct bt_field_common_string *string = (void *) obj; + struct bt_field_string *string = (void *) field; + + BT_LOGD("Destroying string field object: addr=%p", field); + BT_ASSERT(field); + bt_field_finalize(field); + + if (string->buf) { + g_array_free(string->buf, TRUE); + } - BT_ASSERT(obj); - bt_field_common_finalize(BT_TO_COMMON(string)); - BT_LOGD("Destroying string field object: addr=%p", obj); + g_free(field); +} - if (string->payload) { - g_string_free(string->payload, TRUE); +BT_HIDDEN +void bt_field_destroy_recursive(struct bt_field *field) +{ + if (!field) { + return; } - g_free(string); + BT_ASSERT(bt_field_type_has_known_id((void *) field->type)); + field_destroy_funcs[field->type->id](field); +} + +static inline +void bt_field_initialize(struct bt_field *field, + struct bt_field_type *ft, + struct bt_field_methods *methods) +{ + BT_ASSERT(field); + BT_ASSERT(ft); + bt_object_init_unique(&field->base); + field->methods = methods; + field->type = bt_get(ft); } static struct bt_field *bt_field_integer_create(struct bt_field_type *type) { - struct bt_field_common_integer *integer = - g_new0(struct bt_field_common_integer, 1); + struct bt_field_integer *integer = + g_new0(struct bt_field_integer, 1); BT_LOGD("Creating integer field object: ft-addr=%p", type); if (integer) { - bt_field_common_initialize(BT_TO_COMMON(integer), (void *) type, - bt_field_common_integer_destroy, + bt_field_initialize((void *) integer, (void *) type, &bt_field_integer_methods); BT_LOGD("Created integer field object: addr=%p, ft-addr=%p", integer, type); @@ -552,16 +913,14 @@ struct bt_field *bt_field_integer_create(struct bt_field_type *type) static struct bt_field *bt_field_enumeration_create(struct bt_field_type *type) { - struct bt_field_common_enumeration *enumeration = g_new0( - struct bt_field_common_enumeration, 1); + struct bt_field_enumeration *enumeration = g_new0( + struct bt_field_enumeration, 1); BT_LOGD("Creating 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_field_enumeration_methods); + bt_field_initialize((void *) enumeration, + (void *) type, &bt_field_enumeration_methods); BT_LOGD("Created enumeration field object: addr=%p, ft-addr=%p", enumeration, type); } else { @@ -574,16 +933,14 @@ struct bt_field *bt_field_enumeration_create(struct bt_field_type *type) static struct bt_field *bt_field_floating_point_create(struct bt_field_type *type) { - struct bt_field_common_floating_point *floating_point; + struct bt_field_floating_point *floating_point; BT_LOGD("Creating floating point number field object: ft-addr=%p", type); - floating_point = g_new0(struct bt_field_common_floating_point, 1); + floating_point = g_new0(struct bt_field_floating_point, 1); if (floating_point) { - bt_field_common_initialize(BT_TO_COMMON(floating_point), - (void *) type, - bt_field_common_floating_point_destroy, - &bt_field_floating_point_methods); + bt_field_initialize((void *) floating_point, + (void *) type, &bt_field_floating_point_methods); BT_LOGD("Created floating point number field object: addr=%p, ft-addr=%p", floating_point, type); } else { @@ -593,31 +950,29 @@ struct bt_field *bt_field_floating_point_create(struct bt_field_type *type) return (void *) floating_point; } -BT_HIDDEN -int bt_field_common_structure_initialize(struct bt_field_common *field, - struct bt_field_type_common *type, - bt_object_release_func release_func, - struct bt_field_common_methods *methods, - bt_field_common_create_func field_create_func) +static inline +int bt_field_structure_initialize(struct bt_field *field, + struct bt_field_type *type, + struct bt_field_methods *methods, + bt_field_create_func field_create_func, + GDestroyNotify field_release_func) { int ret = 0; - struct bt_field_type_common_structure *structure_type = - BT_FROM_COMMON(type); - struct bt_field_common_structure *structure = BT_FROM_COMMON(field); + struct bt_field_type_structure *structure_type = (void *) type; + struct bt_field_structure *structure = (void *) field; size_t i; - BT_LOGD("Initializing common structure field object: ft-addr=%p", type); - bt_field_common_initialize(field, type, release_func, methods); - structure->fields = g_ptr_array_new_with_free_func( - (GDestroyNotify) bt_put); + BT_LOGD("Initializing structure field object: ft-addr=%p", type); + bt_field_initialize(field, type, 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 by the structure field. */ + /* Create all fields contained in the structure field. */ for (i = 0; i < structure_type->fields->len; i++) { - struct bt_field_common *field; - struct structure_field_common *struct_field = - g_ptr_array_index(structure_type->fields, i); - + struct bt_field *field; + struct bt_field_type_structure_field *struct_field = + BT_FIELD_TYPE_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", @@ -629,7 +984,7 @@ int bt_field_common_structure_initialize(struct bt_field_common *field, g_ptr_array_index(structure->fields, i) = field; } - BT_LOGD("Initialized common structure field object: addr=%p, ft-addr=%p", + BT_LOGD("Initialized structure field object: addr=%p, ft-addr=%p", field, type); end: @@ -639,8 +994,8 @@ end: static struct bt_field *bt_field_structure_create(struct bt_field_type *type) { - struct bt_field_common_structure *structure = g_new0( - struct bt_field_common_structure, 1); + struct bt_field_structure *structure = g_new0( + struct bt_field_structure, 1); int iret; BT_LOGD("Creating structure field object: ft-addr=%p", type); @@ -650,10 +1005,10 @@ struct bt_field *bt_field_structure_create(struct bt_field_type *type) goto end; } - iret = bt_field_common_structure_initialize(BT_TO_COMMON(structure), - (void *) type, bt_field_common_structure_destroy_recursive, - &bt_field_structure_methods, - (bt_field_common_create_func) bt_field_create); + iret = bt_field_structure_initialize((void *) structure, + (void *) type, &bt_field_structure_methods, + (bt_field_create_func) bt_field_create_recursive, + (GDestroyNotify) bt_field_destroy_recursive); if (iret) { BT_PUT(structure); goto end; @@ -666,42 +1021,125 @@ end: return (void *) structure; } +static inline +int bt_field_variant_initialize(struct bt_field *field, + struct bt_field_type *type, + struct bt_field_methods *methods, + bt_field_create_func field_create_func, + GDestroyNotify field_release_func) +{ + int ret = 0; + struct bt_field_type_variant *variant_type = (void *) type; + struct bt_field_variant *variant = (void *) field; + size_t i; + + BT_LOGD("Initializing variant field object: ft-addr=%p", type); + bt_field_initialize(field, type, methods); + ret = bt_field_type_variant_update_choices(type); + if (ret) { + BT_LOGE("Cannot update 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_field *field; + struct bt_field_type_variant_choice *var_choice = + BT_FIELD_TYPE_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 variant field object: addr=%p, ft-addr=%p", + field, type); + +end: + return ret; +} + +static inline +int bt_field_string_initialize(struct bt_field *field, + struct bt_field_type *type, + struct bt_field_methods *methods) +{ + int ret = 0; + struct bt_field_string *string = (void *) field; + + BT_LOGD("Initializing string field object: ft-addr=%p", type); + bt_field_initialize(field, type, 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 string field object: addr=%p, ft-addr=%p", + field, type); + +end: + return ret; +} + static struct bt_field *bt_field_variant_create(struct bt_field_type *type) { - struct bt_field_common_variant *variant = g_new0( - struct bt_field_common_variant, 1); + struct bt_field_variant *variant = g_new0( + struct bt_field_variant, 1); + int iret; BT_LOGD("Creating 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_field_variant_methods); - BT_LOGD("Created variant field object: addr=%p, ft-addr=%p", - variant, type); - } else { + if (!variant) { BT_LOGE_STR("Failed to allocate one variant field."); + goto end; + } + + iret = bt_field_variant_initialize((void *) variant, + (void *) type, &bt_field_variant_methods, + (bt_field_create_func) bt_field_create_recursive, + (GDestroyNotify) bt_field_destroy_recursive); + if (iret) { + BT_PUT(variant); + goto end; } + BT_LOGD("Created variant field object: addr=%p, ft-addr=%p", + variant, type); + +end: return (void *) variant; } -BT_HIDDEN -int bt_field_common_array_initialize(struct bt_field_common *field, - struct bt_field_type_common *type, - bt_object_release_func release_func, - struct bt_field_common_methods *methods) +static inline +int bt_field_array_initialize(struct bt_field *field, + struct bt_field_type *type, + struct bt_field_methods *methods, + bt_field_create_func field_create_func, + GDestroyNotify field_destroy_func) { - struct bt_field_type_common_array *array_type = BT_FROM_COMMON(type); - struct bt_field_common_array *array = BT_FROM_COMMON(field); + struct bt_field_type_array *array_type = (void *) type; + struct bt_field_array *array = (void *) field; unsigned int array_length; int ret = 0; + uint64_t i; - BT_LOGD("Initializing common array field object: ft-addr=%p", type); + BT_LOGD("Initializing array field object: ft-addr=%p", type); BT_ASSERT(type); - bt_field_common_initialize(field, type, release_func, methods); + bt_field_initialize(field, type, methods); array_length = array_type->length; array->elements = g_ptr_array_sized_new(array_length); if (!array->elements) { @@ -709,9 +1147,19 @@ int bt_field_common_array_initialize(struct bt_field_common *field, goto end; } - g_ptr_array_set_free_func(array->elements, (GDestroyNotify) bt_put); + g_ptr_array_set_free_func(array->elements, field_destroy_func); g_ptr_array_set_size(array->elements, array_length); - BT_LOGD("Initialized common array field object: addr=%p, ft-addr=%p", + + 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 array field object: addr=%p, ft-addr=%p", field, type); end: @@ -721,8 +1169,8 @@ end: static struct bt_field *bt_field_array_create(struct bt_field_type *type) { - struct bt_field_common_array *array = - g_new0(struct bt_field_common_array, 1); + struct bt_field_array *array = + g_new0(struct bt_field_array, 1); int ret; BT_LOGD("Creating array field object: ft-addr=%p", type); @@ -733,10 +1181,10 @@ struct bt_field *bt_field_array_create(struct bt_field_type *type) goto end; } - ret = bt_field_common_array_initialize(BT_TO_COMMON(array), - (void *) type, - bt_field_common_array_destroy_recursive, - &bt_field_array_methods); + ret = bt_field_array_initialize((void *) array, + (void *) type, &bt_field_array_methods, + (bt_field_create_func) bt_field_create_recursive, + (GDestroyNotify) bt_field_destroy_recursive); if (ret) { BT_PUT(array); goto end; @@ -749,41 +1197,73 @@ end: return (void *) array; } -static -struct bt_field *bt_field_sequence_create(struct bt_field_type *type) +static inline +int bt_field_sequence_initialize(struct bt_field *field, + struct bt_field_type *type, + struct bt_field_methods *methods, + GDestroyNotify field_destroy_func) { - struct bt_field_common_sequence *sequence = g_new0( - struct bt_field_common_sequence, 1); + struct bt_field_sequence *sequence = (void *) field; + int ret = 0; - BT_LOGD("Creating sequence field object: ft-addr=%p", type); + BT_LOGD("Initializing sequence field object: ft-addr=%p", type); + BT_ASSERT(type); + bt_field_initialize(field, type, methods); + sequence->elements = g_ptr_array_new(); + if (!sequence->elements) { + ret = -1; + goto end; + } - if (sequence) { - bt_field_common_initialize(BT_TO_COMMON(sequence), - (void *) type, - bt_field_common_sequence_destroy_recursive, - &bt_field_sequence_methods); - BT_LOGD("Created sequence field object: addr=%p, ft-addr=%p", - sequence, type); - } else { + g_ptr_array_set_free_func(sequence->elements, field_destroy_func); + BT_LOGD("Initialized sequence field object: addr=%p, ft-addr=%p", + field, type); + +end: + return ret; +} + +static +struct bt_field *bt_field_sequence_create(struct bt_field_type *type) +{ + struct bt_field_sequence *sequence = + g_new0(struct bt_field_sequence, 1); + int ret; + + BT_LOGD("Creating sequence field object: ft-addr=%p", type); + BT_ASSERT(type); + + if (!sequence) { BT_LOGE_STR("Failed to allocate one sequence field."); + goto end; } + ret = bt_field_sequence_initialize((void *) sequence, + (void *) type, &bt_field_sequence_methods, + (GDestroyNotify) bt_field_destroy_recursive); + if (ret) { + BT_PUT(sequence); + goto end; + } + + BT_LOGD("Created sequence field object: addr=%p, ft-addr=%p", + sequence, type); + +end: return (void *) sequence; } static struct bt_field *bt_field_string_create(struct bt_field_type *type) { - struct bt_field_common_string *string = g_new0( - struct bt_field_common_string, 1); + struct bt_field_string *string = g_new0( + struct bt_field_string, 1); BT_LOGD("Creating string field object: ft-addr=%p", type); if (string) { - bt_field_common_initialize(BT_TO_COMMON(string), - (void *) type, - bt_field_common_string_destroy, - &bt_field_string_methods); + bt_field_string_initialize((void *) string, + (void *) type, &bt_field_string_methods); BT_LOGD("Created string field object: addr=%p, ft-addr=%p", string, type); } else { @@ -793,57 +1273,35 @@ struct bt_field *bt_field_string_create(struct bt_field_type *type) return (void *) string; } -BT_HIDDEN -int bt_field_common_generic_validate(struct bt_field_common *field) +static +int bt_field_generic_validate(struct bt_field *field) { return (field && field->payload_set) ? 0 : -1; } -BT_HIDDEN -int bt_field_common_enumeration_validate_recursive( - struct bt_field_common *field) -{ - int ret; - struct bt_field_common_enumeration *enumeration = BT_FROM_COMMON(field); - - BT_ASSERT(field); - - if (!enumeration->payload) { - BT_ASSERT_PRE_MSG("Invalid enumeration field: payload is not set: " - "%!+_f", field); - ret = -1; - goto end; - } - - ret = bt_field_common_validate_recursive(enumeration->payload); - -end: - return ret; -} - -BT_HIDDEN -int bt_field_common_structure_validate_recursive(struct bt_field_common *field) +static +int bt_field_structure_validate_recursive(struct bt_field *field) { int64_t i; int ret = 0; - struct bt_field_common_structure *structure = BT_FROM_COMMON(field); + struct bt_field_structure *structure = (void *) field; BT_ASSERT(field); for (i = 0; i < structure->fields->len; i++) { - ret = bt_field_common_validate_recursive( + ret = bt_field_validate_recursive( (void *) structure->fields->pdata[i]); if (ret) { int this_ret; const char *name; - this_ret = bt_field_type_common_structure_borrow_field_by_index( + this_ret = bt_field_type_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-]+_f, field-name=\"%s\", " - "index=%" PRId64 ", %![field-]+_f", + "%![struct-field-]+f, field-name=\"%s\", " + "index=%" PRId64 ", %![field-]+f", field, name, i, structure->fields->pdata[i]); goto end; } @@ -853,38 +1311,40 @@ end: return ret; } -BT_HIDDEN -int bt_field_common_variant_validate_recursive(struct bt_field_common *field) +static +int bt_field_variant_validate_recursive(struct bt_field *field) { int ret = 0; - struct bt_field_common_variant *variant = BT_FROM_COMMON(field); + struct bt_field_variant *variant = (void *) field; BT_ASSERT(field); - ret = bt_field_common_validate_recursive(variant->payload); - if (ret) { - BT_ASSERT_PRE_MSG("Invalid variant field's payload field: " - "%![variant-field-]+_f, %![payload-field-]+_f", - field, variant->payload); + + if (!variant->current_field) { + ret = -1; + goto end; } + ret = bt_field_validate_recursive(variant->current_field); + +end: return ret; } -BT_HIDDEN -int bt_field_common_array_validate_recursive(struct bt_field_common *field) +static +int bt_field_array_validate_recursive(struct bt_field *field) { int64_t i; int ret = 0; - struct bt_field_common_array *array = BT_FROM_COMMON(field); + struct bt_field_array *array = (void *) field; BT_ASSERT(field); for (i = 0; i < array->elements->len; i++) { - ret = bt_field_common_validate_recursive((void *) array->elements->pdata[i]); + ret = bt_field_validate_recursive((void *) array->elements->pdata[i]); if (ret) { BT_ASSERT_PRE_MSG("Invalid array field's element field: " - "%![array-field-]+_f, " PRId64 ", " - "%![elem-field-]+_f", + "%![array-field-]+f, " PRId64 ", " + "%![elem-field-]+f", field, i, array->elements->pdata[i]); goto end; } @@ -894,22 +1354,22 @@ end: return ret; } -BT_HIDDEN -int bt_field_common_sequence_validate_recursive(struct bt_field_common *field) +static +int bt_field_sequence_validate_recursive(struct bt_field *field) { size_t i; int ret = 0; - struct bt_field_common_sequence *sequence = BT_FROM_COMMON(field); + struct bt_field_sequence *sequence = (void *) field; BT_ASSERT(field); for (i = 0; i < sequence->elements->len; i++) { - ret = bt_field_common_validate_recursive( + ret = bt_field_validate_recursive( (void *) sequence->elements->pdata[i]); if (ret) { BT_ASSERT_PRE_MSG("Invalid sequence field's element field: " - "%![seq-field-]+_f, " PRId64 ", " - "%![elem-field-]+_f", + "%![seq-field-]+f, " PRId64 ", " + "%![elem-field-]+f", field, i, sequence->elements->pdata[i]); goto end; } @@ -918,37 +1378,23 @@ end: return ret; } -BT_HIDDEN -void bt_field_common_generic_reset(struct bt_field_common *field) +static +void bt_field_generic_reset(struct bt_field *field) { BT_ASSERT(field); field->payload_set = false; } -BT_HIDDEN -void bt_field_common_enumeration_reset_recursive(struct bt_field_common *field) -{ - struct bt_field_common_enumeration *enumeration = BT_FROM_COMMON(field); - - BT_ASSERT(field); - - if (!enumeration->payload) { - return; - } - - bt_field_common_reset_recursive(enumeration->payload); -} - -BT_HIDDEN -void bt_field_common_structure_reset_recursive(struct bt_field_common *field) +static +void bt_field_structure_reset_recursive(struct bt_field *field) { int64_t i; - struct bt_field_common_structure *structure = BT_FROM_COMMON(field); + struct bt_field_structure *structure = (void *) field; BT_ASSERT(field); for (i = 0; i < structure->fields->len; i++) { - struct bt_field_common *member = structure->fields->pdata[i]; + struct bt_field *member = structure->fields->pdata[i]; if (!member) { /* @@ -959,30 +1405,29 @@ void bt_field_common_structure_reset_recursive(struct bt_field_common *field) continue; } - bt_field_common_reset_recursive(member); + bt_field_reset_recursive(member); } } -BT_HIDDEN -void bt_field_common_variant_reset_recursive(struct bt_field_common *field) +static +void bt_field_variant_reset_recursive(struct bt_field *field) { - struct bt_field_common_variant *variant = BT_FROM_COMMON(field); + struct bt_field_variant *variant = (void *) field; BT_ASSERT(field); - BT_PUT(variant->tag); - BT_PUT(variant->payload); + variant->current_field = NULL; } -BT_HIDDEN -void bt_field_common_array_reset_recursive(struct bt_field_common *field) +static +void bt_field_array_reset_recursive(struct bt_field *field) { size_t i; - struct bt_field_common_array *array = BT_FROM_COMMON(field); + struct bt_field_array *array = (void *) field; BT_ASSERT(field); for (i = 0; i < array->elements->len; i++) { - struct bt_field_common *member = array->elements->pdata[i]; + struct bt_field *member = array->elements->pdata[i]; if (!member) { /* @@ -992,500 +1437,158 @@ void bt_field_common_array_reset_recursive(struct bt_field_common *field) continue; } - bt_field_common_reset_recursive(member); - } -} - -BT_HIDDEN -void bt_field_common_sequence_reset_recursive(struct bt_field_common *field) -{ - struct bt_field_common_sequence *sequence = BT_FROM_COMMON(field); - - BT_ASSERT(field); - - if (sequence->elements) { - g_ptr_array_free(sequence->elements, TRUE); - sequence->elements = NULL; - } - - BT_PUT(sequence->length); -} - -BT_HIDDEN -void bt_field_common_string_reset(struct bt_field_common *field) -{ - struct bt_field_common_string *string = BT_FROM_COMMON(field); - - BT_ASSERT(field); - bt_field_common_generic_reset(field); - - if (string->payload) { - g_string_truncate(string->payload, 0); - } -} - -static -struct bt_field_common *bt_field_integer_copy(struct bt_field_common *src) -{ - struct bt_field_common_integer *integer_src = (void *) src; - struct bt_field_common_integer *integer_dst; - - BT_LOGD("Copying integer field: src-field-addr=%p", src); - integer_dst = (void *) bt_field_create((void *) src->type); - if (!integer_dst) { - goto end; - } - - integer_dst->payload = integer_src->payload; - BT_LOGD_STR("Copied integer field."); - -end: - return BT_TO_COMMON(integer_dst); -} - -static -struct bt_field_common *bt_field_enumeration_copy_recursive( - struct bt_field_common *src) -{ - struct bt_field_common_enumeration *enum_src = BT_FROM_COMMON(src); - struct bt_field_common_enumeration *enum_dst; - - BT_LOGD("Copying enumeration field: src-field-addr=%p", src); - enum_dst = (void *) bt_field_create((void *) src->type); - if (!enum_dst) { - goto error; - } - - if (enum_src->payload) { - BT_LOGD_STR("Copying enumeration field's payload field."); - enum_dst->payload = (void *) - bt_field_copy((void *) enum_src->payload); - if (!enum_dst->payload) { - BT_LOGE_STR("Cannot copy enumeration field's payload field."); - goto error; - } - } - - BT_LOGD_STR("Copied enumeration field."); - goto end; - -error: - BT_PUT(enum_dst); - -end: - return BT_TO_COMMON(enum_dst); -} - -static -struct bt_field_common *bt_field_floating_point_copy( - struct bt_field_common *src) -{ - struct bt_field_common_floating_point *float_src = BT_FROM_COMMON(src); - struct bt_field_common_floating_point *float_dst; - - BT_LOGD("Copying floating point number field: src-field-addr=%p", src); - float_dst = (void *) bt_field_create((void *) src->type); - if (!float_dst) { - goto end; + bt_field_reset_recursive(member); } - - float_dst->payload = float_src->payload; - BT_LOGD_STR("Copied floating point number field."); - -end: - return BT_TO_COMMON(float_dst); } static -struct bt_field_common *bt_field_structure_copy_recursive( - struct bt_field_common *src) +void bt_field_sequence_reset_recursive(struct bt_field *field) { - int64_t i; - struct bt_field_common_structure *struct_src = BT_FROM_COMMON(src); - struct bt_field_common_structure *struct_dst; + struct bt_field_sequence *sequence = (void *) field; + uint64_t i; - BT_LOGD("Copying structure field: src-field-addr=%p", src); - struct_dst = (void *) bt_field_create((void *) src->type); - if (!struct_dst) { - goto error; - } + BT_ASSERT(field); - g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len); - - for (i = 0; i < struct_src->fields->len; i++) { - struct bt_field_common *field = - g_ptr_array_index(struct_src->fields, i); - struct bt_field_common *field_copy = NULL; - - if (field) { - BT_LOGD("Copying structure field's field: src-field-addr=%p" - "index=%" PRId64, field, i); - field_copy = (void *) bt_field_copy((void *) field); - if (!field_copy) { - BT_LOGE("Cannot copy structure field's field: " - "src-field-addr=%p, index=%" PRId64, - field, i); - goto error; - } + for (i = 0; i < sequence->elements->len; i++) { + if (sequence->elements->pdata[i]) { + bt_field_reset_recursive( + sequence->elements->pdata[i]); } - - BT_MOVE(g_ptr_array_index(struct_dst->fields, i), field_copy); } - BT_LOGD_STR("Copied structure field."); - goto end; - -error: - BT_PUT(struct_dst); - -end: - return BT_TO_COMMON(struct_dst); + sequence->length = 0; } static -struct bt_field_common *bt_field_variant_copy_recursive( - struct bt_field_common *src) +void bt_field_generic_set_is_frozen(struct bt_field *field, + bool is_frozen) { - struct bt_field_common_variant *variant_src = BT_FROM_COMMON(src); - struct bt_field_common_variant *variant_dst; - - BT_LOGD("Copying variant field: src-field-addr=%p", src); - variant_dst = (void *) bt_field_create((void *) src->type); - if (!variant_dst) { - goto end; - } - - if (variant_src->tag) { - BT_LOGD_STR("Copying variant field's tag field."); - variant_dst->tag = (void *) bt_field_copy( - (void *) variant_src->tag); - if (!variant_dst->tag) { - BT_LOGE_STR("Cannot copy variant field's tag field."); - goto error; - } - } - if (variant_src->payload) { - BT_LOGD_STR("Copying variant field's payload field."); - variant_dst->payload = (void *) bt_field_copy( - (void *) variant_src->payload); - if (!variant_dst->payload) { - BT_LOGE_STR("Cannot copy variant field's payload field."); - goto error; - } - } - - BT_LOGD_STR("Copied variant field."); - goto end; - -error: - BT_PUT(variant_dst); - -end: - return BT_TO_COMMON(variant_dst); + field->frozen = is_frozen; } static -struct bt_field_common *bt_field_array_copy_recursive( - struct bt_field_common *src) +void bt_field_structure_set_is_frozen_recursive( + struct bt_field *field, bool is_frozen) { - int64_t i; - struct bt_field_common_array *array_src = BT_FROM_COMMON(src); - struct bt_field_common_array *array_dst; + uint64_t i; + struct bt_field_structure *structure_field = (void *) field; - BT_LOGD("Copying array field: src-field-addr=%p", src); - array_dst = (void *) bt_field_create((void *) src->type); - if (!array_dst) { - goto error; - } + BT_LOGD("Freezing structure field object: addr=%p", field); - g_ptr_array_set_size(array_dst->elements, array_src->elements->len); - for (i = 0; i < array_src->elements->len; i++) { - struct bt_field_common *field = - g_ptr_array_index(array_src->elements, i); - struct bt_field_common *field_copy = NULL; - - if (field) { - BT_LOGD("Copying array field's element field: field-addr=%p, " - "index=%" PRId64, field, i); - field_copy = (void *) bt_field_copy((void *) field); - if (!field_copy) { - BT_LOGE("Cannot copy array field's element field: " - "src-field-addr=%p, index=%" PRId64, - field, i); - goto error; - } - } + for (i = 0; i < structure_field->fields->len; i++) { + struct bt_field *struct_field = + g_ptr_array_index(structure_field->fields, i); - g_ptr_array_index(array_dst->elements, i) = field_copy; + BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64, + struct_field, i); + bt_field_set_is_frozen_recursive(struct_field, + is_frozen); } - BT_LOGD_STR("Copied array field."); - goto end; - -error: - BT_PUT(array_dst); - -end: - return BT_TO_COMMON(array_dst); + bt_field_generic_set_is_frozen(field, is_frozen); } static -struct bt_field_common *bt_field_sequence_copy_recursive( - struct bt_field_common *src) +void bt_field_variant_set_is_frozen_recursive( + struct bt_field *field, bool is_frozen) { - int ret = 0; - int64_t i; - struct bt_field_common_sequence *sequence_src = BT_FROM_COMMON(src); - struct bt_field_common_sequence *sequence_dst; - struct bt_field_common *src_length; - struct bt_field_common *dst_length; - - BT_LOGD("Copying sequence field: src-field-addr=%p", src); - sequence_dst = (void *) bt_field_create((void *) src->type); - if (!sequence_dst) { - goto error; - } + uint64_t i; + struct bt_field_variant *variant_field = (void *) field; - src_length = bt_field_common_sequence_borrow_length(src); - if (!src_length) { - /* no length set yet: keep destination sequence empty */ - goto end; - } - - /* copy source length */ - BT_LOGD_STR("Copying sequence field's length field."); - dst_length = (void *) bt_field_copy((void *) src_length); - if (!dst_length) { - BT_LOGE_STR("Cannot copy sequence field's length field."); - goto error; - } - - /* this will initialize the destination sequence's internal array */ - ret = bt_field_common_sequence_set_length( - BT_TO_COMMON(sequence_dst), dst_length); - bt_put(dst_length); - if (ret) { - BT_LOGE("Cannot set sequence field copy's length field: " - "dst-length-field-addr=%p", dst_length); - goto error; - } + BT_LOGD("Freezing variant field object: addr=%p", field); - BT_ASSERT(sequence_dst->elements->len == sequence_src->elements->len); - - for (i = 0; i < sequence_src->elements->len; i++) { - struct bt_field_common *field = - g_ptr_array_index(sequence_src->elements, i); - struct bt_field_common *field_copy = NULL; - - if (field) { - BT_LOGD("Copying sequence field's element field: field-addr=%p, " - "index=%" PRId64, field, i); - field_copy = (void *) bt_field_copy((void *) field); - if (!field_copy) { - BT_LOGE("Cannot copy sequence field's element field: " - "src-field-addr=%p, index=%" PRId64, - field, i); - goto error; - } - } + for (i = 0; i < variant_field->fields->len; i++) { + struct bt_field *var_field = + g_ptr_array_index(variant_field->fields, i); - g_ptr_array_index(sequence_dst->elements, i) = field_copy; + BT_LOGD("Freezing variant field's field: field-addr=%p, index=%" PRId64, + var_field, i); + bt_field_set_is_frozen_recursive(var_field, is_frozen); } - BT_LOGD_STR("Copied sequence field."); - goto end; - -error: - BT_PUT(sequence_dst); - -end: - return BT_TO_COMMON(sequence_dst); + bt_field_generic_set_is_frozen(field, is_frozen); } static -struct bt_field_common *bt_field_string_copy(struct bt_field_common *src) -{ - struct bt_field_common_string *string_src = BT_FROM_COMMON(src); - struct bt_field_common_string *string_dst; - - BT_LOGD("Copying string field: src-field-addr=%p", src); - string_dst = (void *) bt_field_create((void *) src->type); - if (!string_dst) { - goto error; - } - - if (string_src->payload) { - string_dst->payload = g_string_new(string_src->payload->str); - if (!string_dst->payload) { - BT_LOGE_STR("Failed to allocate a GString."); - goto error; - } - } - - BT_LOGD_STR("Copied string field."); - goto end; - -error: - BT_PUT(string_dst); - -end: - return BT_TO_COMMON(string_dst); -} - -BT_HIDDEN -void bt_field_common_generic_freeze(struct bt_field_common *field) -{ - field->frozen = true; -} - -BT_HIDDEN -void bt_field_common_enumeration_freeze_recursive(struct bt_field_common *field) -{ - struct bt_field_common_enumeration *enum_field = BT_FROM_COMMON(field); - - BT_LOGD("Freezing enumeration field object: addr=%p", field); - BT_LOGD("Freezing enumeration field object's contained payload field: payload-field-addr=%p", enum_field->payload); - bt_field_common_freeze_recursive(enum_field->payload); - bt_field_common_generic_freeze(field); -} - -BT_HIDDEN -void bt_field_common_structure_freeze_recursive(struct bt_field_common *field) +void bt_field_array_set_is_frozen_recursive( + struct bt_field *field, bool is_frozen) { int64_t i; - struct bt_field_common_structure *structure_field = - BT_FROM_COMMON(field); - - BT_LOGD("Freezing structure field object: addr=%p", field); - - for (i = 0; i < structure_field->fields->len; i++) { - struct bt_field_common *field = - g_ptr_array_index(structure_field->fields, i); - - BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64, - field, i); - bt_field_common_freeze_recursive(field); - } - - bt_field_common_generic_freeze(field); -} - -BT_HIDDEN -void bt_field_common_variant_freeze_recursive(struct bt_field_common *field) -{ - struct bt_field_common_variant *variant_field = BT_FROM_COMMON(field); - - BT_LOGD("Freezing variant field object: addr=%p", field); - BT_LOGD("Freezing variant field object's tag field: tag-field-addr=%p", variant_field->tag); - bt_field_common_freeze_recursive(variant_field->tag); - BT_LOGD("Freezing variant field object's payload field: payload-field-addr=%p", variant_field->payload); - bt_field_common_freeze_recursive(variant_field->payload); - bt_field_common_generic_freeze(field); -} - -BT_HIDDEN -void bt_field_common_array_freeze_recursive(struct bt_field_common *field) -{ - int64_t i; - struct bt_field_common_array *array_field = BT_FROM_COMMON(field); + struct bt_field_array *array_field = (void *) field; BT_LOGD("Freezing array field object: addr=%p", field); for (i = 0; i < array_field->elements->len; i++) { - struct bt_field_common *elem_field = + struct bt_field *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_field_common_freeze_recursive(elem_field); + bt_field_set_is_frozen_recursive(elem_field, is_frozen); } - bt_field_common_generic_freeze(field); + bt_field_generic_set_is_frozen(field, is_frozen); } -BT_HIDDEN -void bt_field_common_sequence_freeze_recursive(struct bt_field_common *field) +static +void bt_field_sequence_set_is_frozen_recursive( + struct bt_field *field, bool is_frozen) { int64_t i; - struct bt_field_common_sequence *sequence_field = - BT_FROM_COMMON(field); + struct bt_field_sequence *sequence_field = (void *) field; BT_LOGD("Freezing sequence field object: addr=%p", field); - BT_LOGD("Freezing sequence field object's length field: length-field-addr=%p", - sequence_field->length); - bt_field_common_freeze_recursive(sequence_field->length); - for (i = 0; i < sequence_field->elements->len; i++) { - struct bt_field_common *elem_field = + for (i = 0; i < sequence_field->length; i++) { + struct bt_field *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_field_common_freeze_recursive(elem_field); + bt_field_set_is_frozen_recursive(elem_field, is_frozen); } - bt_field_common_generic_freeze(field); + bt_field_generic_set_is_frozen(field, is_frozen); } BT_HIDDEN -void _bt_field_common_freeze_recursive(struct bt_field_common *field) +void _bt_field_set_is_frozen_recursive(struct bt_field *field, + bool is_frozen) { if (!field) { goto end; } - if (field->frozen) { - goto end; - } - - BT_LOGD("Freezing field object: addr=%p", field); - BT_ASSERT(field_type_common_has_known_id(field->type)); - BT_ASSERT(field->methods->freeze); - field->methods->freeze(field); + BT_LOGD("Setting field object's frozen state: addr=%p, is-frozen=%d", + field, is_frozen); + BT_ASSERT(bt_field_type_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_field_common_generic_is_set(struct bt_field_common *field) +static +bt_bool bt_field_generic_is_set(struct bt_field *field) { return field && field->payload_set; } -BT_HIDDEN -bt_bool bt_field_common_enumeration_is_set_recursive( - struct bt_field_common *field) -{ - bt_bool is_set = BT_FALSE; - struct bt_field_common_enumeration *enumeration = BT_FROM_COMMON(field); - - BT_ASSERT(field); - - if (!enumeration->payload) { - goto end; - } - - is_set = bt_field_common_is_set_recursive(enumeration->payload); - -end: - return is_set; -} - -BT_HIDDEN -bt_bool bt_field_common_structure_is_set_recursive( - struct bt_field_common *field) +static +bt_bool bt_field_structure_is_set_recursive( + struct bt_field *field) { bt_bool is_set = BT_FALSE; size_t i; - struct bt_field_common_structure *structure = BT_FROM_COMMON(field); + struct bt_field_structure *structure = (void *) field; BT_ASSERT(field); for (i = 0; i < structure->fields->len; i++) { - is_set = bt_field_common_is_set_recursive( + is_set = bt_field_is_set_recursive( structure->fields->pdata[i]); if (!is_set) { goto end; @@ -1496,26 +1599,33 @@ end: return is_set; } -BT_HIDDEN -bt_bool bt_field_common_variant_is_set_recursive(struct bt_field_common *field) +static +bt_bool bt_field_variant_is_set_recursive(struct bt_field *field) { - struct bt_field_common_variant *variant = BT_FROM_COMMON(field); + struct bt_field_variant *variant = (void *) field; + bt_bool is_set = BT_FALSE; BT_ASSERT(field); - return bt_field_common_is_set_recursive(variant->payload); + + if (variant->current_field) { + is_set = bt_field_is_set_recursive( + variant->current_field); + } + + return is_set; } -BT_HIDDEN -bt_bool bt_field_common_array_is_set_recursive(struct bt_field_common *field) +static +bt_bool bt_field_array_is_set_recursive(struct bt_field *field) { size_t i; bt_bool is_set = BT_FALSE; - struct bt_field_common_array *array = BT_FROM_COMMON(field); + struct bt_field_array *array = (void *) field; BT_ASSERT(field); for (i = 0; i < array->elements->len; i++) { - is_set = bt_field_common_is_set_recursive(array->elements->pdata[i]); + is_set = bt_field_is_set_recursive(array->elements->pdata[i]); if (!is_set) { goto end; } @@ -1525,12 +1635,12 @@ end: return is_set; } -BT_HIDDEN -bt_bool bt_field_common_sequence_is_set_recursive(struct bt_field_common *field) +static +bt_bool bt_field_sequence_is_set_recursive(struct bt_field *field) { size_t i; bt_bool is_set = BT_FALSE; - struct bt_field_common_sequence *sequence = BT_FROM_COMMON(field); + struct bt_field_sequence *sequence = (void *) field; BT_ASSERT(field); @@ -1539,7 +1649,7 @@ bt_bool bt_field_common_sequence_is_set_recursive(struct bt_field_common *field) } for (i = 0; i < sequence->elements->len; i++) { - is_set = bt_field_common_is_set_recursive( + is_set = bt_field_is_set_recursive( sequence->elements->pdata[i]); if (!is_set) { goto end;