Esempio n. 1
0
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_LOGW("Invalid parameter: event class or field type is NULL: "
			"event-class-addr=%p, field-type-addr=%p",
			event_class, type);
		ret = -1;
		goto end;
	}

	if (!bt_ctf_identifier_is_valid(name)) {
		BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: "
			"addr=%p, name=\"%s\", id=%" PRId64 ", field-name=\"%s\"",
			event_class, bt_ctf_event_class_get_name(event_class),
			bt_ctf_event_class_get_id(event_class),
			name);
		ret = -1;
		goto end;
	}

	if (event_class->common.frozen) {
		BT_LOGW("Invalid parameter: event class is frozen: "
			"addr=%p, name=\"%s\", id=%" PRId64,
			event_class, bt_ctf_event_class_get_name(event_class),
			bt_ctf_event_class_get_id(event_class));
		ret = -1;
		goto end;
	}

	if (!event_class->common.payload_field_type) {
		BT_LOGW("Event class has no payload field type: "
			"addr=%p, name=\"%s\", id=%" PRId64,
			event_class, bt_ctf_event_class_get_name(event_class),
			bt_ctf_event_class_get_id(event_class));
		ret = -1;
		goto end;
	}

	BT_ASSERT(bt_ctf_field_type_common_get_type_id(
		event_class->common.payload_field_type) ==
		BT_CTF_FIELD_TYPE_ID_STRUCT);
	ret = bt_ctf_field_type_structure_add_field(
		(void *) event_class->common.payload_field_type,
		(void *) type, name);
	BT_LOGV("Added field to event class's payload field type: "
		"event-class-addr=%p, event-class-name=\"%s\", "
		"event-class-id=%" PRId64 ", field-name=\"%s\", ft-addr=%p",
		event_class, bt_ctf_event_class_get_name(event_class),
		bt_ctf_event_class_get_id(event_class), name, type);
end:
	return ret;
}
Esempio n. 2
0
BT_HIDDEN
int bt_ctf_event_class_common_validate_single_clock_class(
		struct bt_ctf_event_class_common *event_class,
		struct bt_ctf_clock_class **expected_clock_class)
{
	int ret = 0;

	BT_ASSERT(event_class);
	BT_ASSERT(expected_clock_class);
	ret = bt_ctf_field_type_common_validate_single_clock_class(
		event_class->context_field_type,
		expected_clock_class);
	if (ret) {
		BT_LOGW("Event class's context field type "
			"is not recursively mapped to the "
			"expected clock class: "
			"event-class-addr=%p, "
			"event-class-name=\"%s\", "
			"event-class-id=%" PRId64 ", "
			"ft-addr=%p",
			event_class,
			bt_ctf_event_class_common_get_name(event_class),
			event_class->id,
			event_class->context_field_type);
		goto end;
	}

	ret = bt_ctf_field_type_common_validate_single_clock_class(
		event_class->payload_field_type,
		expected_clock_class);
	if (ret) {
		BT_LOGW("Event class's payload field type "
			"is not recursively mapped to the "
			"expected clock class: "
			"event-class-addr=%p, "
			"event-class-name=\"%s\", "
			"event-class-id=%" PRId64 ", "
			"ft-addr=%p",
			event_class,
			bt_ctf_event_class_common_get_name(event_class),
			event_class->id,
			event_class->payload_field_type);
		goto end;
	}

end:
	return ret;
}
Esempio n. 3
0
BT_HIDDEN
struct bt_value *bt_attributes_get_field_value_by_name(
		struct bt_value *attr_obj, const char *name)
{
	struct bt_value *value_obj = NULL;
	struct bt_value *attr_field_obj = NULL;

	if (!attr_obj || !name) {
		BT_LOGW("Invalid parameter: attributes object or name is NULL: "
			"value-addr=%p, name-addr=%p", attr_obj, name);
		goto end;
	}

	attr_field_obj = bt_attributes_get_field_by_name(attr_obj, name);
	if (!attr_field_obj) {
		BT_LOGD("Cannot find attributes object's field by name: "
			"value-addr=%p, name=\"%s\"", attr_obj, name);
		goto end;
	}

	value_obj = bt_value_array_get(attr_field_obj,
		BT_ATTR_VALUE_INDEX);
	if (!value_obj) {
		BT_LOGE("Cannot get attribute array value's element by index: "
			"value-addr=%p, index=%" PRIu64, attr_field_obj,
			(uint64_t) BT_ATTR_VALUE_INDEX);
	}

end:
	BT_PUT(attr_field_obj);

	return value_obj;
}
Esempio n. 4
0
static inline
int64_t get_compound_field_type_length(struct bt_btr *btr,
		struct bt_field_type *field_type)
{
	int64_t length;

	switch (bt_field_type_get_type_id(field_type)) {
	case BT_FIELD_TYPE_ID_STRUCT:
		length = (int64_t) bt_field_type_structure_get_field_count(
			field_type);
		break;
	case BT_FIELD_TYPE_ID_VARIANT:
		/* Variant field types always "contain" a single type */
		length = 1;
		break;
	case BT_FIELD_TYPE_ID_ARRAY:
		length = bt_field_type_array_get_length(field_type);
		break;
	case BT_FIELD_TYPE_ID_SEQUENCE:
		length = btr->user.cbs.query.get_sequence_length(field_type,
			btr->user.data);
		break;
	default:
		BT_LOGW("Cannot get field type's field count: btr-addr=%p, "
			"ft-addr=%p, ft-id=%s",
			btr, field_type,
			bt_field_type_id_string(
				bt_field_type_get_type_id(field_type)));
		length = BT_BTR_STATUS_ERROR;
	}

	return length;
}
Esempio n. 5
0
struct bt_clock_value *bt_event_get_clock_value(
		struct bt_event *event, struct bt_clock_class *clock_class)
{
	struct bt_clock_value *clock_value = NULL;

	if (!event || !clock_class) {
		BT_LOGW("Invalid parameter: event or clock class is NULL: "
			"event-addr=%p, clock-class-addr=%p",
			event, clock_class);
		goto end;
	}

	clock_value = g_hash_table_lookup(event->clock_values, clock_class);
	if (!clock_value) {
		BT_LOGV("No clock value associated to the given clock class: "
			"event-addr=%p, event-class-name=\"%s\", "
			"event-class-id=%" PRId64 ", clock-class-addr=%p, "
			"clock-class-name=\"%s\"", event,
			bt_event_class_get_name(event->event_class),
			bt_event_class_get_id(event->event_class),
			clock_class, bt_clock_class_get_name(clock_class));
		goto end;
	}

	bt_get(clock_value);
end:
	return clock_value;
}
Esempio n. 6
0
BT_HIDDEN
int bt_event_serialize(struct bt_event *event,
		struct bt_stream_pos *pos,
		enum bt_byte_order native_byte_order)
{
	int ret = 0;

	assert(event);
	assert(pos);

	BT_LOGV_STR("Serializing event's context field.");
	if (event->context_payload) {
		ret = bt_field_serialize(event->context_payload, pos,
			native_byte_order);
		if (ret) {
			BT_LOGW("Cannot serialize event's context field: "
				"event-addr=%p, event-class-name=\"%s\", "
				"event-class-id=%" PRId64,
				event,
				bt_event_class_get_name(event->event_class),
				bt_event_class_get_id(event->event_class));
			goto end;
		}
	}

	BT_LOGV_STR("Serializing event's payload field.");
	if (event->fields_payload) {
		ret = bt_field_serialize(event->fields_payload, pos,
			native_byte_order);
		if (ret) {
			BT_LOGW("Cannot serialize event's payload field: "
				"event-addr=%p, event-class-name=\"%s\", "
				"event-class-id=%" PRId64,
				event,
				bt_event_class_get_name(event->event_class),
				bt_event_class_get_id(event->event_class));
			goto end;
		}
	}
end:
	return ret;
}
Esempio n. 7
0
BT_HIDDEN
void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class *clock_class,
		struct metadata_context *context)
{
	unsigned char *uuid;

	BT_LOGD("Serializing clock class's metadata: clock-class-addr=%p, "
		"name=\"%s\", metadata-context-addr=%p", clock_class,
		bt_ctf_clock_class_get_name(clock_class),
		context);

	if (!clock_class || !context) {
		BT_LOGW("Invalid parameter: clock class or metadata context is NULL: "
			"clock-class-addr=%p, name=\"%s\", metadata-context-addr=%p",
			clock_class,
			bt_ctf_clock_class_get_name(clock_class),
			context);
		return;
	}

	uuid = clock_class->uuid;
	g_string_append(context->string, "clock {\n");
	g_string_append_printf(context->string, "\tname = %s;\n",
		clock_class->name->str);

	if (clock_class->uuid_set) {
		g_string_append_printf(context->string,
			"\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
			uuid[0], uuid[1], uuid[2], uuid[3],
			uuid[4], uuid[5], uuid[6], uuid[7],
			uuid[8], uuid[9], uuid[10], uuid[11],
			uuid[12], uuid[13], uuid[14], uuid[15]);
	}

	if (clock_class->description) {
		g_string_append_printf(context->string, "\tdescription = \"%s\";\n",
			clock_class->description->str);
	}

