Пример #1
0
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;
}
Пример #2
0
int bt_ctf_stream_append_event(struct bt_ctf_stream *stream,
		struct bt_ctf_event *event)
{
	int ret = 0;
	struct bt_ctf_field *event_context_copy = NULL;

	if (!stream || !event) {
		ret = -1;
		goto end;
	}

	ret = bt_ctf_event_set_stream(event, stream);
	if (ret) {
		/* Event was already associated to a stream */
		ret = -1;
		goto end;
	}

	ret = bt_ctf_event_populate_event_header(event);
	if (ret) {
		goto end;
	}

	/* Make sure the event's payload is set */
	ret = bt_ctf_event_validate(event);
	if (ret) {
		goto end;
	}

	/* Sample the current stream event context by copying it */
	if (stream->event_context) {
		/* Make sure the event context's payload is set */
		ret = bt_ctf_field_validate(stream->event_context);
		if (ret) {
			goto end;
		}

		event_context_copy = bt_ctf_field_copy(stream->event_context);
		if (!event_context_copy) {
			ret = -1;
			goto end;
		}
	}

	bt_get(event);
	/* Save the new event along with its associated stream event context */
	g_ptr_array_add(stream->events, event);
	if (event_context_copy) {
		g_ptr_array_add(stream->event_contexts, event_context_copy);
	}
end:
	if (ret) {
		(void) bt_ctf_event_set_stream(event, NULL);
	}
	return ret;
}
Пример #3
0
BT_HIDDEN
int bt_ctf_event_validate(struct bt_ctf_event *event)
{
	/* Make sure each field's payload has been set */
	int ret;
	struct bt_ctf_stream_class *stream_class = NULL;

	assert(event);
	ret = bt_ctf_field_validate(event->event_header);
	if (ret) {
		goto end;
	}

	stream_class = bt_ctf_event_class_get_stream_class(event->event_class);
	/*
	 * We should not have been able to create the event without associating
	 * the event class to a stream class.
	 */
	assert(stream_class);
	if (stream_class->event_context_type) {
		ret = bt_ctf_field_validate(event->stream_event_context);
		if (ret) {
			goto end;
		}
	}

	ret = bt_ctf_field_validate(event->fields_payload);
	if (ret) {
		goto end;
	}

	if (event->event_class->context) {
		ret = bt_ctf_field_validate(event->context_payload);
	}
end:
	bt_put(stream_class);
	return ret;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
static
int bt_ctf_field_variant_validate(struct bt_ctf_field *field)
{
	int ret = 0;
	struct bt_ctf_field_variant *variant;

	if (!field) {
		ret = -1;
		goto end;
	}

	variant = container_of(field, struct bt_ctf_field_variant, parent);
	ret = bt_ctf_field_validate(variant->payload);
end:
	return ret;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
static
int bt_ctf_field_sequence_validate(struct bt_ctf_field *field)
{
	size_t i;
	int ret = 0;
	struct bt_ctf_field_sequence *sequence;

	if (!field) {
		ret = -1;
		goto end;
	}

	sequence = container_of(field, struct bt_ctf_field_sequence, parent);
	for (i = 0; i < sequence->elements->len; i++) {
		ret = bt_ctf_field_validate(sequence->elements->pdata[i]);
		if (ret) {
			goto end;
		}
	}
end:
	return ret;
}
Пример #10
0
static
int bt_ctf_field_array_validate(struct bt_ctf_field *field)
{
	size_t i;
	int ret = 0;
	struct bt_ctf_field_array *array;

	if (!field) {
		ret = -1;
		goto end;
	}

	array = container_of(field, struct bt_ctf_field_array, parent);
	for (i = 0; i < array->elements->len; i++) {
		ret = bt_ctf_field_validate(array->elements->pdata[i]);
		if (ret) {
			goto end;
		}
	}
end:
	return ret;
}
Пример #11
0
static
int bt_ctf_field_structure_validate(struct bt_ctf_field *field)
{
	size_t i;
	int ret = 0;
	struct bt_ctf_field_structure *structure;

	if (!field) {
		ret = -1;
		goto end;
	}

	structure = container_of(field, struct bt_ctf_field_structure, parent);
	for (i = 0; i < structure->fields->len; i++) {
		ret = bt_ctf_field_validate(structure->fields->pdata[i]);
		if (ret) {
			goto end;
		}
	}
end:
	return ret;
}
Пример #12
0
static
int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field)
{
	int ret;
	struct bt_ctf_field_enumeration *enumeration;

	if (!field) {
		ret = -1;
		goto end;
	}

	enumeration = container_of(field, struct bt_ctf_field_enumeration,
		parent);
	if (!enumeration->payload) {
		ret = -1;
		goto end;
	}

	ret = bt_ctf_field_validate(enumeration->payload);
end:
	return ret;
}
Пример #13
0
static
int set_packet_header_uuid(struct bt_ctf_stream *stream)
{
	int i, ret = 0;
	struct bt_ctf_field_type *uuid_field_type = NULL;
	struct bt_ctf_field_type *element_field_type = NULL;
	struct bt_ctf_field *uuid_field = bt_ctf_field_structure_get_field(
		stream->packet_header, "uuid");

	if (!uuid_field) {
		/* No uuid field found. Not an error, skip. */
		goto end;
	}

	if (!bt_ctf_field_validate(uuid_field)) {
		/* Value already set. Not an error, skip. */
		goto end;
	}

	uuid_field_type = bt_ctf_field_get_type(uuid_field);
	assert(uuid_field_type);
	if (bt_ctf_field_type_get_type_id(uuid_field_type) !=
		CTF_TYPE_ARRAY) {
		/* UUID field is not an array. Not an error, skip. */
		goto end;
	}

	if (bt_ctf_field_type_array_get_length(uuid_field_type) != 16) {
		/*
		 * UUID field is not of the expected size.
		 * Not an error, skip.
		 */
		goto end;
	}

	element_field_type = bt_ctf_field_type_array_get_element_type(
		uuid_field_type);
	assert(element_field_type);
	if (bt_ctf_field_type_get_type_id(element_field_type) !=
		CTF_TYPE_INTEGER) {
		/* UUID array elements are not integers. Not an error, skip */
		goto end;
	}

	for (i = 0; i < 16; i++) {
		struct bt_ctf_field *uuid_element =
			bt_ctf_field_array_get_field(uuid_field, i);

		ret = bt_ctf_field_type_integer_get_signed(element_field_type);
		assert(ret >= 0);

		if (ret) {
			ret = bt_ctf_field_signed_integer_set_value(
				uuid_element, (int64_t) stream->trace->uuid[i]);
		} else {
			ret = bt_ctf_field_unsigned_integer_set_value(
				uuid_element,
				(uint64_t) stream->trace->uuid[i]);
		}
		bt_put(uuid_element);
		if (ret) {
			goto end;
		}
	}

end:
	bt_put(uuid_field);
	bt_put(uuid_field_type);
	bt_put(element_field_type);
	return ret;
}
Пример #14
0
int bt_ctf_stream_flush(struct bt_ctf_stream *stream)
{
	int ret = 0;
	size_t i;
	uint64_t timestamp_begin, timestamp_end, events_discarded;
	struct bt_ctf_field *integer = NULL;
	struct ctf_stream_pos packet_context_pos;

	if (!stream || stream->pos.fd < 0) {
		/*
		 * Stream does not have an associated fd. It is,
		 * therefore, not a stream being used to write events.
		 */
		ret = -1;
		goto end;
	}

	if (!stream->events->len) {
		goto end;
	}

	ret = bt_ctf_field_validate(stream->packet_header);
	if (ret) {
		goto end;
	}

	/* mmap the next packet */
	ctf_packet_seek(&stream->pos.parent, 0, SEEK_CUR);

	ret = bt_ctf_field_serialize(stream->packet_header, &stream->pos);
	if (ret) {
		goto end;
	}

	/* Set the default context attributes if present and unset. */
	if (!get_event_header_timestamp(
		((struct bt_ctf_event *) g_ptr_array_index(
		stream->events, 0))->event_header, &timestamp_begin)) {
		ret = set_structure_field_integer(stream->packet_context,
			"timestamp_begin", timestamp_begin);
		if (ret) {
			goto end;
		}
	}

	if (!get_event_header_timestamp(
		((struct bt_ctf_event *) g_ptr_array_index(
		stream->events, stream->events->len - 1))->event_header,
		&timestamp_end)) {

		ret = set_structure_field_integer(stream->packet_context,
			"timestamp_end", timestamp_end);
		if (ret) {
			goto end;
		}
	}
	ret = set_structure_field_integer(stream->packet_context,
		"content_size", UINT64_MAX);
	if (ret) {
		goto end;
	}

	ret = set_structure_field_integer(stream->packet_context,
		"packet_size", UINT64_MAX);
	if (ret) {
		goto end;
	}

	/* Write packet context */
	memcpy(&packet_context_pos, &stream->pos,
	       sizeof(struct ctf_stream_pos));
	ret = bt_ctf_field_serialize(stream->packet_context,
		&stream->pos);
	if (ret) {
		goto end;
	}

	ret = bt_ctf_stream_get_discarded_events_count(stream,
		&events_discarded);
	if (ret) {
		goto end;
	}

	/* Unset the packet context's fields. */
	ret = bt_ctf_field_reset(stream->packet_context);
	if (ret) {
		goto end;
	}

	/* Set the previous number of discarded events. */
	ret = set_structure_field_integer(stream->packet_context,
		"events_discarded", events_discarded);
	if (ret) {
		goto end;
	}

	for (i = 0; i < stream->events->len; i++) {
		struct bt_ctf_event *event = g_ptr_array_index(
			stream->events, i);

		ret = bt_ctf_field_reset(event->event_header);
		if (ret) {
			goto end;
		}

		/* Write event header */
		ret = bt_ctf_field_serialize(event->event_header,
			&stream->pos);
		if (ret) {
			goto end;
		}

		/* Write stream event context */
		if (stream->event_contexts) {
			ret = bt_ctf_field_serialize(
				g_ptr_array_index(stream->event_contexts, i),
				&stream->pos);
			if (ret) {
				goto end;
			}
		}

		/* Write event content */
		ret = bt_ctf_event_serialize(event, &stream->pos);
		if (ret) {
			goto end;
		}
	}

	/*
	 * Update the packet total size and content size and overwrite the
	 * packet context.
	 * Copy base_mma as the packet may have been remapped (e.g. when a
	 * packet is resized).
	 */
	packet_context_pos.base_mma = stream->pos.base_mma;
	ret = set_structure_field_integer(stream->packet_context,
		"content_size", stream->pos.offset);
	if (ret) {
		goto end;
	}

	ret = set_structure_field_integer(stream->packet_context,
		"packet_size", stream->pos.packet_size);
	if (ret) {
		goto end;
	}

	ret = bt_ctf_field_serialize(stream->packet_context,
		&packet_context_pos);
	if (ret) {
		goto end;
	}

	g_ptr_array_set_size(stream->events, 0);
	if (stream->event_contexts) {
		g_ptr_array_set_size(stream->event_contexts, 0);
	}
	stream->flushed_packet_count++;
end:
	bt_put(integer);
	return ret;
}