struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field, struct bt_ctf_field *tag_field) { struct bt_ctf_field *new_field = NULL; struct bt_ctf_field_variant *variant; struct bt_ctf_field_type_variant *variant_type; struct bt_ctf_field_type *field_type; struct bt_ctf_field *tag_enum = NULL; struct bt_ctf_field_integer *tag_enum_integer; int64_t tag_enum_value; if (!field || !tag_field || bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_VARIANT || bt_ctf_field_type_get_type_id(tag_field->type) != CTF_TYPE_ENUM) { goto end; } variant = container_of(field, struct bt_ctf_field_variant, parent); variant_type = container_of(field->type, struct bt_ctf_field_type_variant, parent); tag_enum = bt_ctf_field_enumeration_get_container(tag_field); if (!tag_enum) { goto end; } tag_enum_integer = container_of(tag_enum, struct bt_ctf_field_integer, parent); if (!bt_ctf_field_validate(variant->tag)) { goto end; } tag_enum_value = tag_enum_integer->definition.value._signed; field_type = bt_ctf_field_type_variant_get_field_type_signed( variant_type, tag_enum_value); if (!field_type) { goto end; } new_field = bt_ctf_field_create(field_type); if (!new_field) { goto end; } bt_ctf_field_put(variant->tag); bt_ctf_field_put(variant->payload); bt_ctf_field_get(new_field); bt_ctf_field_get(tag_field); variant->tag = tag_field; variant->payload = new_field; end: bt_ctf_field_put(tag_enum); return new_field; }
struct bt_ctf_field *bt_ctf_field_enumeration_get_container( struct bt_ctf_field *field) { struct bt_ctf_field *container = NULL; struct bt_ctf_field_enumeration *enumeration; if (!field || bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_ENUM) { goto end; } enumeration = container_of(field, struct bt_ctf_field_enumeration, parent); if (!enumeration->payload) { struct bt_ctf_field_type_enumeration *enumeration_type = container_of(field->type, struct bt_ctf_field_type_enumeration, parent); enumeration->payload = bt_ctf_field_create(enumeration_type->container); } container = enumeration->payload; bt_ctf_field_get(container); end: return container; }
struct bt_ctf_field *bt_ctf_field_sequence_get_field(struct bt_ctf_field *field, uint64_t index) { struct bt_ctf_field *new_field = NULL; struct bt_ctf_field_type *field_type = NULL; struct bt_ctf_field_sequence *sequence; if (!field || bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_SEQUENCE) { goto end; } sequence = container_of(field, struct bt_ctf_field_sequence, parent); if (!sequence->elements || sequence->elements->len <= index) { goto end; } field_type = bt_ctf_field_type_sequence_get_element_type(field->type); if (sequence->elements->pdata[(size_t)index]) { new_field = sequence->elements->pdata[(size_t)index]; goto end; } new_field = bt_ctf_field_create(field_type); bt_ctf_field_get(new_field); sequence->elements->pdata[(size_t)index] = new_field; end: if (field_type) { bt_ctf_field_type_put(field_type); } return new_field; }
struct bt_ctf_field_type *bt_ctf_event_class_get_field_by_name( struct bt_ctf_event_class *event_class, const char *name) { GQuark name_quark; struct bt_ctf_field_type *field_type = NULL; if (!event_class || !name) { goto end; } if (bt_ctf_field_type_get_type_id(event_class->fields) != CTF_TYPE_STRUCT) { goto end; } name_quark = g_quark_try_string(name); if (!name_quark) { goto end; } /* * No need to increment field_type's reference count since getting it * from the structure already does. */ field_type = bt_ctf_field_type_structure_get_field_type_by_name( event_class->fields, name); end: return field_type; }
struct bt_ctf_field *bt_ctf_field_array_get_field(struct bt_ctf_field *field, uint64_t index) { struct bt_ctf_field *new_field = NULL; struct bt_ctf_field_type *field_type = NULL; struct bt_ctf_field_array *array; if (!field || bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_ARRAY) { goto end; } array = container_of(field, struct bt_ctf_field_array, parent); if (index >= array->elements->len) { goto end; } field_type = bt_ctf_field_type_array_get_element_type(field->type); if (array->elements->pdata[(size_t)index]) { new_field = array->elements->pdata[(size_t)index]; goto end; } new_field = bt_ctf_field_create(field_type); bt_ctf_field_get(new_field); array->elements->pdata[(size_t)index] = new_field; end: if (field_type) { bt_ctf_field_type_put(field_type); } return new_field; }
struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type) { struct bt_ctf_field *field = NULL; enum ctf_type_id type_id; if (!type) { goto error; } type_id = bt_ctf_field_type_get_type_id(type); if (type_id <= CTF_TYPE_UNKNOWN || type_id >= NR_CTF_TYPES || bt_ctf_field_type_validate(type)) { goto error; } field = field_create_funcs[type_id](type); if (!field) { goto error; } /* The type's declaration can't change after this point */ bt_ctf_field_type_freeze(type); bt_ctf_field_type_get(type); bt_ctf_ref_init(&field->ref_count); field->type = type; error: return field; }
int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *field, uint64_t *value) { int ret = 0; struct bt_ctf_field_integer *integer; struct bt_ctf_field_type_integer *integer_type; if (!field || !value || !field->payload_set || bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_INTEGER) { ret = -1; goto end; } integer_type = container_of(field->type, struct bt_ctf_field_type_integer, parent); if (integer_type->declaration.signedness) { ret = -1; goto end; } integer = container_of(field, struct bt_ctf_field_integer, parent); *value = integer->definition.value._unsigned; end: return ret; }
BT_HIDDEN int bt_ctf_event_set_payload_field(struct bt_ctf_event *event, struct bt_ctf_field *payload) { int ret = 0; struct bt_ctf_field_type *payload_type = NULL; if (!event || !payload || event->frozen) { ret = -1; goto end; } payload_type = bt_ctf_field_get_type(payload); if (!payload_type) { ret = -1; goto end; } if (bt_ctf_field_type_get_type_id(payload_type) != CTF_TYPE_STRUCT) { ret = -1; goto end; } bt_get(payload); bt_put(event->fields_payload); event->fields_payload = payload; end: bt_put(payload_type); return ret; }
struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index( struct bt_ctf_field *field, size_t index) { int ret; const char *field_name; struct bt_ctf_field_structure *structure; struct bt_ctf_field_type *structure_type; struct bt_ctf_field_type *field_type = NULL; struct bt_ctf_field *ret_field = NULL; if (!field || bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_STRUCT) { goto end; } structure = container_of(field, struct bt_ctf_field_structure, parent); if (index >= structure->fields->len) { goto error; } ret_field = structure->fields->pdata[index]; if (ret_field) { goto end; } /* Field has not been instanciated yet, create it */ structure_type = bt_ctf_field_get_type(field); if (!structure_type) { goto error; } ret = bt_ctf_field_type_structure_get_field(structure_type, &field_name, &field_type, index); bt_ctf_field_type_put(structure_type); if (ret) { goto error; } ret_field = bt_ctf_field_create(field_type); if (!ret_field) { goto error; } structure->fields->pdata[index] = ret_field; end: bt_ctf_field_get(ret_field); error: if (field_type) { bt_ctf_field_type_put(field_type); } return ret_field; }
int bt_ctf_field_sequence_set_length(struct bt_ctf_field *field, struct bt_ctf_field *length_field) { int ret = 0; struct bt_ctf_field_type_integer *length_type; struct bt_ctf_field_integer *length; struct bt_ctf_field_sequence *sequence; uint64_t sequence_length; if (!field || !length_field) { ret = -1; goto end; } if (bt_ctf_field_type_get_type_id(length_field->type) != CTF_TYPE_INTEGER) { ret = -1; goto end; } length_type = container_of(length_field->type, struct bt_ctf_field_type_integer, parent); /* The length field must be unsigned */ if (length_type->declaration.signedness) { ret = -1; goto end; } length = container_of(length_field, struct bt_ctf_field_integer, parent); sequence_length = length->definition.value._unsigned; sequence = container_of(field, struct bt_ctf_field_sequence, parent); if (sequence->elements) { g_ptr_array_free(sequence->elements, TRUE); bt_ctf_field_put(sequence->length); } sequence->elements = g_ptr_array_sized_new((size_t)sequence_length); if (!sequence->elements) { ret = -1; goto end; } g_ptr_array_set_free_func(sequence->elements, (GDestroyNotify)bt_ctf_field_put); g_ptr_array_set_size(sequence->elements, (size_t)sequence_length); bt_ctf_field_get(length_field); sequence->length = length_field; end: return ret; }
static int set_packet_header_magic(struct bt_ctf_stream *stream) { int ret = 0; struct bt_ctf_field_type *magic_field_type = NULL; struct bt_ctf_field *magic_field = bt_ctf_field_structure_get_field( stream->packet_header, "magic"); if (!magic_field) { /* No magic field found. Not an error, skip. */ goto end; } if (!bt_ctf_field_validate(magic_field)) { /* Value already set. Not an error, skip. */ goto end; } magic_field_type = bt_ctf_field_get_type(magic_field); assert(magic_field_type); if (bt_ctf_field_type_get_type_id(magic_field_type) != CTF_TYPE_INTEGER) { /* Magic field is not an integer. Not an error, skip. */ goto end; } if (bt_ctf_field_type_integer_get_size(magic_field_type) != 32) { /* * Magic field is not of the expected size. * Not an error, skip. */ goto end; } ret = bt_ctf_field_type_integer_get_signed(magic_field_type); assert(ret >= 0); if (ret) { ret = bt_ctf_field_signed_integer_set_value(magic_field, (int64_t) 0xC1FC1FC1); } else { ret = bt_ctf_field_unsigned_integer_set_value(magic_field, (uint64_t) 0xC1FC1FC1); } end: bt_put(magic_field); bt_put(magic_field_type); return ret; }
static int set_structure_field_integer(struct bt_ctf_field *structure, char *name, uint64_t value) { int ret = 0; struct bt_ctf_field_type *field_type = NULL; struct bt_ctf_field *integer = bt_ctf_field_structure_get_field(structure, name); if (!structure || !name) { ret = -1; goto end; } if (!integer) { /* Field not found, not an error. */ goto end; } /* Make sure the payload has not already been set. */ if (!bt_ctf_field_validate(integer)) { /* Payload already set, not an error */ goto end; } field_type = bt_ctf_field_get_type(integer); /* Something is serioulsly wrong */ assert(field_type); if (bt_ctf_field_type_get_type_id(field_type) != CTF_TYPE_INTEGER) { /* * The user most likely meant for us to populate this field * automatically. However, we can only do this if the field * is an integer. Return an error. */ ret = -1; goto end; } if (bt_ctf_field_type_integer_get_signed(field_type)) { ret = bt_ctf_field_signed_integer_set_value(integer, (int64_t) value); } else { ret = bt_ctf_field_unsigned_integer_set_value(integer, value); } end: bt_put(integer); bt_put(field_type); return ret; }
const char *bt_ctf_field_string_get_value(struct bt_ctf_field *field) { const char *ret = NULL; struct bt_ctf_field_string *string; if (!field || !field->payload_set || bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_STRING) { goto end; } string = container_of(field, struct bt_ctf_field_string, parent); ret = string->payload->str; end: return ret; }
struct bt_ctf_field *bt_ctf_field_structure_get_field( struct bt_ctf_field *field, const char *name) { struct bt_ctf_field *new_field = NULL; GQuark field_quark; struct bt_ctf_field_structure *structure; struct bt_ctf_field_type *field_type = NULL; size_t index; if (!field || !name || bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_STRUCT) { goto error; } field_quark = g_quark_from_string(name); structure = container_of(field, struct bt_ctf_field_structure, parent); field_type = bt_ctf_field_type_structure_get_field_type_by_name(field->type, name); if (!g_hash_table_lookup_extended(structure->field_name_to_index, GUINT_TO_POINTER(field_quark), NULL, (gpointer *)&index)) { goto error; } if (structure->fields->pdata[index]) { new_field = structure->fields->pdata[index]; goto end; } new_field = bt_ctf_field_create(field_type); if (!new_field) { goto error; } structure->fields->pdata[index] = new_field; end: bt_ctf_field_get(new_field); error: if (field_type) { bt_ctf_field_type_put(field_type); } return new_field; }
BT_HIDDEN int bt_ctf_field_structure_set_field(struct bt_ctf_field *field, const char *name, struct bt_ctf_field *value) { int ret = 0; GQuark field_quark; struct bt_ctf_field_structure *structure; struct bt_ctf_field_type *expected_field_type = NULL; size_t index; if (!field || !name || !value || bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_STRUCT) { ret = -1; goto end; } field_quark = g_quark_from_string(name); structure = container_of(field, struct bt_ctf_field_structure, parent); expected_field_type = bt_ctf_field_type_structure_get_field_type_by_name(field->type, name); if (expected_field_type != value->type) { ret = -1; goto end; } if (!g_hash_table_lookup_extended(structure->field_name_to_index, GUINT_TO_POINTER(field_quark), NULL, (gpointer *) &index)) { goto end; } if (structure->fields->pdata[index]) { bt_ctf_field_put(structure->fields->pdata[index]); } structure->fields->pdata[index] = value; bt_ctf_field_get(value); end: if (expected_field_type) { bt_ctf_field_type_put(expected_field_type); } return ret; }
static int get_event_header_timestamp(struct bt_ctf_field *event_header, uint64_t *timestamp) { int ret = 0; struct bt_ctf_field *timestamp_field = NULL; struct bt_ctf_field_type *timestamp_field_type = NULL; timestamp_field = bt_ctf_field_structure_get_field(event_header, "timestamp"); if (!timestamp_field) { ret = -1; goto end; } timestamp_field_type = bt_ctf_field_get_type(timestamp_field); assert(timestamp_field_type); if (bt_ctf_field_type_get_type_id(timestamp_field_type) != CTF_TYPE_INTEGER) { ret = -1; goto end; } if (bt_ctf_field_type_integer_get_signed(timestamp_field_type)) { int64_t val; ret = bt_ctf_field_signed_integer_get_value(timestamp_field, &val); if (ret) { goto end; } *timestamp = (uint64_t) val; } else { ret = bt_ctf_field_unsigned_integer_get_value(timestamp_field, timestamp); if (ret) { goto end; } } end: bt_put(timestamp_field); bt_put(timestamp_field_type); return ret; }
int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field, double value) { int ret = 0; struct bt_ctf_field_floating_point *floating_point; if (!field || bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_FLOAT) { ret = -1; goto end; } floating_point = container_of(field, struct bt_ctf_field_floating_point, parent); floating_point->definition.value = value; floating_point->parent.payload_set = 1; end: return ret; }
BT_HIDDEN int bt_ctf_event_class_set_payload_type(struct bt_ctf_event_class *event_class, struct bt_ctf_field_type *payload) { int ret = 0; if (!event_class || !payload || bt_ctf_field_type_get_type_id(payload) != CTF_TYPE_STRUCT) { ret = -1; goto end; } bt_get(payload); bt_put(event_class->fields); event_class->fields = payload; end: return ret; }
static int set_integer_field_value(struct bt_ctf_field* field, uint64_t value) { int ret = 0; struct bt_ctf_field_type *field_type = NULL; if (!field) { ret = -1; goto end; } if (!bt_ctf_field_validate(field)) { /* Payload already set, skip! (not an error) */ goto end; } field_type = bt_ctf_field_get_type(field); assert(field_type); if (bt_ctf_field_type_get_type_id(field_type) != CTF_TYPE_INTEGER) { /* Not an integer and the value is unset, error. */ ret = -1; goto end; } if (bt_ctf_field_type_integer_get_signed(field_type)) { ret = bt_ctf_field_signed_integer_set_value(field, (int64_t) value); if (ret) { /* Value is out of range, error. */ goto end; } } else { ret = bt_ctf_field_unsigned_integer_set_value(field, value); if (ret) { /* Value is out of range, error. */ goto end; } } end: bt_put(field_type); return ret; }
static int set_packet_header_stream_id(struct bt_ctf_stream *stream) { int ret = 0; uint32_t stream_id; struct bt_ctf_field_type *stream_id_field_type = NULL; struct bt_ctf_field *stream_id_field = bt_ctf_field_structure_get_field( stream->packet_header, "stream_id"); if (!stream_id_field) { /* No stream_id field found. Not an error, skip. */ goto end; } if (!bt_ctf_field_validate(stream_id_field)) { /* Value already set. Not an error, skip. */ goto end; } stream_id_field_type = bt_ctf_field_get_type(stream_id_field); assert(stream_id_field_type); if (bt_ctf_field_type_get_type_id(stream_id_field_type) != CTF_TYPE_INTEGER) { /* stream_id field is not an integer. Not an error, skip. */ goto end; } stream_id = stream->stream_class->id; ret = bt_ctf_field_type_integer_get_signed(stream_id_field_type); assert(ret >= 0); if (ret) { ret = bt_ctf_field_signed_integer_set_value(stream_id_field, (int64_t) stream_id); } else { ret = bt_ctf_field_unsigned_integer_set_value(stream_id_field, (uint64_t) stream_id); } end: bt_put(stream_id_field); bt_put(stream_id_field_type); return ret; }
BT_HIDDEN int bt_ctf_field_reset(struct bt_ctf_field *field) { int ret = 0; enum ctf_type_id type_id; if (!field) { ret = -1; goto end; } type_id = bt_ctf_field_type_get_type_id(field->type); if (type_id <= CTF_TYPE_UNKNOWN || type_id >= NR_CTF_TYPES) { ret = -1; goto end; } ret = field_reset_funcs[type_id](field); end: return ret; }
struct bt_ctf_field *bt_ctf_field_sequence_get_length( struct bt_ctf_field *field) { struct bt_ctf_field *ret = NULL; struct bt_ctf_field_sequence *sequence; if (!field) { goto end; } if (bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_SEQUENCE) { goto end; } sequence = container_of(field, struct bt_ctf_field_sequence, parent); ret = sequence->length; bt_ctf_field_get(ret); end: return ret; }
BT_HIDDEN int bt_ctf_event_class_get_field_count( struct bt_ctf_event_class *event_class) { int ret; if (!event_class) { ret = -1; goto end; } if (bt_ctf_field_type_get_type_id(event_class->fields) != CTF_TYPE_STRUCT) { ret = -1; goto end; } ret = bt_ctf_field_type_structure_get_field_count(event_class->fields); end: return ret; }
BT_HIDDEN int bt_ctf_field_serialize(struct bt_ctf_field *field, struct ctf_stream_pos *pos) { int ret = 0; enum ctf_type_id type_id; if (!field || !pos) { ret = -1; goto end; } type_id = bt_ctf_field_type_get_type_id(field->type); if (type_id <= CTF_TYPE_UNKNOWN || type_id >= NR_CTF_TYPES) { ret = -1; goto end; } ret = field_serialize_funcs[type_id](field, pos); end: return ret; }
BT_HIDDEN int bt_ctf_event_class_get_field(struct bt_ctf_event_class *event_class, const char **field_name, struct bt_ctf_field_type **field_type, int index) { int ret; if (!event_class || index < 0) { ret = -1; goto end; } if (bt_ctf_field_type_get_type_id(event_class->fields) != CTF_TYPE_STRUCT) { ret = -1; goto end; } ret = bt_ctf_field_type_structure_get_field(event_class->fields, field_name, field_type, index); end: return ret; }
int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class, struct bt_ctf_field_type *type, const char *name) { int ret = 0; if (!event_class || !type || bt_ctf_validate_identifier(name) || event_class->frozen) { ret = -1; goto end; } if (bt_ctf_field_type_get_type_id(event_class->fields) != CTF_TYPE_STRUCT) { ret = -1; goto end; } ret = bt_ctf_field_type_structure_add_field(event_class->fields, type, name); end: return ret; }
int bt_ctf_trace_set_packet_header_type(struct bt_ctf_trace *trace, struct bt_ctf_field_type *packet_header_type) { int ret = 0; if (!trace || !packet_header_type || trace->frozen) { ret = -1; goto end; } /* packet_header_type must be a structure */ if (bt_ctf_field_type_get_type_id(packet_header_type) != CTF_TYPE_STRUCT) { ret = -1; goto end; } bt_get(packet_header_type); bt_put(trace->packet_header_type); trace->packet_header_type = packet_header_type; end: return ret; }
int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *field, int64_t value) { int ret = 0; struct bt_ctf_field_integer *integer; struct bt_ctf_field_type_integer *integer_type; unsigned int size; int64_t min_value, max_value; if (!field || bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_INTEGER) { ret = -1; goto end; } integer = container_of(field, struct bt_ctf_field_integer, parent); integer_type = container_of(field->type, struct bt_ctf_field_type_integer, parent); if (!integer_type->declaration.signedness) { ret = -1; goto end; } size = integer_type->declaration.len; min_value = -((int64_t)1 << (size - 1)); max_value = ((int64_t)1 << (size - 1)) - 1; if (value < min_value || value > max_value) { ret = -1; goto end; } integer->definition.value._signed = value; integer->parent.payload_set = 1; end: return ret; }
int bt_ctf_field_string_set_value(struct bt_ctf_field *field, const char *value) { int ret = 0; struct bt_ctf_field_string *string; if (!field || !value || bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_STRING) { ret = -1; goto end; } string = container_of(field, struct bt_ctf_field_string, parent); if (string->payload) { g_string_assign(string->payload, value); } else { string->payload = g_string_new(value); } string->parent.payload_set = 1; end: return ret; }
BT_HIDDEN int bt_ctf_event_class_set_context_type( struct bt_ctf_event_class *event_class, struct bt_ctf_field_type *context) { int ret = 0; if (!event_class || !context || event_class->frozen) { ret = -1; goto end; } if (bt_ctf_field_type_get_type_id(context) != CTF_TYPE_STRUCT) { ret = -1; goto end; } bt_get(context); bt_put(event_class->context); event_class->context = context; end: return ret; }