	g_string_append_printf(context->string, "\tfreq = %" PRIu64 ";\n",
		clock_class->frequency);
	g_string_append_printf(context->string, "\tprecision = %" PRIu64 ";\n",
		clock_class->precision);
	g_string_append_printf(context->string, "\toffset_s = %" PRIu64 ";\n",
		clock_class->offset_s);
	g_string_append_printf(context->string, "\toffset = %" PRIu64 ";\n",
		clock_class->offset);
	g_string_append_printf(context->string, "\tabsolute = %s;\n",
		clock_class->absolute ? "true" : "false");
	g_string_append(context->string, "};\n\n");
}
Esempio n. 8
0
BT_HIDDEN
int bt_attributes_set_field_value(struct bt_value *attr_obj,
		const char *name, struct bt_value *value_obj)
{
	int ret = 0;
	struct bt_value *attr_field_obj = NULL;

	if (!attr_obj || !name || !value_obj) {
		BT_LOGW("Invalid parameter: attributes object, name, or value object is NULL: "
			"attr-value-addr=%p, name-addr=%p, value-addr=%p",
			attr_obj, name, value_obj);
		ret = -1;
		goto end;
	}

	attr_field_obj = bt_attributes_get_field_by_name(attr_obj, name);
	if (attr_field_obj) {
		ret = bt_value_array_set(attr_field_obj,
			BT_ATTR_VALUE_INDEX, value_obj);
		goto end;
	}

	attr_field_obj = bt_value_array_create();
	if (!attr_field_obj) {
		BT_LOGE_STR("Failed to create empty array value.");
		ret = -1;
		goto end;
	}

	ret = bt_value_array_append_string(attr_field_obj, name);
	ret |= bt_value_array_append(attr_field_obj, value_obj);
	if (ret) {
		BT_LOGE("Cannot append elements to array value: addr=%p",
			attr_field_obj);
		goto end;
	}

	ret = bt_value_array_append(attr_obj, attr_field_obj);
	if (ret) {
		BT_LOGE("Cannot append element to array value: "
			"array-value-addr=%p, element-value-addr=%p",
			attr_obj, attr_field_obj);
	}

end:
	BT_PUT(attr_field_obj);

	return ret;
}
Esempio n. 9
0
static inline
enum bt_btr_status validate_contiguous_bo(struct bt_btr *btr,
		enum bt_byte_order next_bo)
{
	enum bt_btr_status status = BT_BTR_STATUS_OK;

	/* Always valid when at a byte boundary */
	if (packet_at(btr) % 8 == 0) {
		goto end;
	}

	/* Always valid if last byte order is unknown */
	if (btr->last_bo == BT_BYTE_ORDER_UNKNOWN) {
		goto end;
	}

	/* Always valid if next byte order is unknown */
	if (next_bo == BT_BYTE_ORDER_UNKNOWN) {
		goto end;
	}

	/* Make sure last byte order is compatible with the next byte order */
	switch (btr->last_bo) {
	case BT_BYTE_ORDER_BIG_ENDIAN:
	case BT_BYTE_ORDER_NETWORK:
		if (next_bo != BT_BYTE_ORDER_BIG_ENDIAN &&
				next_bo != BT_BYTE_ORDER_NETWORK) {
			status = BT_BTR_STATUS_ERROR;
		}
		break;
	case BT_BYTE_ORDER_LITTLE_ENDIAN:
		if (next_bo != BT_BYTE_ORDER_LITTLE_ENDIAN) {
			status = BT_BTR_STATUS_ERROR;
		}
		break;
	default:
		status = BT_BTR_STATUS_ERROR;
	}

end:
	if (status < 0) {
		BT_LOGW("Cannot read bit array: two different byte orders not at a byte boundary: "
			"btr-addr=%p, last-bo=%s, next-bo=%s",
			btr, bt_byte_order_string(btr->last_bo),
			bt_byte_order_string(next_bo));
	}

	return status;
}
Esempio n. 10
0
struct bt_ctf_field_type *
bt_ctf_event_class_get_payload_type_field_type_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) {
		BT_LOGW("Invalid parameter: event class or name is NULL: "
			"event-class-addr=%p, name-addr=%p",
			event_class, name);
		goto end;
	}

	if (!event_class->common.payload_field_type) {
		BT_LOGV("Event class has no payload field type: "
			"addr=%p, name=\"%s\", id=%" PRId64,
			event_class, bt_ctf_event_class_get_name(event_class),
			bt_ctf_event_class_get_id(event_class));
		goto end;
	}

	BT_ASSERT(bt_ctf_field_type_common_get_type_id(
		event_class->common.payload_field_type) ==
			BT_CTF_FIELD_TYPE_ID_STRUCT);
	name_quark = g_quark_try_string(name);
	if (!name_quark) {
		BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
		goto end;
	}

	/*
	 * No need to increment field_type's reference count since getting it
	 * from the structure already does.
	 */
	field_type = (void *)
		bt_ctf_field_type_structure_get_field_type_by_name(
			(void *) event_class->common.payload_field_type, name);

end:
	return field_type;
}
Esempio n. 11
0
static
int stack_push_with_len(struct bt_btr *btr,
		struct bt_field_type *base_type)
{
	int ret = 0;
	int64_t base_len = get_compound_field_type_length(btr, base_type);

	if (base_len < 0) {
		BT_LOGW("Cannot get compound field type's field count: "
			"btr-addr=%p, ft-addr=%p, ft-id=%s",
			btr, base_type, bt_field_type_id_string(
				bt_field_type_get_type_id(base_type)));
		ret = BT_BTR_STATUS_ERROR;
		goto end;
	}

	ret = stack_push(btr->stack, base_type, (size_t) base_len);

end:
	return ret;
}
Esempio n. 12
0
void bt_put(void *ptr)
{
	struct bt_object *obj = ptr;

	if (unlikely(!obj)) {
		return;
	}

	if (unlikely(!obj->ref_count.release)) {
		return;
	}

	if (BT_LOG_ON_WARN && unlikely(bt_object_get_ref_count(obj) == 0)) {
		BT_LOGW("Decrementing a reference count set to 0: addr=%p",
			ptr);
	}

	BT_LOGV("Decrementing object's reference count: %lu -> %lu: "
		"addr=%p, cur-count=%lu, new-count=%lu",
		obj->ref_count.count, obj->ref_count.count - 1,
		ptr,
		obj->ref_count.count, obj->ref_count.count - 1);
	bt_ref_put(&obj->ref_count);
}
Esempio n. 13
0
int bt_event_set_clock_value(struct bt_event *event,
		struct bt_clock_value *value)
{
	int ret = 0;
	struct bt_trace *trace;
	struct bt_stream_class *stream_class;
	struct bt_event_class *event_class;
	struct bt_clock_class *clock_class = NULL;

	if (!event || !value) {
		BT_LOGW("Invalid parameter: event or clock value is NULL: "
			"event-addr=%p, clock-value-addr=%p",
			event, value);
		ret = -1;
		goto end;
	}

	if (event->frozen) {
		BT_LOGW("Invalid parameter: event is frozen: addr=%p, "
			"event-class-name=\"%s\", event-class-id=%" PRId64,
			event, bt_event_class_get_name(event->event_class),
			bt_event_class_get_id(event->event_class));
		ret = -1;
		goto end;
	}

	clock_class = bt_clock_value_get_class(value);
	event_class = bt_event_borrow_event_class(event);
	assert(event_class);
	stream_class = bt_event_class_borrow_stream_class(event_class);
	assert(stream_class);
	trace = bt_stream_class_borrow_trace(stream_class);
	assert(trace);

	if (!bt_trace_has_clock_class(trace, clock_class)) {
		BT_LOGW("Invalid parameter: clock class is not part of event's trace: "
			"event-addr=%p, event-class-name=\"%s\", "
			"event-class-id=%" PRId64 ", clock-class-addr=%p, "
			"clock-class-name=\"%s\"",
			event, bt_event_class_get_name(event->event_class),
			bt_event_class_get_id(event->event_class),
			clock_class, bt_clock_class_get_name(clock_class));
		ret = -1;
		goto end;
	}

	g_hash_table_insert(event->clock_values, clock_class, bt_get(value));
	BT_LOGV("Set event's clock value: "
		"event-addr=%p, event-class-name=\"%s\", "
		"event-class-id=%" PRId64 ", clock-class-addr=%p, "
		"clock-class-name=\"%s\", clock-value-addr=%p, "
		"clock-value-cycles=%" PRIu64,
		event, bt_event_class_get_name(event->event_class),
		bt_event_class_get_id(event->event_class),
		clock_class, bt_clock_class_get_name(clock_class),
		value, value->value);
	clock_class = NULL;

end:
	bt_put(clock_class);
	return ret;
}
Esempio n. 14
0
int bt_event_set_stream_event_context(struct bt_event *event,
		struct bt_field *stream_event_context)
{
	int ret = 0;
	struct bt_field_type *field_type = NULL;
	struct bt_stream_class *stream_class = NULL;

	if (!event) {
		BT_LOGW_STR("Invalid parameter: event is NULL.");
		ret = -1;
		goto end;
	}

	if (event->frozen) {
		BT_LOGW("Invalid parameter: event is frozen: addr=%p, "
			"event-class-name=\"%s\", event-class-id=%" PRId64,
			event, bt_event_class_get_name(event->event_class),
			bt_event_class_get_id(event->event_class));
		ret = -1;
		goto end;
	}

	stream_class = bt_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_event_context) {
		field_type = bt_field_get_type(stream_event_context);
		if (bt_field_type_compare(field_type,
				stream_class->event_context_type)) {
			BT_LOGW("Invalid parameter: stream event context field type is different from the expected field type: "
				"event-addr=%p, event-class-name=\"%s\", "
				"event-class-id=%" PRId64,
				event,
				bt_event_class_get_name(event->event_class),
				bt_event_class_get_id(event->event_class));
			ret = -1;
			goto end;
		}
	} else {
		if (stream_class->event_context_type) {
			BT_LOGW("Invalid parameter: setting no stream event context but stream event context field type is not NULL: "
				"event-addr=%p, event-class-name=\"%s\", "
				"event-class-id=%" PRId64 ", "
				"stream-event-context-ft-addr=%p",
				event,
				bt_event_class_get_name(event->event_class),
				bt_event_class_get_id(event->event_class),
				stream_class->event_context_type);
			ret = -1;
			goto end;
		}
	}

	bt_get(stream_event_context);
	BT_MOVE(event->stream_event_context, stream_event_context);
	BT_LOGV("Set event's stream event context field: event-addr=%p, "
		"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
		"stream-event-context-field-addr=%p",
		event, bt_event_class_get_name(event->event_class),
		bt_event_class_get_id(event->event_class),
		stream_event_context);
