From cd95e351b813fe155d6694c87b7eea800f4f06b9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Thu, 22 May 2014 15:02:02 -0400 Subject: [PATCH] Implement CTF-IR event fields getters MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémie Galarneau --- formats/ctf/ir/event-fields.c | 238 +++++++++++++++++++++++ include/babeltrace/ctf-ir/event-fields.h | 109 ++++++++++- tests/lib/test_ctf_writer.c | 8 +- 3 files changed, 351 insertions(+), 4 deletions(-) diff --git a/formats/ctf/ir/event-fields.c b/formats/ctf/ir/event-fields.c index 17616a51..973c9bdd 100644 --- a/formats/ctf/ir/event-fields.c +++ b/formats/ctf/ir/event-fields.c @@ -212,6 +212,42 @@ void bt_ctf_field_put(struct bt_ctf_field *field) } } +struct bt_ctf_field_type *bt_ctf_field_get_type(struct bt_ctf_field *field) +{ + struct bt_ctf_field_type *ret = NULL; + + if (!field) { + goto end; + } + + ret = field->type; + bt_ctf_field_type_get(ret); +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; +} + int bt_ctf_field_sequence_set_length(struct bt_ctf_field *field, struct bt_ctf_field *length_field) { @@ -305,6 +341,59 @@ error: return new_field; } +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; +} + BT_HIDDEN int bt_ctf_field_structure_set_field(struct bt_ctf_field *field, const char *name, struct bt_ctf_field *value) @@ -498,6 +587,89 @@ end: return container; } +const char *bt_ctf_field_enumeration_get_mapping_name( + struct bt_ctf_field *field) +{ + int ret; + const char *name = NULL; + struct bt_ctf_field *container = NULL; + struct bt_ctf_field_type *container_type = NULL; + struct bt_ctf_field_type_integer *integer_type = NULL; + struct bt_ctf_field_type_enumeration *enumeration_type = NULL; + + container = bt_ctf_field_enumeration_get_container(field); + if (!container) { + goto end; + } + + container_type = bt_ctf_field_get_type(container); + if (!container_type) { + goto error_put_container; + } + + integer_type = container_of(container_type, + struct bt_ctf_field_type_integer, parent); + enumeration_type = container_of(field->type, + struct bt_ctf_field_type_enumeration, parent); + + if (integer_type->declaration.signedness) { + uint64_t value; + ret = bt_ctf_field_unsigned_integer_get_value(container, + &value); + if (ret) { + goto error_put_container_type; + } + + name = bt_ctf_field_type_enumeration_get_mapping_name_unsigned( + enumeration_type, value); + } else { + int64_t value; + ret = bt_ctf_field_signed_integer_get_value(container, + &value); + if (ret) { + goto error_put_container_type; + } + + name = bt_ctf_field_type_enumeration_get_mapping_name_signed( + enumeration_type, value); + } + +error_put_container_type: + bt_ctf_field_type_put(container_type); +error_put_container: + bt_ctf_field_put(container); +end: + return name; +} + +int bt_ctf_field_signed_integer_get_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; + + 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._signed; +end: + return ret; +} + int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *field, int64_t value) { @@ -536,6 +708,34 @@ end: return ret; } +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; +} + int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *field, uint64_t value) { @@ -573,6 +773,26 @@ end: return ret; } +int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field, + double *value) +{ + int ret = 0; + struct bt_ctf_field_floating_point *floating_point; + + if (!field || !value || !field->payload_set || + 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); + *value = floating_point->definition.value; +end: + return ret; +} + int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field, double value) { @@ -593,6 +813,24 @@ end: 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; +} + int bt_ctf_field_string_set_value(struct bt_ctf_field *field, const char *value) { diff --git a/include/babeltrace/ctf-ir/event-fields.h b/include/babeltrace/ctf-ir/event-fields.h index 1094864d..c617dac2 100644 --- a/include/babeltrace/ctf-ir/event-fields.h +++ b/include/babeltrace/ctf-ir/event-fields.h @@ -31,6 +31,7 @@ */ #include +#include #ifdef __cplusplus extern "C" { @@ -68,6 +69,21 @@ extern struct bt_ctf_field *bt_ctf_field_create( extern struct bt_ctf_field *bt_ctf_field_structure_get_field( struct bt_ctf_field *structure, const char *name); +/* + * bt_ctf_field_structure_get_field_by_index: get a structure's field by index. + * + * Get the structure's field corresponding to the provided field name. + * bt_ctf_field_put() must be called on the returned value. + * The indexes are the same as those provided for bt_ctf_field_type_structure. + * + * @param structure Structure field instance. + * @param index Index of the field in the provided structure. + * + * Returns a field instance on success, NULL on error. + */ +extern struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index( + struct bt_ctf_field *structure, size_t index); + /* * bt_ctf_field_array_get_field: get an array's field at position "index". * @@ -82,6 +98,18 @@ extern struct bt_ctf_field *bt_ctf_field_structure_get_field( extern struct bt_ctf_field *bt_ctf_field_array_get_field( struct bt_ctf_field *array, uint64_t index); +/* + * bt_ctf_field_sequence_get_length: get a sequence's length. + * + * Get the sequence's length field. + * + * @param sequence Sequence field instance. + * + * Returns a field instance on success, NULL if a length was never set. + */ +extern struct bt_ctf_field *bt_ctf_field_sequence_get_length( + struct bt_ctf_field *sequence); + /* * bt_ctf_field_sequence_set_length: set a sequence's length. * @@ -90,7 +118,7 @@ extern struct bt_ctf_field *bt_ctf_field_array_get_field( * @param sequence Sequence field instance. * @param length_field Integer field instance indicating the sequence's length. * - * Returns a field instance on success, NULL on error. + * Returns 0 on success, a negative value on error. */ extern int bt_ctf_field_sequence_set_length(struct bt_ctf_field *sequence, struct bt_ctf_field *length_field); @@ -138,6 +166,33 @@ extern struct bt_ctf_field *bt_ctf_field_variant_get_field( extern struct bt_ctf_field *bt_ctf_field_enumeration_get_container( struct bt_ctf_field *enumeration); +/* + * bt_ctf_field_enumeration_get_mapping_name: get an enumeration field's mapping + * name. + * + * Return the enumeration's underlying container field (an integer). + * bt_ctf_field_put() must be called on the returned value. + * + * @param enumeration Enumeration field instance. + * + * Returns a field instance on success, NULL on error. + */ +extern const char *bt_ctf_field_enumeration_get_mapping_name( + struct bt_ctf_field *enumeration); + +/* + * bt_ctf_field_signed_integer_get_value: get a signed integer field's value + * + * Get a signed integer field's value. + * + * @param integer Signed integer field instance. + * @param value Pointer to a signed integer where the value will be stored. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field *integer, + int64_t *value); + /* * bt_ctf_field_signed_integer_set_value: set a signed integer field's value * @@ -152,6 +207,19 @@ extern struct bt_ctf_field *bt_ctf_field_enumeration_get_container( extern int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *integer, int64_t value); +/* + * bt_ctf_field_unsigned_integer_get_value: get unsigned integer field's value + * + * Get an unsigned integer field's value. + * + * @param integer Unsigned integer field instance. + * @param value Pointer to an unsigned integer where the value will be stored. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *integer, + uint64_t *value); + /* * bt_ctf_field_unsigned_integer_set_value: set unsigned integer field's value * @@ -166,6 +234,19 @@ extern int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *integer, extern int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *integer, uint64_t value); +/* + * bt_ctf_field_floating_point_get_value: get a floating point field's value + * + * Get a floating point field's value. + * + * @param floating_point Floating point field instance. + * @param value Pointer to a double where the value will be stored. + * + * Returns 0 on success, a negative value on error. + */ +extern int bt_ctf_field_floating_point_get_value( + struct bt_ctf_field *floating_point, double *value); + /* * bt_ctf_field_floating_point_set_value: set a floating point field's value * @@ -181,19 +262,41 @@ extern int bt_ctf_field_floating_point_set_value( struct bt_ctf_field *floating_point, double value); +/* + * bt_ctf_field_string_get_value: get a string field's value + * + * Get a string field's value. + * + * @param string_field String field instance. + * + * Returns the string's value, NULL if unset. + */ +extern const char *bt_ctf_field_string_get_value( + struct bt_ctf_field *string_field); + /* * bt_ctf_field_string_set_value: set a string field's value * * Set a string field's value. * - * @param string String field instance. + * @param string_field String field instance. * @param value String field value (will be copied). * * Returns 0 on success, a negative value on error. */ -extern int bt_ctf_field_string_set_value(struct bt_ctf_field *string, +extern int bt_ctf_field_string_set_value(struct bt_ctf_field *string_field, const char *value); +/* + * bt_ctf_field_get_type: get a field's type + * + * @param field Field intance. + * + * Returns a field type instance on success, NULL on error. + */ +extern struct bt_ctf_field_type *bt_ctf_field_get_type( + struct bt_ctf_field *field); + /* * bt_ctf_field_get and bt_ctf_field_put: increment and decrement the * field's reference count. diff --git a/tests/lib/test_ctf_writer.c b/tests/lib/test_ctf_writer.c index 00224beb..e41af56a 100644 --- a/tests/lib/test_ctf_writer.c +++ b/tests/lib/test_ctf_writer.c @@ -359,7 +359,7 @@ void append_complex_event(struct bt_ctf_stream_class *stream_class, struct bt_ctf_field *uint_35_field, *int_16_field, *a_string_field, *inner_structure_field, *complex_structure_field, *a_sequence_field, *enum_variant_field, *enum_container_field, - *variant_field; + *variant_field, *ret_field; bt_ctf_field_type_set_alignment(int_16_type, 32); bt_ctf_field_type_integer_set_signed(int_16_type, 1); @@ -463,6 +463,11 @@ void append_complex_event(struct bt_ctf_stream_class *stream_class, SEQUENCE_TEST_LENGTH); ok(bt_ctf_field_sequence_set_length(a_sequence_field, uint_35_field) == 0, "Set a sequence field's length"); + ret_field = bt_ctf_field_sequence_get_length(a_sequence_field); + ok(ret_field == uint_35_field, + "bt_ctf_field_sequence_get_length returns the correct length field"); + ok(bt_ctf_field_sequence_get_length(NULL) == NULL, + "bt_ctf_field_sequence_get_length properly handles NULL"); for (i = 0; i < SEQUENCE_TEST_LENGTH; i++) { int_16_field = bt_ctf_field_sequence_get_field( @@ -485,6 +490,7 @@ void append_complex_event(struct bt_ctf_stream_class *stream_class, bt_ctf_field_put(enum_variant_field); bt_ctf_field_put(enum_container_field); bt_ctf_field_put(variant_field); + bt_ctf_field_put(ret_field); bt_ctf_field_type_put(uint_35_type); bt_ctf_field_type_put(int_16_type); bt_ctf_field_type_put(string_type); -- 2.34.1