static
int bt_ctf_field_string_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+void generic_field_freeze(struct bt_ctf_field *);
+static
+void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *);
+static
+void bt_ctf_field_structure_freeze(struct bt_ctf_field *);
+static
+void bt_ctf_field_variant_freeze(struct bt_ctf_field *);
+static
+void bt_ctf_field_array_freeze(struct bt_ctf_field *);
+static
+void bt_ctf_field_sequence_freeze(struct bt_ctf_field *);
+
+static
+bool bt_ctf_field_generic_is_set(struct bt_ctf_field *);
+static
+bool bt_ctf_field_structure_is_set(struct bt_ctf_field *);
+static
+bool bt_ctf_field_variant_is_set(struct bt_ctf_field *);
+static
+bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *);
+static
+bool bt_ctf_field_array_is_set(struct bt_ctf_field *);
+static
+bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *);
+
static
int increase_packet_size(struct ctf_stream_pos *pos);
[BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_copy,
};
+static
+void (* const field_freeze_funcs[])(struct bt_ctf_field *) = {
+ [BT_CTF_TYPE_ID_INTEGER] = generic_field_freeze,
+ [BT_CTF_TYPE_ID_FLOAT] = generic_field_freeze,
+ [BT_CTF_TYPE_ID_STRING] = generic_field_freeze,
+ [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_freeze,
+ [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_freeze,
+ [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_freeze,
+ [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_freeze,
+ [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_freeze,
+};
+
+static
+bool (* const field_is_set_funcs[])(struct bt_ctf_field *) = {
+ [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_is_set,
+ [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_is_set,
+ [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_is_set,
+ [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_is_set,
+ [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_is_set,
+ [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_is_set,
+ [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_is_set,
+ [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_generic_is_set,
+};
+
struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type)
{
struct bt_ctf_field *field = NULL;
struct bt_ctf_field_sequence *sequence;
uint64_t sequence_length;
- if (!field || !length_field) {
+ if (!field || !length_field || field->frozen) {
ret = -1;
goto end;
}
goto end;
}
+ /* We don't want to modify this field if it's frozen */
+ if (field->frozen) {
+ goto end;
+ }
+
new_field = bt_ctf_field_create(field_type);
if (!new_field) {
goto error;
goto end;
}
+ /* We don't want to modify this field if it's frozen */
+ if (field->frozen) {
+ goto end;
+ }
+
/* Field has not been instanciated yet, create it */
structure_type = bt_ctf_field_get_type(field);
if (!structure_type) {
struct bt_ctf_field_type *expected_field_type = NULL;
size_t index;
- if (!field || !name || !value ||
+ if (!field || !name || !value || field->frozen ||
bt_ctf_field_type_get_type_id(field->type) !=
BT_CTF_TYPE_ID_STRUCT) {
ret = -1;
goto end;
}
+ /* We don't want to modify this field if it's frozen */
+ if (field->frozen) {
+ goto end;
+ }
+
new_field = bt_ctf_field_create(field_type);
array->elements->pdata[(size_t)index] = new_field;
end:
goto end;
}
+ /* We don't want to modify this field if it's frozen */
+ if (field->frozen) {
+ goto end;
+ }
+
new_field = bt_ctf_field_create(field_type);
sequence->elements->pdata[(size_t) index] = new_field;
end:
}
}
+ /* We don't want to modify this field if it's frozen */
+ if (field->frozen) {
+ goto end;
+ }
+
field_type = bt_ctf_field_type_variant_get_field_type_signed(
variant_type, tag_enum_value);
if (!field_type) {
return current_field;
}
+struct bt_ctf_field *bt_ctf_field_variant_get_tag(
+ struct bt_ctf_field *variant_field)
+{
+ struct bt_ctf_field *tag = NULL;
+ struct bt_ctf_field_variant *variant;
+
+ if (!variant_field ||
+ bt_ctf_field_type_get_type_id(variant_field->type) !=
+ BT_CTF_TYPE_ID_VARIANT) {
+ goto end;
+ }
+
+ variant = container_of(variant_field, struct bt_ctf_field_variant,
+ parent);
+ if (variant->tag) {
+ tag = bt_get(variant->tag);
+ }
+end:
+ return tag;
+}
+
struct bt_ctf_field *bt_ctf_field_enumeration_get_container(
struct bt_ctf_field *field)
{
enumeration = container_of(field, struct bt_ctf_field_enumeration,
parent);
if (!enumeration->payload) {
+ /* We don't want to modify this field if it's frozen */
+ if (field->frozen) {
+ goto end;
+ }
+
struct bt_ctf_field_type_enumeration *enumeration_type =
container_of(field->type,
struct bt_ctf_field_type_enumeration, parent);
unsigned int size;
int64_t min_value, max_value;
- if (!field ||
+ if (!field || field->frozen ||
bt_ctf_field_type_get_type_id(field->type) !=
BT_CTF_TYPE_ID_INTEGER) {
ret = -1;
}
size = integer_type->declaration.len;
- min_value = -((int64_t)1 << (size - 1));
- max_value = ((int64_t)1 << (size - 1)) - 1;
+ min_value = -(1ULL << (size - 1));
+ max_value = (1ULL << (size - 1)) - 1;
if (value < min_value || value > max_value) {
ret = -1;
goto end;
unsigned int size;
uint64_t max_value;
- if (!field ||
+ if (!field || field->frozen ||
bt_ctf_field_type_get_type_id(field->type) !=
BT_CTF_TYPE_ID_INTEGER) {
ret = -1;
}
size = integer_type->declaration.len;
- max_value = (size == 64) ? UINT64_MAX : ((uint64_t)1 << size) - 1;
+ max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
if (value > max_value) {
ret = -1;
goto end;
int ret = 0;
struct bt_ctf_field_floating_point *floating_point;
- if (!field ||
+ if (!field || field->frozen ||
bt_ctf_field_type_get_type_id(field->type) !=
BT_CTF_TYPE_ID_FLOAT) {
ret = -1;
int ret = 0;
struct bt_ctf_field_string *string;
- if (!field || !value ||
+ if (!field || !value || field->frozen ||
bt_ctf_field_type_get_type_id(field->type) !=
BT_CTF_TYPE_ID_STRING) {
ret = -1;
int ret = 0;
struct bt_ctf_field_string *string_field;
- if (!field || !value ||
+ if (!field || !value || field->frozen ||
bt_ctf_field_type_get_type_id(field->type) !=
BT_CTF_TYPE_ID_STRING) {
ret = -1;
unsigned int effective_length = length;
struct bt_ctf_field_string *string_field;
- if (!field || !value ||
+ if (!field || !value || field->frozen ||
bt_ctf_field_type_get_type_id(field->type) !=
BT_CTF_TYPE_ID_STRING) {
ret = -1;
return ret;
}
+
+BT_HIDDEN
+bool bt_ctf_field_is_set(struct bt_ctf_field *field)
+{
+ bool is_set = false;
+ enum bt_ctf_type_id type_id;
+
+ if (!field) {
+ goto end;
+ }
+
+ type_id = bt_ctf_field_type_get_type_id(field->type);
+ if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
+ goto end;
+ }
+
+ is_set = field_is_set_funcs[type_id](field);
+end:
+ return is_set;
+}
+
struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
{
int ret;
for (i = 0; i < structure->fields->len; i++) {
ret = bt_ctf_field_validate(structure->fields->pdata[i]);
if (ret) {
+ const char *name;
+ struct bt_ctf_field_type *field_type =
+ bt_ctf_field_get_type(field);
+
+ (void) bt_ctf_field_type_structure_get_field(field_type,
+ &name, NULL, i);
+ fprintf(stderr, "Field %s failed validation\n",
+ name ? name : "NULL");
+ bt_put(field_type);
goto end;
}
}
for (i = 0; i < array->elements->len; i++) {
ret = bt_ctf_field_validate(array->elements->pdata[i]);
if (ret) {
+ fprintf(stderr, "Failed to validate array field #%zu\n", i);
goto end;
}
}
for (i = 0; i < sequence->elements->len; i++) {
ret = bt_ctf_field_validate(sequence->elements->pdata[i]);
if (ret) {
+ fprintf(stderr, "Failed to validate sequence field #%zu\n", i);
goto end;
}
}
ret = bt_ctf_field_serialize(field, pos);
if (ret) {
+ const char *name;
+ struct bt_ctf_field_type *field_type =
+ bt_ctf_field_get_type(field);
+
+ (void) bt_ctf_field_type_structure_get_field(field_type,
+ &name, NULL, i);
+ fprintf(stderr, "Field %s failed to serialize\n",
+ name ? name : "NULL");
+ bt_put(field_type);
break;
}
}
ret = bt_ctf_field_serialize(
g_ptr_array_index(array->elements, i), pos);
if (ret) {
+ fprintf(stderr, "Failed to serialize array element #%zu\n", i);
goto end;
}
}
ret = bt_ctf_field_serialize(
g_ptr_array_index(sequence->elements, i), pos);
if (ret) {
+ fprintf(stderr, "Failed to serialize sequence element #%zu\n", i);
goto end;
}
}
end:
return ret;
}
+
+static
+void generic_field_freeze(struct bt_ctf_field *field)
+{
+ field->frozen = 1;
+}
+
+static
+void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *field)
+{
+ struct bt_ctf_field_enumeration *enum_field =
+ container_of(field, struct bt_ctf_field_enumeration, parent);
+
+ bt_ctf_field_freeze(enum_field->payload);
+ generic_field_freeze(field);
+}
+
+static
+void bt_ctf_field_structure_freeze(struct bt_ctf_field *field)
+{
+ int i;
+ struct bt_ctf_field_structure *structure_field =
+ container_of(field, struct bt_ctf_field_structure, parent);
+
+ for (i = 0; i < structure_field->fields->len; i++) {
+ struct bt_ctf_field *field =
+ g_ptr_array_index(structure_field->fields, i);
+
+ bt_ctf_field_freeze(field);
+ }
+
+ generic_field_freeze(field);
+}
+
+static
+void bt_ctf_field_variant_freeze(struct bt_ctf_field *field)
+{
+ struct bt_ctf_field_variant *variant_field =
+ container_of(field, struct bt_ctf_field_variant, parent);
+
+ bt_ctf_field_freeze(variant_field->tag);
+ bt_ctf_field_freeze(variant_field->payload);
+ generic_field_freeze(field);
+}
+
+static
+void bt_ctf_field_array_freeze(struct bt_ctf_field *field)
+{
+ int i;
+ struct bt_ctf_field_array *array_field =
+ container_of(field, struct bt_ctf_field_array, parent);
+
+ for (i = 0; i < array_field->elements->len; i++) {
+ struct bt_ctf_field *field =
+ g_ptr_array_index(array_field->elements, i);
+
+ bt_ctf_field_freeze(field);
+ }
+
+ generic_field_freeze(field);
+}
+
+static
+void bt_ctf_field_sequence_freeze(struct bt_ctf_field *field)
+{
+ int i;
+ struct bt_ctf_field_sequence *sequence_field =
+ container_of(field, struct bt_ctf_field_sequence, parent);
+
+ bt_ctf_field_freeze(sequence_field->length);
+
+ for (i = 0; i < sequence_field->elements->len; i++) {
+ struct bt_ctf_field *field =
+ g_ptr_array_index(sequence_field->elements, i);
+
+ bt_ctf_field_freeze(field);
+ }
+
+ generic_field_freeze(field);
+}
+
+BT_HIDDEN
+void bt_ctf_field_freeze(struct bt_ctf_field *field)
+{
+ enum bt_ctf_type_id type_id;
+
+ if (!field) {
+ goto end;
+ }
+
+ type_id = bt_ctf_field_get_type_id(field);
+ if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
+ type_id >= BT_CTF_NR_TYPE_IDS) {
+ goto end;
+ }
+
+ field_freeze_funcs[type_id](field);
+end:
+ return;
+}
+
+static
+bool bt_ctf_field_generic_is_set(struct bt_ctf_field *field)
+{
+ return field && field->payload_set;
+}
+
+static
+bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *field)
+{
+ bool is_set = false;
+ struct bt_ctf_field_enumeration *enumeration;
+
+ if (!field) {
+ goto end;
+ }
+
+ enumeration = container_of(field, struct bt_ctf_field_enumeration,
+ parent);
+ if (!enumeration->payload) {
+ goto end;
+ }
+
+ is_set = bt_ctf_field_is_set(enumeration->payload);
+end:
+ return is_set;
+}
+
+static
+bool bt_ctf_field_structure_is_set(struct bt_ctf_field *field)
+{
+ bool is_set = false;
+ size_t i;
+ struct bt_ctf_field_structure *structure;
+
+ if (!field) {
+ goto end;
+ }
+
+ structure = container_of(field, struct bt_ctf_field_structure, parent);
+ for (i = 0; i < structure->fields->len; i++) {
+ is_set = bt_ctf_field_is_set(structure->fields->pdata[i]);
+ if (!is_set) {
+ goto end;
+ }
+ }
+end:
+ return is_set;
+}
+
+static
+bool bt_ctf_field_variant_is_set(struct bt_ctf_field *field)
+{
+ bool is_set = false;
+ struct bt_ctf_field_variant *variant;
+
+ if (!field) {
+ goto end;
+ }
+
+ variant = container_of(field, struct bt_ctf_field_variant, parent);
+ is_set = bt_ctf_field_is_set(variant->payload);
+end:
+ return is_set;
+}
+
+static
+bool bt_ctf_field_array_is_set(struct bt_ctf_field *field)
+{
+ size_t i;
+ bool is_set = false;
+ struct bt_ctf_field_array *array;
+
+ if (!field) {
+ goto end;
+ }
+
+ array = container_of(field, struct bt_ctf_field_array, parent);
+ for (i = 0; i < array->elements->len; i++) {
+ is_set = bt_ctf_field_is_set(array->elements->pdata[i]);
+ if (!is_set) {
+ goto end;
+ }
+ }
+end:
+ return is_set;
+}
+
+static
+bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *field)
+{
+ size_t i;
+ bool is_set = false;
+ struct bt_ctf_field_sequence *sequence;
+
+ if (!field) {
+ goto end;
+ }
+
+ sequence = container_of(field, struct bt_ctf_field_sequence, parent);
+ for (i = 0; i < sequence->elements->len; i++) {
+ is_set = bt_ctf_field_validate(sequence->elements->pdata[i]);
+ if (!is_set) {
+ goto end;
+ }
+ }
+end:
+ return is_set;
+}