end:
	BT_PUT(stream_class);
	bt_put(field_type);
	return ret;
}
Esempio n. 15
0
size_t bt_btr_start(struct bt_btr *btr,
	struct bt_field_type *type, const uint8_t *buf,
	size_t offset, size_t packet_offset, size_t sz,
	enum bt_btr_status *status)
{
	assert(btr);
	assert(BYTES_TO_BITS(sz) >= offset);
	reset(btr);
	btr->buf.addr = buf;
	btr->buf.offset = offset;
	btr->buf.at = 0;
	btr->buf.packet_offset = packet_offset;
	btr->buf.buf_sz = sz;
	btr->buf.sz = BYTES_TO_BITS(sz) - offset;
	*status = BT_BTR_STATUS_OK;

	BT_LOGV("Starting decoding: btr-addr=%p, ft-addr=%p, "
		"buf-addr=%p, buf-size=%zu, offset=%zu, "
		"packet-offset=%zu",
		btr, type, buf, sz, offset, packet_offset);

	/* Set root type */
	if (is_compound_type(type)) {
		/* Compound type: push on visit stack */
		int stack_ret;

		if (btr->user.cbs.types.compound_begin) {
			BT_LOGV("Calling user function (compound, begin).");
			*status = btr->user.cbs.types.compound_begin(
				type, btr->user.data);
			BT_LOGV("User function returned: status=%s",
				bt_btr_status_string(*status));
			if (*status != BT_BTR_STATUS_OK) {
				BT_LOGW("User function failed: btr-addr=%p, status=%s",
					btr, bt_btr_status_string(*status));
				goto end;
			}
		}

		stack_ret = stack_push_with_len(btr, type);
		if (stack_ret) {
			/* stack_push_with_len() logs errors */
			*status = BT_BTR_STATUS_ERROR;
			goto end;
		}

		btr->state = BTR_STATE_ALIGN_COMPOUND;
	} else {
		/* Basic type: set as current basic type */
		btr->cur_basic_field_type = type;
		bt_get(btr->cur_basic_field_type);
		btr->state = BTR_STATE_ALIGN_BASIC;
	}

	/* Run the machine! */
	BT_LOGV_STR("Running the state machine.");

	while (true) {
		*status = handle_state(btr);
		if (*status != BT_BTR_STATUS_OK ||
				btr->state == BTR_STATE_DONE) {
			break;
		}
	}

	/* Update packet offset for next time */
	update_packet_offset(btr);

end:
	return btr->buf.at;
}
Esempio n. 16
0
int bt_event_set_event_context(struct bt_event *event,
		struct bt_field *context)
{
	int ret = 0;
	struct bt_field_type *field_type = NULL;

	if (!event) {
		BT_LOGW_STR("Invalid parameter: event is NULL.");
		ret = -1;
		goto end;
	}

	if (event->frozen) {
		BT_LOGW("Invalid parameter: event is frozen: addr=%p, "
			"event-class-name=\"%s\", event-class-id=%" PRId64,
			event, bt_event_class_get_name(event->event_class),
			bt_event_class_get_id(event->event_class));
		ret = -1;
		goto end;
	}

	if (context) {
		field_type = bt_field_get_type(context);

		if (bt_field_type_compare(field_type,
				event->event_class->context)) {
			BT_LOGW("Invalid parameter: context field type is different from the expected field type: "
				"event-addr=%p, event-class-name=\"%s\", "
				"event-class-id=%" PRId64,
				event,
				bt_event_class_get_name(event->event_class),
				bt_event_class_get_id(event->event_class));
			ret = -1;
			goto end;
		}
	} else {
		if (event->event_class->context) {
			BT_LOGW("Invalid parameter: setting no event context but event context field type is not NULL: "
				"event-addr=%p, event-class-name=\"%s\", "
				"event-class-id=%" PRId64 ", "
				"event-context-ft-addr=%p",
				event,
				bt_event_class_get_name(event->event_class),
				bt_event_class_get_id(event->event_class),
				event->event_class->context);
			ret = -1;
			goto end;
		}
	}

	bt_put(event->context_payload);
	event->context_payload = bt_get(context);
	BT_LOGV("Set event's context field: event-addr=%p, "
		"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
		"context-field-addr=%p",
		event, bt_event_class_get_name(event->event_class),
		bt_event_class_get_id(event->event_class), context);
end:
	bt_put(field_type);
	return ret;
}
Esempio n. 17
0
struct bt_event *bt_event_create(struct bt_event_class *event_class)
{
	int ret;
	enum bt_validation_flag validation_flags =
		BT_VALIDATION_FLAG_STREAM |
		BT_VALIDATION_FLAG_EVENT;
	struct bt_event *event = NULL;
	struct bt_trace *trace = NULL;
	struct bt_stream_class *stream_class = NULL;
	struct bt_field_type *packet_header_type = NULL;
	struct bt_field_type *packet_context_type = NULL;
	struct bt_field_type *event_header_type = NULL;
	struct bt_field_type *stream_event_ctx_type = NULL;
	struct bt_field_type *event_context_type = NULL;
	struct bt_field_type *event_payload_type = NULL;
	struct bt_field *event_header = NULL;
	struct bt_field *stream_event_context = NULL;
	struct bt_field *event_context = NULL;
	struct bt_field *event_payload = NULL;
	struct bt_value *environment = NULL;
	struct bt_validation_output validation_output = { 0 };
	int trace_valid = 0;

	BT_LOGD("Creating event object: event-class-addr=%p, "
		"event-class-name=\"%s\", event-class-id=%" PRId64,
		event_class, bt_event_class_get_name(event_class),
		bt_event_class_get_id(event_class));

	if (!event_class) {
		BT_LOGW_STR("Invalid parameter: event class is NULL.");
		goto error;
	}

	stream_class = bt_event_class_get_stream_class(event_class);

	/*
	 * We disallow the creation of an event if its event class has not been
	 * associated to a stream class.
	 */
	if (!stream_class) {
		BT_LOGW_STR("Event class is not part of a stream class.");
		goto error;
	}

	/* The event class was frozen when added to its stream class */
	assert(event_class->frozen);

	/* Validate the trace (if any), the stream class, and the event class */
	trace = bt_stream_class_get_trace(stream_class);
	if (trace) {
		BT_LOGD_STR("Event's class is part of a trace.");
		packet_header_type = bt_trace_get_packet_header_type(trace);
		trace_valid = trace->valid;
		assert(trace_valid);
		environment = trace->environment;
	}

	packet_context_type = bt_stream_class_get_packet_context_type(
		stream_class);
	event_header_type = bt_stream_class_get_event_header_type(
		stream_class);
	stream_event_ctx_type = bt_stream_class_get_event_context_type(
		stream_class);
	event_context_type = bt_event_class_get_context_type(event_class);
	event_payload_type = bt_event_class_get_payload_type(event_class);
	ret = bt_validate_class_types(environment, packet_header_type,
		packet_context_type, event_header_type, stream_event_ctx_type,
		event_context_type, event_payload_type, trace_valid,
		stream_class->valid, event_class->valid,
		&validation_output, validation_flags);
	BT_PUT(packet_header_type);
	BT_PUT(packet_context_type);
	BT_PUT(event_header_type);
	BT_PUT(stream_event_ctx_type);
	BT_PUT(event_context_type);
	BT_PUT(event_payload_type);
	if (ret) {
		/*
		 * This means something went wrong during the validation
		 * process, not that the objects are invalid.
		 */
		BT_LOGE("Failed to validate event and parents: ret=%d", ret);
		goto error;
	}

	if ((validation_output.valid_flags & validation_flags) !=
			validation_flags) {
		/* Invalid trace/stream class/event class */
		BT_LOGW("Invalid trace, stream class, or event class: "
			"valid-flags=0x%x", validation_output.valid_flags);
		goto error;
	}

	/*
	 * At this point we know the trace (if associated to the stream
	 * class), the stream class, and the event class, with their
	 * current types, are valid. We may proceed with creating
	 * the event.
	 */
	event = g_new0(struct bt_event, 1);
	if (!event) {
		BT_LOGE_STR("Failed to allocate one event.");
		goto error;
	}

	bt_object_init(event, bt_event_destroy);

	/*
	 * event does not share a common ancestor with the event class; it has
	 * to guarantee its existence by holding a reference. This reference
	 * shall be released once the event is associated to a stream since,
	 * from that point, the event and its class will share the same
	 * lifetime.
	 */
	event->event_class = bt_get(event_class);
	event->clock_values = g_hash_table_new_full(g_direct_hash,
			g_direct_equal, bt_put, bt_put);

	if (validation_output.event_header_type) {
		BT_LOGD("Creating initial event header field: ft-addr=%p",
			validation_output.event_header_type);
		event_header =
			bt_field_create(validation_output.event_header_type);
		if (!event_header) {
			BT_LOGE_STR("Cannot create initial event header field object.");
			goto error;
		}
	}

	if (validation_output.stream_event_ctx_type) {
		BT_LOGD("Creating initial stream event context field: ft-addr=%p",
			validation_output.stream_event_ctx_type);
		stream_event_context = bt_field_create(
			validation_output.stream_event_ctx_type);
		if (!stream_event_context) {
			BT_LOGE_STR("Cannot create initial stream event context field object.");
			goto error;
		}
	}

