Implement CTF-IR event fields getters
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 22 May 2014 19:02:02 +0000 (15:02 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 27 Jun 2014 20:07:25 +0000 (16:07 -0400)
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
formats/ctf/ir/event-fields.c
include/babeltrace/ctf-ir/event-fields.h
tests/lib/test_ctf_writer.c

index 17616a51be4f21baa3b7faa1d0f6098d8724926a..973c9bdd395338bbc5370355393dd61a374fd85c 100644 (file)
@@ -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)
 {
index 1094864d10a5f5b8b4a25375d053aa33fbbcce31..c617dac2c11130d233c30fd090a66e604bd398d0 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <stdint.h>
+#include <stddef.h>
 
 #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.
index 00224bebf9c9461f8bf23345a5dfb61984a59e1d..e41af56a6b91e784a24d4f15a1792b46bb23046f 100644 (file)
@@ -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);
This page took 0.032839 seconds and 4 git commands to generate.