	if (validation_output.event_context_type) {
		BT_LOGD("Creating initial event context field: ft-addr=%p",
			validation_output.event_context_type);
		event_context = bt_field_create(
			validation_output.event_context_type);
		if (!event_context) {
			BT_LOGE_STR("Cannot create initial event context field object.");
			goto error;
		}
	}

	if (validation_output.event_payload_type) {
		BT_LOGD("Creating initial event payload field: ft-addr=%p",
			validation_output.event_payload_type);
		event_payload = bt_field_create(
			validation_output.event_payload_type);
		if (!event_payload) {
			BT_LOGE_STR("Cannot create initial event payload field object.");
			goto error;
		}
	}

	/*
	 * At this point all the fields are created, potentially from
	 * validated copies of field types, so that the field types and
	 * fields can be replaced in the trace, stream class,
	 * event class, and created event.
	 */
	bt_validation_replace_types(trace, stream_class,
		event_class, &validation_output, validation_flags);
	BT_MOVE(event->event_header, event_header);
	BT_MOVE(event->stream_event_context, stream_event_context);
	BT_MOVE(event->context_payload, event_context);
	BT_MOVE(event->fields_payload, event_payload);

	/*
	 * Put what was not moved in bt_validation_replace_types().
	 */
	bt_validation_output_put_types(&validation_output);

	/*
	 * Freeze the stream class since the event header must not be changed
	 * anymore.
	 */
	bt_stream_class_freeze(stream_class);

	/*
	 * Mark stream class, and event class as valid since
	 * they're all frozen now.
	 */
	stream_class->valid = 1;
	event_class->valid = 1;

	/* Put stuff we borrowed from the event class */
	BT_PUT(stream_class);
	BT_PUT(trace);
	BT_LOGD("Created event object: addr=%p, event-class-name=\"%s\", "
		"event-class-id=%" PRId64,
		event, bt_event_class_get_name(event->event_class),
		bt_event_class_get_id(event_class));
	return event;

error:
	bt_validation_output_put_types(&validation_output);
	BT_PUT(event);
	BT_PUT(stream_class);
	BT_PUT(trace);
	BT_PUT(event_header);
	BT_PUT(stream_event_context);
	BT_PUT(event_context);
	BT_PUT(event_payload);
	assert(!packet_header_type);
	assert(!packet_context_type);
	assert(!event_header_type);
	assert(!stream_event_ctx_type);
	assert(!event_context_type);
	assert(!event_payload_type);

	return event;
}
Esempio n. 18
0
int bt_event_set_payload(struct bt_event *event,
		const char *name,
		struct bt_field *payload)
{
	int ret = 0;

	if (!event || !payload) {
		BT_LOGW("Invalid parameter: event or payload field is NULL: "
			"event-addr=%p, payload-field-addr=%p",
			event, payload);
		ret = -1;
		goto end;
	}

	if (event->frozen) {
		BT_LOGW("Invalid parameter: event is frozen: addr=%p, "
			"event-class-name=\"%s\", event-class-id=%" PRId64,
			event, bt_event_class_get_name(event->event_class),
			bt_event_class_get_id(event->event_class));
		ret = -1;
		goto end;
	}

	if (name) {
		ret = bt_field_structure_set_field_by_name(
			event->fields_payload, name, payload);
	} else {
		struct bt_field_type *payload_type;

		payload_type = bt_field_get_type(payload);

		if (bt_field_type_compare(payload_type,
				event->event_class->fields) == 0) {
			bt_put(event->fields_payload);
			bt_get(payload);
			event->fields_payload = payload;
		} else {
			BT_LOGW("Invalid parameter: payload field type is different from the expected field type: "
				"event-addr=%p, event-class-name=\"%s\", "
				"event-class-id=%" PRId64,
				event,
				bt_event_class_get_name(event->event_class),
				bt_event_class_get_id(event->event_class));
			ret = -1;
		}

		bt_put(payload_type);
	}

	if (ret) {
		BT_LOGW("Failed to set event's payload field: event-addr=%p, "
			"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
			"payload-field-name=\"%s\", payload-field-addr=%p",
			event, bt_event_class_get_name(event->event_class),
			bt_event_class_get_id(event->event_class),
			name, payload);
	} else {
		BT_LOGV("Set event's payload field: event-addr=%p, "
			"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
			"payload-field-name=\"%s\", payload-field-addr=%p",
			event, bt_event_class_get_name(event->event_class),
			bt_event_class_get_id(event->event_class),
			name, payload);
	}

end:
	return ret;
}
Esempio n. 19
0
int bt_event_set_header(struct bt_event *event,
		struct bt_field *header)
{
	int ret = 0;
	struct bt_field_type *field_type = NULL;
	struct bt_stream_class *stream_class = NULL;

	if (!event) {
		BT_LOGW_STR("Invalid parameter: event is NULL.");
		ret = -1;
		goto end;
	}

	if (event->frozen) {
		BT_LOGW("Invalid parameter: event is frozen: addr=%p, "
			"event-class-name=\"%s\", event-class-id=%" PRId64,
			event, bt_event_class_get_name(event->event_class),
			bt_event_class_get_id(event->event_class));
		ret = -1;
		goto end;
	}

	stream_class = (struct bt_stream_class *) bt_object_get_parent(
			event->event_class);
	/*
	 * Ensure the provided header's type matches the one registered to the
	 * stream class.
	 */
	if (header) {
		field_type = bt_field_get_type(header);
		if (bt_field_type_compare(field_type,
				stream_class->event_header_type)) {
			BT_LOGW("Invalid parameter: header field type is different from the expected field type: "
				"event-addr=%p, event-class-name=\"%s\", "
				"event-class-id=%" PRId64,
				event,
				bt_event_class_get_name(event->event_class),
				bt_event_class_get_id(event->event_class));
			ret = -1;
			goto end;
		}
	} else {
		if (stream_class->event_header_type) {
			BT_LOGW("Invalid parameter: setting no event header but event header field type is not NULL: "
				"event-addr=%p, event-class-name=\"%s\", "
				"event-class-id=%" PRId64 ", "
				"event-header-ft-addr=%p",
				event,
				bt_event_class_get_name(event->event_class),
				bt_event_class_get_id(event->event_class),
				stream_class->event_header_type);
			ret = -1;
			goto end;
		}
	}

	bt_put(event->event_header);
	event->event_header = bt_get(header);
	BT_LOGV("Set event's header field: event-addr=%p, "
		"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
		"header-field-addr=%p",
		event, bt_event_class_get_name(event->event_class),
		bt_event_class_get_id(event->event_class), header);
end:
	bt_put(stream_class);
	bt_put(field_type);
	return ret;
}
static
struct bt_plugin *bt_plugin_from_python_plugin_info(PyObject *plugin_info)
{
	struct bt_plugin *plugin = NULL;
	PyObject *py_name = NULL;
	PyObject *py_author = NULL;
	PyObject *py_description = NULL;
	PyObject *py_license = NULL;
	PyObject *py_version = NULL;
	PyObject *py_comp_class_addrs = NULL;
	const char *name = NULL;
	const char *author = NULL;
	const char *description = NULL;
	const char *license = NULL;
	unsigned int major = 0, minor = 0, patch = 0;
	const char *version_extra = NULL;
	int ret;

	assert(plugin_info);
	assert(python_state == PYTHON_STATE_FULLY_INITIALIZED);
	py_name = PyObject_GetAttrString(plugin_info, "name");
	if (!py_name) {
		BT_LOGW("Cannot find `name` attribute in Python plugin info object: "
			"py-plugin-info-addr=%p", plugin_info);
		goto error;
	}

	py_author = PyObject_GetAttrString(plugin_info, "author");
	if (!py_author) {
		BT_LOGW("Cannot find `author` attribute in Python plugin info object: "
			"py-plugin-info-addr=%p", plugin_info);
		goto error;
	}

	py_description = PyObject_GetAttrString(plugin_info, "description");
	if (!py_description) {
		BT_LOGW("Cannot find `desciption` attribute in Python plugin info object: "
			"py-plugin-info-addr=%p", plugin_info);
		goto error;
	}

	py_license = PyObject_GetAttrString(plugin_info, "license");
	if (!py_license) {
		BT_LOGW("Cannot find `license` attribute in Python plugin info object: "
			"py-plugin-info-addr=%p", plugin_info);
		goto error;
	}

	py_version = PyObject_GetAttrString(plugin_info, "version");
	if (!py_version) {
		BT_LOGW("Cannot find `version` attribute in Python plugin info object: "
			"py-plugin-info-addr=%p", plugin_info);
		goto error;
	}

	py_comp_class_addrs = PyObject_GetAttrString(plugin_info,
		"comp_class_addrs");
	if (!py_comp_class_addrs) {
		BT_LOGW("Cannot find `comp_class_addrs` attribute in Python plugin info object: "
			"py-plugin-info-addr=%p", plugin_info);
		goto error;
	}

	if (PyUnicode_Check(py_name)) {
		name = PyUnicode_AsUTF8(py_name);
		if (!name) {
			BT_LOGW("Cannot decode Python plugin name string: "
				"py-plugin-info-addr=%p", plugin_info);
			goto error;
		}
	} else {
		/* Plugin name is mandatory */
		BT_LOGW("Plugin name is not a string: "
			"py-plugin-info-addr=%p", plugin_info);
		goto error;
	}

	if (PyUnicode_Check(py_author)) {
		author = PyUnicode_AsUTF8(py_author);
		if (!author) {
			BT_LOGW("Cannot decode Python plugin author string: "
				"py-plugin-info-addr=%p", plugin_info);
			goto error;
		}
	}

	if (PyUnicode_Check(py_description)) {
		description = PyUnicode_AsUTF8(py_description);
		if (!description) {
			BT_LOGW("Cannot decode Python plugin description string: "
				"py-plugin-info-addr=%p", plugin_info);
			goto error;
		}
	}

	if (PyUnicode_Check(py_license)) {
		license = PyUnicode_AsUTF8(py_license);
		if (!license) {
			BT_LOGW("Cannot decode Python plugin license string: "
				"py-plugin-info-addr=%p", plugin_info);
			goto error;
		}
	}

	if (PyTuple_Check(py_version)) {
		if (PyTuple_Size(py_version) >= 3) {
			PyObject *py_major = PyTuple_GetItem(py_version, 0);
			PyObject *py_minor = PyTuple_GetItem(py_version, 1);
			PyObject *py_patch = PyTuple_GetItem(py_version, 2);

			assert(py_major);
			assert(py_minor);
			assert(py_patch);

			if (PyLong_Check(py_major)) {
				major = PyLong_AsUnsignedLong(py_major);
			}

			if (PyLong_Check(py_minor)) {
				minor = PyLong_AsUnsignedLong(py_minor);
			}

			if (PyLong_Check(py_patch)) {
				patch = PyLong_AsUnsignedLong(py_patch);
			}

			if (PyErr_Occurred()) {
				/* Overflow error, most probably */
				BT_LOGW("Invalid Python plugin version format: "
					"py-plugin-info-addr=%p", plugin_info);
				goto error;
			}
		}

		if (PyTuple_Size(py_version) >= 4) {
			PyObject *py_extra = PyTuple_GetItem(py_version, 3);

			assert(py_extra);

			if (PyUnicode_Check(py_extra)) {
				version_extra = PyUnicode_AsUTF8(py_extra);
				if (!version_extra) {
				BT_LOGW("Cannot decode Python plugin version's extra string: "
					"py-plugin-info-addr=%p", plugin_info);
					goto error;
				}
			}
		}
	}

	plugin = bt_plugin_create_empty(BT_PLUGIN_TYPE_PYTHON);
	if (!plugin) {
		BT_LOGE_STR("Cannot create empty plugin object.");
		goto error;
	}

	bt_plugin_set_name(plugin, name);

	if (description) {
		bt_plugin_set_description(plugin, description);
	}

	if (author) {
		bt_plugin_set_author(plugin, author);
	}

	if (license) {
		bt_plugin_set_license(plugin, license);
	}

	bt_plugin_set_version(plugin, major, minor, patch, version_extra);

	if (PyList_Check(py_comp_class_addrs)) {
		size_t i;

		for (i = 0; i < PyList_Size(py_comp_class_addrs); i++) {
			struct bt_component_class *comp_class;
			PyObject *py_comp_class_addr;

			py_comp_class_addr =
				PyList_GetItem(py_comp_class_addrs, i);
			assert(py_comp_class_addr);
			if (PyLong_Check(py_comp_class_addr)) {
				comp_class = (struct bt_component_class *)
					PyLong_AsUnsignedLongLong(py_comp_class_addr);
			} else {
				BT_LOGW("Component class address is not an integer in Python plugin info object: "
					"py-plugin-info-addr=%p, index=%zu",
					plugin_info, i);
				continue;
			}

			ret = bt_plugin_add_component_class(plugin, comp_class);
			if (ret < 0) {
				BT_LOGE("Cannot add component class to plugin: "
					"py-plugin-info-addr=%p, "
					"plugin-addr=%p, plugin-name=\"%s\", "
					"comp-class-addr=%p, "
					"comp-class-name=\"%s\", "
					"comp-class-type=%s",
					plugin_info,
					plugin, bt_plugin_get_name(plugin),
					comp_class,
					bt_component_class_get_name(comp_class),
					bt_component_class_type_string(
						bt_component_class_get_type(comp_class)));
				continue;
			}
		}
	}

	bt_plugin_freeze(plugin);

	goto end;

error:
	print_python_traceback_warn();
	pyerr_clear();
	BT_PUT(plugin);

end:
	Py_XDECREF(py_name);
	Py_XDECREF(py_author);
	Py_XDECREF(py_description);
	Py_XDECREF(py_license);
	Py_XDECREF(py_version);
	Py_XDECREF(py_comp_class_addrs);
	return plugin;
}
G_MODULE_EXPORT
struct bt_plugin_set *bt_plugin_python_create_all_from_file(const char *path)
{
	struct bt_plugin_set *plugin_set = NULL;
	struct bt_plugin *plugin = NULL;
	PyObject *py_plugin_info = NULL;
	gchar *basename = NULL;
	size_t path_len;

	assert(path);

	if (python_state == PYTHON_STATE_CANNOT_INITIALIZE) {
		/*
		 * We do not even care about the rest of the function
		 * here because we already know Python cannot be fully
		 * initialized.
		 */
		goto error;
	}

	BT_LOGD("Creating all Python plugins from file: path=\"%s\"", path);
	path_len = strlen(path);

	/* File name ends with `.py` */
	if (strncmp(path + path_len - PYTHON_PLUGIN_FILE_EXT_LEN,
			PYTHON_PLUGIN_FILE_EXT,
			PYTHON_PLUGIN_FILE_EXT_LEN) != 0) {
		BT_LOGD("Skipping non-Python file: path=\"%s\"", path);
		goto error;
	}

	/* File name starts with `bt_plugin_` */
	basename = g_path_get_basename(path);
	if (!basename) {
		BT_LOGW("Cannot get path's basename: path=\"%s\"", path);
		goto error;
	}

	if (strncmp(basename, PYTHON_PLUGIN_FILE_PREFIX,
			PYTHON_PLUGIN_FILE_PREFIX_LEN) != 0) {
		BT_LOGD("Skipping Python file not starting with `%s`: "
			"path=\"%s\"", PYTHON_PLUGIN_FILE_PREFIX, path);
		goto error;
	}

	/*
	 * Initialize Python now.
	 *
	 * This is not done in the library contructor because the
	 * interpreter is somewhat slow to initialize. If you don't
	 * have any potential Python plugins, you don't need to endure
	 * this waiting time everytime you load the library.
	 */
	init_python();
	if (python_state != PYTHON_STATE_FULLY_INITIALIZED) {
		/*
		 * For some reason we cannot initialize Python,
		 * import the required modules, and get the required
		 * attributes from them.
		 */
		BT_LOGI("Failed to initialize Python interpreter.");
		goto error;
	}

	/*
	 * Call bt2.py_plugin._try_load_plugin_module() with this path
	 * to get plugin info if the plugin is loadable and complete.
	 * This function returns None when there's an error, but just in
	 * case we also manually clear the last Python error state.
	 */
	BT_LOGD_STR("Getting Python plugin info object from Python module.");
	py_plugin_info = PyObject_CallFunction(py_try_load_plugin_module_func,
		"(s)", path);
	if (!py_plugin_info || py_plugin_info == Py_None) {
		BT_LOGW("Cannot load Python plugin: path=\"%s\"", path);
		print_python_traceback_warn();
		PyErr_Clear();
		goto error;
	}

	/*
	 * Get bt_plugin from plugin info object.
	 */
	plugin = bt_plugin_from_python_plugin_info(py_plugin_info);
	if (!plugin) {
		BT_LOGW("Cannot create plugin object from Python plugin info object: "
			"path=\"%s\", py-plugin-info-addr=%p",
			path, py_plugin_info);
		goto error;
	}

	bt_plugin_set_path(plugin, path);
	plugin_set = bt_plugin_set_create();
	if (!plugin_set) {
		BT_LOGE_STR("Cannot create empty plugin set.");
		goto error;
	}

	bt_plugin_set_add_plugin(plugin_set, plugin);
	BT_LOGD("Created all Python plugins from file: path=\"%s\", "
		"plugin-addr=%p, plugin-name=\"%s\"",
		path, plugin, bt_plugin_get_name(plugin));
	goto end;

error:
	BT_PUT(plugin_set);

end:
	bt_put(plugin);
	Py_XDECREF(py_plugin_info);
	g_free(basename);
	return plugin_set;
}
Esempio n. 22
0
static
enum bt_btr_status read_basic_float_and_call_cb(struct bt_btr *btr,
		const uint8_t *buf, size_t at)
{
	int ret;
	double dblval;
	int64_t field_size;
	enum bt_byte_order bo;
	enum bt_btr_status status = BT_BTR_STATUS_OK;

	field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type);
	bo = bt_field_type_get_byte_order(btr->cur_basic_field_type);
	btr->cur_bo = bo;

	switch (field_size) {
	case 32:
	{
		uint64_t v;
		union {
			uint32_t u;
			float f;
		} f32;

		ret = bt_field_type_floating_point_get_mantissa_digits(
			btr->cur_basic_field_type);
		assert(ret == 24);
		ret = bt_field_type_floating_point_get_exponent_digits(
			btr->cur_basic_field_type);
		assert(ret == 8);
		status = read_unsigned_bitfield(buf, at, field_size, bo, &v);
		if (status != BT_BTR_STATUS_OK) {
			BT_LOGW("Cannot read unsigned 32-bit bit array for floating point number field: "
				"btr-addr=%p, status=%s",
				btr, bt_btr_status_string(status));
			goto end;
		}

		f32.u = (uint32_t) v;
		dblval = (double) f32.f;
		break;
	}
	case 64:
	{
		union {
			uint64_t u;
			double d;
		} f64;

		ret = bt_field_type_floating_point_get_mantissa_digits(
			btr->cur_basic_field_type);
		assert(ret == 53);
		ret = bt_field_type_floating_point_get_exponent_digits(
			btr->cur_basic_field_type);
		assert(ret == 11);
		status = read_unsigned_bitfield(buf, at, field_size, bo,
			&f64.u);
		if (status != BT_BTR_STATUS_OK) {
			BT_LOGW("Cannot read unsigned 64-bit bit array for floating point number field: "
				"btr-addr=%p, status=%s",
				btr, bt_btr_status_string(status));
			goto end;
		}

		dblval = f64.d;
		break;
	}
	default:
		/* Only 32-bit and 64-bit fields are supported currently */
		BT_LOGW("Only 32-bit and 64-bit floating point number fields are supported: "
			"btr-addr=%p", btr);
		status = BT_BTR_STATUS_ERROR;
		goto end;
	}

	BT_LOGV("Read floating point number value: btr=%p, cur=%zu, val=%f",
		btr, at, dblval);

	if (btr->user.cbs.types.floating_point) {
		BT_LOGV("Calling user function (floating point number).");
		status = btr->user.cbs.types.floating_point(dblval,
			btr->cur_basic_field_type, btr->user.data);
		BT_LOGV("User function returned: status=%s",
			bt_btr_status_string(status));
		if (status != BT_BTR_STATUS_OK) {
			BT_LOGW("User function failed: btr-addr=%p, status=%s",
				btr, bt_btr_status_string(status));
		}
	}

end:
	return status;
}
Esempio n. 23
0
static
int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace,
		const char *path)
{
	int64_t stream_instance_id = -1;
	int64_t begin_ns = -1;
	struct ctf_fs_ds_file_group *ds_file_group = NULL;
	bool add_group = false;
	int ret;
	size_t i;
	struct ctf_fs_ds_file *ds_file = NULL;
	struct ctf_fs_ds_index *index = NULL;
	struct bt_msg_iter *msg_iter = NULL;
	struct ctf_stream_class *sc = NULL;
	struct bt_msg_iter_packet_properties props;

	msg_iter = bt_msg_iter_create(ctf_fs_trace->metadata->tc,
		bt_common_get_page_size() * 8, ctf_fs_ds_file_medops, NULL);
	if (!msg_iter) {
		BT_LOGE_STR("Cannot create a CTF message iterator.");
		goto error;
	}

	ds_file = ctf_fs_ds_file_create(ctf_fs_trace, NULL, msg_iter,
		NULL, path);
	if (!ds_file) {
		goto error;
	}

	ret = bt_msg_iter_get_packet_properties(ds_file->msg_iter, &props);
	if (ret) {
		BT_LOGE("Cannot get stream file's first packet's header and context fields (`%s`).",
			path);
		goto error;
	}

	sc = ctf_trace_class_borrow_stream_class_by_id(ds_file->metadata->tc,
		props.stream_class_id);
	BT_ASSERT(sc);
	stream_instance_id = props.data_stream_id;

	if (props.snapshots.beginning_clock != UINT64_C(-1)) {
		BT_ASSERT(sc->default_clock_class);
		ret = bt_util_clock_cycles_to_ns_from_origin(
			props.snapshots.beginning_clock,
			sc->default_clock_class->frequency,
			sc->default_clock_class->offset_seconds,
			sc->default_clock_class->offset_cycles, &begin_ns);
		if (ret) {
			BT_LOGE("Cannot convert clock cycles to nanoseconds from origin (`%s`).",
				path);
			goto error;
		}
	}

	index = ctf_fs_ds_file_build_index(ds_file);
	if (!index) {
		BT_LOGW("Failed to index CTF stream file \'%s\'",
			ds_file->file->path->str);
	}

	if (begin_ns == -1) {
		/*
		 * No beggining timestamp to sort the stream files
		 * within a stream file group, so consider that this
		 * file must be the only one within its group.
		 */
		stream_instance_id = -1;
	}

	if (stream_instance_id == -1) {
		/*
		 * No stream instance ID or no beginning timestamp:
		 * create a unique stream file group for this stream
		 * file because, even if there's a stream instance ID,
		 * there's no timestamp to order the file within its
		 * group.
		 */
		ds_file_group = ctf_fs_ds_file_group_create(ctf_fs_trace,
			sc, UINT64_C(-1));
		if (!ds_file_group) {
			goto error;
		}

		ret = ctf_fs_ds_file_group_add_ds_file_info(ds_file_group,
			path, begin_ns, index);
		/* Ownership of index is transferred. */
		index = NULL;
		if (ret) {
			goto error;
		}

		add_group = true;
		goto end;
	}

	BT_ASSERT(stream_instance_id != -1);
	BT_ASSERT(begin_ns != -1);

	/* Find an existing stream file group with this ID */
	for (i = 0; i < ctf_fs_trace->ds_file_groups->len; i++) {
		ds_file_group = g_ptr_array_index(
			ctf_fs_trace->ds_file_groups, i);

		if (ds_file_group->sc == sc &&
				ds_file_group->stream_id ==
				stream_instance_id) {
			break;
		}

		ds_file_group = NULL;
	}

	if (!ds_file_group) {
		ds_file_group = ctf_fs_ds_file_group_create(ctf_fs_trace,
			sc, stream_instance_id);
		if (!ds_file_group) {
			goto error;
		}

		add_group = true;
	}

	ret = ctf_fs_ds_file_group_add_ds_file_info(ds_file_group, path,
		begin_ns, index);
	index = NULL;
	if (ret) {
		goto error;
	}

	goto end;

error:
	ctf_fs_ds_file_group_destroy(ds_file_group);
	ds_file_group = NULL;
	ret = -1;

end:
	if (add_group && ds_file_group) {
		g_ptr_array_add(ctf_fs_trace->ds_file_groups, ds_file_group);
	}

	ctf_fs_ds_file_destroy(ds_file);

	if (msg_iter) {
		bt_msg_iter_destroy(msg_iter);
	}

	ctf_fs_ds_index_destroy(index);
	return ret;
}
Esempio n. 24
0
static inline
enum bt_btr_status read_basic_int_and_call(struct bt_btr *btr,
		const uint8_t *buf, size_t at,
		struct bt_field_type *int_type,
		struct bt_field_type *orig_type)
{
	bt_bool signd;
	int64_t field_size;
	enum bt_byte_order bo;
	enum bt_btr_status status = BT_BTR_STATUS_OK;

	signd = bt_field_type_integer_is_signed(int_type);
	field_size = get_basic_field_type_size(btr, int_type);
	if (field_size < 1) {
		BT_LOGW("Cannot get integer field type's size: "
			"btr=%p, at=%zu, ft-addr=%p",
			btr, at, int_type);
		status = BT_BTR_STATUS_ERROR;
		goto end;
	}

	bo = bt_field_type_get_byte_order(int_type);

	/*
	 * Update current byte order now because we could be reading
	 * the integer value of an enumeration type, and thus we know
	 * here the actual supporting integer type's byte order.
	 */
	btr->cur_bo = bo;

	if (signd) {
		int64_t v;

		status = read_signed_bitfield(buf, at, field_size, bo, &v);
		if (status != BT_BTR_STATUS_OK) {
			BT_LOGW("Cannot read signed bit array for signed integer field: "
				"btr-addr=%p, status=%s",
				btr, bt_btr_status_string(status));
			goto end;
		}

		if (btr->user.cbs.types.signed_int) {
			BT_LOGV("Calling user function (signed integer).");
			status = btr->user.cbs.types.signed_int(v,
				btr->cur_basic_field_type, btr->user.data);
			BT_LOGV("User function returned: status=%s",
				bt_btr_status_string(status));
			if (status != BT_BTR_STATUS_OK) {
				BT_LOGW("User function failed: "
					"btr-addr=%p, status=%s",
					btr, bt_btr_status_string(status));
			}
		}
	} else {
		uint64_t v;

		status = read_unsigned_bitfield(buf, at, field_size, bo, &v);
		if (status != BT_BTR_STATUS_OK) {
			BT_LOGW("Cannot read unsigned bit array for unsigned integer field: "
				"btr-addr=%p, status=%s",
				btr, bt_btr_status_string(status));
			goto end;
		}

		if (btr->user.cbs.types.unsigned_int) {
			BT_LOGV("Calling user function (unsigned integer).");
			status = btr->user.cbs.types.unsigned_int(v,
				btr->cur_basic_field_type, btr->user.data);
			BT_LOGV("User function returned: status=%s",
				bt_btr_status_string(status));
			if (status != BT_BTR_STATUS_OK) {
				BT_LOGW("User function failed: "
					"btr-addr=%p, status=%s",
					btr, bt_btr_status_string(status));
			}
		}
	}

end:
	return status;
}
Esempio n. 25
0
static inline
enum bt_btr_status read_basic_type_and_call_continue(struct bt_btr *btr,
		read_basic_and_call_cb_t read_basic_and_call_cb)
{
	size_t available;
	int64_t field_size;
	int64_t needed_bits;
	enum bt_btr_status status = BT_BTR_STATUS_OK;

	if (!at_least_one_bit_left(btr)) {
		BT_LOGV("Reached end of data: btr-addr=%p", btr);
		status = BT_BTR_STATUS_EOF;
		goto end;
	}

	field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type);
	if (field_size < 1) {
		BT_LOGW("Cannot get basic field type's size: "
			"btr-addr=%p, ft-addr=%p",
			btr, btr->cur_basic_field_type);
		status = BT_BTR_STATUS_ERROR;
		goto end;
	}

	available = available_bits(btr);
	needed_bits = field_size - btr->stitch.at;
	BT_LOGV("Continuing basic field decoding: "
		"btr-addr=%p, field-size=%" PRId64 ", needed-size=%" PRId64 ", "
		"available-size=%zu",
		btr, field_size, needed_bits, available);
	if (needed_bits <= available) {
		/* We have all the bits; append to stitch, then decode */
		stitch_append_from_buf(btr, needed_bits);
		status = read_basic_and_call_cb(btr, btr->stitch.buf,
			btr->stitch.offset);
		if (status != BT_BTR_STATUS_OK) {
			BT_LOGW("Cannot read basic field: "
				"btr-addr=%p, ft-addr=%p, status=%s",
				btr, btr->cur_basic_field_type,
				bt_btr_status_string(status));
			goto end;
		}

		if (stack_empty(btr->stack)) {
			/* Root is a basic type */
			btr->state = BTR_STATE_DONE;
		} else {
			/* Go to next field */
			stack_top(btr->stack)->index++;
			btr->state = BTR_STATE_NEXT_FIELD;
			btr->last_bo = btr->cur_bo;
		}
		goto end;
	}

	/* We are here; it means we don't have enough data to decode this */
	BT_LOGV_STR("Not enough data to read the next basic field: appending to stitch buffer.");
	stitch_append_from_remaining_buf(btr);
	status = BT_BTR_STATUS_EOF;

end:
	return status;
}
Esempio n. 26
0
static inline
enum bt_btr_status read_basic_type_and_call_begin(struct bt_btr *btr,
		read_basic_and_call_cb_t read_basic_and_call_cb)
{
	size_t available;
	int64_t field_size;
	enum bt_byte_order bo;
	enum bt_btr_status status = BT_BTR_STATUS_OK;

	if (!at_least_one_bit_left(btr)) {
		BT_LOGV("Reached end of data: btr-addr=%p", btr);
		status = BT_BTR_STATUS_EOF;
		goto end;
	}

	field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type);
	if (field_size < 1) {
		BT_LOGW("Cannot get basic field type's size: "
			"btr-addr=%p, ft-addr=%p",
			btr, btr->cur_basic_field_type);
		status = BT_BTR_STATUS_ERROR;
		goto end;
	}

	bo = bt_field_type_get_byte_order(btr->cur_basic_field_type);
	status = validate_contiguous_bo(btr, bo);
	if (status != BT_BTR_STATUS_OK) {
		/* validate_contiguous_bo() logs errors */
		goto end;
	}

	available = available_bits(btr);

	if (field_size <= available) {
		/* We have all the bits; decode and set now */
		assert(btr->buf.addr);
		status = read_basic_and_call_cb(btr, btr->buf.addr,
			buf_at_from_addr(btr));
		if (status != BT_BTR_STATUS_OK) {
			BT_LOGW("Cannot read basic field: "
				"btr-addr=%p, ft-addr=%p, status=%s",
				btr, btr->cur_basic_field_type,
				bt_btr_status_string(status));
			goto end;
		}

		consume_bits(btr, field_size);

		if (stack_empty(btr->stack)) {
			/* Root is a basic type */
			btr->state = BTR_STATE_DONE;
		} else {
			/* Go to next field */
			stack_top(btr->stack)->index++;
			btr->state = BTR_STATE_NEXT_FIELD;
			btr->last_bo = btr->cur_bo;
		}

		goto end;
	}

	/* We are here; it means we don't have enough data to decode this */
	BT_LOGV_STR("Not enough data to read the next basic field: setting stitch buffer.");
	stitch_set_from_remaining_buf(btr);
	btr->state = BTR_STATE_READ_BASIC_CONTINUE;
	status = BT_BTR_STATUS_EOF;

end:
	return status;
}
Esempio n. 27
0
static inline
enum bt_btr_status read_basic_string_type_and_call(
		struct bt_btr *btr, bool begin)
{
	size_t buf_at_bytes;
	const uint8_t *result;
	size_t available_bytes;
	const uint8_t *first_chr;
	enum bt_btr_status status = BT_BTR_STATUS_OK;

	if (!at_least_one_bit_left(btr)) {
		BT_LOGV("Reached end of data: btr-addr=%p", btr);
		status = BT_BTR_STATUS_EOF;
		goto end;
	}

	assert(buf_at_from_addr(btr) % 8 == 0);
	available_bytes = BITS_TO_BYTES_FLOOR(available_bits(btr));
	buf_at_bytes = BITS_TO_BYTES_FLOOR(buf_at_from_addr(btr));
	assert(btr->buf.addr);
	first_chr = &btr->buf.addr[buf_at_bytes];
	result = memchr(first_chr, '\0', available_bytes);

	if (begin && btr->user.cbs.types.string_begin) {
		BT_LOGV("Calling user function (string, beginning).");
		status = btr->user.cbs.types.string_begin(
			btr->cur_basic_field_type, btr->user.data);
		BT_LOGV("User function returned: status=%s",
			bt_btr_status_string(status));
		if (status != BT_BTR_STATUS_OK) {
			BT_LOGW("User function failed: btr-addr=%p, status=%s",
				btr, bt_btr_status_string(status));
			goto end;
		}
	}

	if (!result) {
		/* No null character yet */
		if (btr->user.cbs.types.string) {
			BT_LOGV("Calling user function (substring).");
			status = btr->user.cbs.types.string(
				(const char *) first_chr,
				available_bytes, btr->cur_basic_field_type,
				btr->user.data);
			BT_LOGV("User function returned: status=%s",
				bt_btr_status_string(status));
			if (status != BT_BTR_STATUS_OK) {
				BT_LOGW("User function failed: "
					"btr-addr=%p, status=%s",
					btr, bt_btr_status_string(status));
				goto end;
			}
		}

		consume_bits(btr, BYTES_TO_BITS(available_bytes));
		btr->state = BTR_STATE_READ_BASIC_CONTINUE;
		status = BT_BTR_STATUS_EOF;
	} else {
		/* Found the null character */
		size_t result_len = (size_t) (result - first_chr);

		if (btr->user.cbs.types.string && result_len) {
			BT_LOGV("Calling user function (substring).");
			status = btr->user.cbs.types.string(
				(const char *) first_chr,
				result_len, btr->cur_basic_field_type,
				btr->user.data);
			BT_LOGV("User function returned: status=%s",
				bt_btr_status_string(status));
			if (status != BT_BTR_STATUS_OK) {
				BT_LOGW("User function failed: "
					"btr-addr=%p, status=%s",
					btr, bt_btr_status_string(status));
				goto end;
			}
		}

		if (btr->user.cbs.types.string_end) {
			BT_LOGV("Calling user function (string, end).");
			status = btr->user.cbs.types.string_end(
				btr->cur_basic_field_type, btr->user.data);
			BT_LOGV("User function returned: status=%s",
				bt_btr_status_string(status));
			if (status != BT_BTR_STATUS_OK) {
				BT_LOGW("User function failed: "
					"btr-addr=%p, status=%s",
					btr, bt_btr_status_string(status));
				goto end;
			}
		}

		consume_bits(btr, BYTES_TO_BITS(result_len + 1));

		if (stack_empty(btr->stack)) {
			/* Root is a basic type */
			btr->state = BTR_STATE_DONE;
		} else {
			/* Go to next field */
			stack_top(btr->stack)->index++;
			btr->state = BTR_STATE_NEXT_FIELD;
			btr->last_bo = btr->cur_bo;
		}
	}

end:
	return status;
}
Esempio n. 28
0
BT_HIDDEN
struct ctf_metadata_decoder *ctf_metadata_decoder_create(
		const struct ctf_metadata_decoder_config *config,
		const char *name)
{
	struct ctf_metadata_decoder *mdec =
		g_new0(struct ctf_metadata_decoder, 1);
	struct ctf_metadata_decoder_config default_config = {
		.clock_class_offset_s = 0,
		.clock_class_offset_ns = 0,
	};

	if (!config) {
		config = &default_config;
	}

	BT_LOGD("Creating CTF metadata decoder: "
		"clock-class-offset-s=%" PRId64 ", "
		"clock-class-offset-ns=%" PRId64 ", name=\"%s\"",
		config->clock_class_offset_s, config->clock_class_offset_ns,
		name);

	if (!mdec) {
		BT_LOGE_STR("Failed to allocate one CTF metadata decoder.");
		goto end;
	}

	mdec->config = *config;
	mdec->visitor = ctf_visitor_generate_ir_create(config, name);
	if (!mdec->visitor) {
		BT_LOGE("Failed to create a CTF IR metadata AST visitor: "
			"mdec-addr=%p", mdec);
		ctf_metadata_decoder_destroy(mdec);
		mdec = NULL;
		goto end;
	}

	BT_LOGD("Creating CTF metadata decoder: "
		"clock-class-offset-s=%" PRId64 ", "
		"clock-class-offset-ns=%" PRId64 ", "
		"name=\"%s\", addr=%p",
		config->clock_class_offset_s, config->clock_class_offset_ns,
		name, mdec);

end:
	return mdec;
}

BT_HIDDEN
void ctf_metadata_decoder_destroy(struct ctf_metadata_decoder *mdec)
{
	if (!mdec) {
		return;
	}

	BT_LOGD("Destroying CTF metadata decoder: addr=%p", mdec);
	ctf_visitor_generate_ir_destroy(mdec->visitor);
	g_free(mdec);
}

BT_HIDDEN
enum ctf_metadata_decoder_status ctf_metadata_decoder_decode(
		struct ctf_metadata_decoder *mdec, FILE *fp)
{
	enum ctf_metadata_decoder_status status =
		CTF_METADATA_DECODER_STATUS_OK;
	int ret;
	struct ctf_scanner *scanner = NULL;
	char *buf = NULL;
	bool close_fp = false;

	assert(mdec);

	if (ctf_metadata_decoder_is_packetized(fp, &mdec->bo)) {
		BT_LOGD("Metadata stream is packetized: mdec-addr=%p", mdec);
		ret = ctf_metadata_decoder_packetized_file_stream_to_buf_with_mdec(
			mdec, fp, &buf, mdec->bo);
		if (ret) {
			BT_LOGE("Cannot decode packetized metadata packets to metadata text: "
				"mdec-addr=%p, ret=%d", mdec, ret);
			status = CTF_METADATA_DECODER_STATUS_ERROR;
			goto end;
		}

		if (strlen(buf) == 0) {
			/* An empty metadata packet is OK. */
			goto end;
		}

		/* Convert the real file pointer to a memory file pointer */
		fp = bt_fmemopen(buf, strlen(buf), "rb");
		close_fp = true;
		if (!fp) {
			BT_LOGE("Cannot memory-open metadata buffer: %s: "
				"mdec-addr=%p", strerror(errno), mdec);
			status = CTF_METADATA_DECODER_STATUS_ERROR;
			goto end;
		}
	} else {
		unsigned int major, minor;
		ssize_t nr_items;
		const long init_pos = ftell(fp);

		BT_LOGD("Metadata stream is plain text: mdec-addr=%p", mdec);

		if (init_pos < 0) {
			BT_LOGE_ERRNO("Failed to get current file position", ".");
			status = CTF_METADATA_DECODER_STATUS_ERROR;
			goto end;
		}

		/* Check text-only metadata header and version */
		nr_items = fscanf(fp, "/* CTF %10u.%10u", &major, &minor);
		if (nr_items < 2) {
			BT_LOGW("Missing \"/* CTF major.minor\" signature in plain text metadata file stream: "
				"mdec-addr=%p", mdec);
		}

		BT_LOGD("Found metadata stream version in signature: version=%u.%u", major, minor);

		if (!is_version_valid(major, minor)) {
			BT_LOGE("Invalid metadata version found in plain text signature: "
				"version=%u.%u, mdec-addr=%p", major, minor,
				mdec);
			status = CTF_METADATA_DECODER_STATUS_INVAL_VERSION;
			goto end;
		}

		if (fseek(fp, init_pos, SEEK_SET)) {
			BT_LOGE("Cannot seek metadata file stream to initial position: %s: "
				"mdec-addr=%p", strerror(errno), mdec);
			status = CTF_METADATA_DECODER_STATUS_ERROR;
			goto end;
		}
	}

	if (BT_LOG_ON_VERBOSE) {
		yydebug = 1;
	}

	/* Allocate a scanner and append the metadata text content */
	scanner = ctf_scanner_alloc();
	if (!scanner) {
		BT_LOGE("Cannot allocate a metadata lexical scanner: "
			"mdec-addr=%p", mdec);
		status = CTF_METADATA_DECODER_STATUS_ERROR;
		goto end;
	}

	assert(fp);
	ret = ctf_scanner_append_ast(scanner, fp);
	if (ret) {
		BT_LOGE("Cannot create the metadata AST out of the metadata text: "
			"mdec-addr=%p", mdec);
		status = CTF_METADATA_DECODER_STATUS_INCOMPLETE;
		goto end;
	}

	ret = ctf_visitor_semantic_check(0, &scanner->ast->root);
	if (ret) {
		BT_LOGE("Validation of the metadata semantics failed: "
			"mdec-addr=%p", mdec);
		status = CTF_METADATA_DECODER_STATUS_ERROR;
		goto end;
	}

	ret = ctf_visitor_generate_ir_visit_node(mdec->visitor,
		&scanner->ast->root);
	switch (ret) {
	case 0:
		/* Success */
		break;
	case -EINCOMPLETE:
		BT_LOGD("While visiting metadata AST: incomplete data: "
			"mdec-addr=%p", mdec);
		status = CTF_METADATA_DECODER_STATUS_INCOMPLETE;
		goto end;
	default:
		BT_LOGE("Failed to visit AST node to create CTF IR objects: "
			"mdec-addr=%p, ret=%d", mdec, ret);
		status = CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR;
		goto end;
	}

end:
	if (scanner) {
		ctf_scanner_free(scanner);
	}

	yydebug = 0;

	if (fp && close_fp) {
		if (fclose(fp)) {
			BT_LOGE("Cannot close metadata file stream: "
				"mdec-addr=%p", mdec);
		}
	}

	if (buf) {
		free(buf);
	}

	return status;
}

BT_HIDDEN
struct bt_trace *ctf_metadata_decoder_get_trace(
		struct ctf_metadata_decoder *mdec)
{
	return ctf_visitor_generate_ir_get_trace(mdec->visitor);
}
Esempio n. 29
0
int bt_event_set_packet(struct bt_event *event,
		struct bt_packet *packet)
{
	struct bt_stream_class *event_stream_class = NULL;
	struct bt_stream_class *packet_stream_class = NULL;
	struct bt_stream *stream = NULL;
	int ret = 0;

	if (!event || !packet) {
		BT_LOGW("Invalid parameter: event or packet is NULL: "
			"event-addr=%p, packet-addr=%p",
			event, packet);
		ret = -1;
		goto end;
	}

	if (event->frozen) {
		BT_LOGW("Invalid parameter: event is frozen: addr=%p, "
			"event-class-name=\"%s\", event-class-id=%" PRId64,
			event, bt_event_class_get_name(event->event_class),
			bt_event_class_get_id(event->event_class));
		ret = -1;
		goto end;
	}

	/*
	 * Make sure the new packet was created by this event's
	 * stream, if it is set.
	 */
	stream = bt_event_get_stream(event);
	if (stream) {
		if (packet->stream != stream) {
			BT_LOGW("Invalid parameter: packet's stream and event's stream differ: "
				"event-addr=%p, event-class-name=\"%s\", "
				"event-class-id=%" PRId64 ", packet-stream-addr=%p, "
				"event-stream-addr=%p",
				event, bt_event_class_get_name(event->event_class),
				bt_event_class_get_id(event->event_class),
				packet->stream, stream);
			ret = -1;
			goto end;
		}
	} else {
		event_stream_class =
			bt_event_class_get_stream_class(event->event_class);
		packet_stream_class =
			bt_stream_get_class(packet->stream);

		assert(event_stream_class);
		assert(packet_stream_class);

		if (event_stream_class != packet_stream_class) {
			BT_LOGW("Invalid parameter: packet's stream class and event's stream class differ: "
				"event-addr=%p, event-class-name=\"%s\", "
				"event-class-id=%" PRId64 ", packet-stream-class-addr=%p, "
				"event-stream-class-addr=%p",
				event, bt_event_class_get_name(event->event_class),
				bt_event_class_get_id(event->event_class),
				packet_stream_class, event_stream_class);
			ret = -1;
			goto end;
		}
	}

	bt_get(packet);
	BT_MOVE(event->packet, packet);
	BT_LOGV("Set event's packet: event-addr=%p, "
		"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
		"packet-addr=%p",
		event, bt_event_class_get_name(event->event_class),
		bt_event_class_get_id(event->event_class), packet);

end:
	BT_PUT(stream);
	BT_PUT(event_stream_class);
	BT_PUT(packet_stream_class);

	return ret;
}
Esempio n. 30
0
BT_HIDDEN
int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
		struct metadata_context *context)
{
	int ret = 0;
	struct bt_ctf_value *attr_value = NULL;

	BT_ASSERT(event_class);
	BT_ASSERT(context);
	BT_LOGD("Serializing event class's metadata: "
		"event-class-addr=%p, event-class-name=\"%s\", "
		"event-class-id=%" PRId64 ", metadata-context-addr=%p",
		event_class, bt_ctf_event_class_get_name(event_class),
		bt_ctf_event_class_get_id(event_class), context);
	context->current_indentation_level = 1;
	g_string_assign(context->field_name, "");
	g_string_append(context->string, "event {\n");

	/* Serialize attributes */
	g_string_append_printf(context->string, "\tname = \"%s\";\n",
		event_class->common.name->str);
	BT_ASSERT(event_class->common.id >= 0);
	g_string_append_printf(context->string, "\tid = %" PRId64 ";\n",
		event_class->common.id);
	g_string_append_printf(context->string, "\tstream_id = %" PRId64 ";\n",
		bt_ctf_stream_class_common_get_id(
			bt_ctf_event_class_common_borrow_stream_class(
				BT_CTF_TO_COMMON(event_class))));

	if (event_class->common.log_level !=
			BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED) {
		g_string_append_printf(context->string, "\tloglevel = %d;\n",
			(int) event_class->common.log_level);
	}

	if (event_class->common.emf_uri->len > 0) {
		g_string_append_printf(context->string, "\tmodel.emf.uri = \"%s\";\n",
			event_class->common.emf_uri->str);
	}

	/* Serialize context field type */
	if (event_class->common.context_field_type) {
		g_string_append(context->string, "\tcontext := ");
		BT_LOGD_STR("Serializing event class's context field type metadata.");
		ret = bt_ctf_field_type_serialize_recursive(
			(void *) event_class->common.context_field_type,
			context);
		if (ret) {
			BT_LOGW("Cannot serialize event class's context field type's metadata: "
				"ret=%d", ret);
			goto end;
		}
		g_string_append(context->string, ";\n");
	}

	/* Serialize payload field type */
	if (event_class->common.payload_field_type) {
		g_string_append(context->string, "\tfields := ");
		BT_LOGD_STR("Serializing event class's payload field type metadata.");
		ret = bt_ctf_field_type_serialize_recursive(
			(void *) event_class->common.payload_field_type,
			context);
		if (ret) {
			BT_LOGW("Cannot serialize event class's payload field type's metadata: "
				"ret=%d", ret);
			goto end;
		}
		g_string_append(context->string, ";\n");
	}

	g_string_append(context->string, "};\n\n");

end:
	context->current_indentation_level = 0;
	BT_CTF_OBJECT_PUT_REF_AND_RESET(attr_value);
	return ret;
}