ir: add bt_ctf_field_type_variant_set_tag()
[babeltrace.git] / formats / ctf / ir / event-types.c
index 195f935d521a11f86ed58dd2aecb6c03b985f957..78d0fa0daa6b4b6b14fd8a9445a7126445f94bf3 100644 (file)
@@ -1955,6 +1955,56 @@ end:
        return copy;
 }
 
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_path_create(void)
+{
+       struct bt_ctf_field_path *field_path = NULL;
+
+       field_path = g_new0(struct bt_ctf_field_path, 1);
+       if (!field_path) {
+               goto end;
+       }
+
+       field_path->root = CTF_NODE_UNKNOWN;
+       field_path->path_indexes = g_array_new(TRUE, FALSE, sizeof(int));
+       if (!field_path->path_indexes) {
+               bt_ctf_field_path_destroy(field_path);
+               field_path = NULL;
+       }
+end:
+       return field_path;
+}
+
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_path_copy(
+               struct bt_ctf_field_path *path)
+{
+       struct bt_ctf_field_path *new_path = bt_ctf_field_path_create();
+
+       if (!new_path) {
+               goto end;
+       }
+
+       new_path->root = path->root;
+       g_array_insert_vals(new_path->path_indexes, 0,
+               path->path_indexes->data, path->path_indexes->len);
+end:
+       return new_path;
+}
+
+BT_HIDDEN
+void bt_ctf_field_path_destroy(struct bt_ctf_field_path *path)
+{
+       if (!path) {
+               return;
+       }
+
+       if (path->path_indexes) {
+               g_array_free(path->path_indexes, TRUE);
+       }
+       g_free(path);
+}
 
 BT_HIDDEN
 int bt_ctf_field_type_structure_get_field_name_index(
@@ -1988,6 +2038,110 @@ int bt_ctf_field_type_structure_get_field_name_index(
 end:
        return ret;
 }
+
+BT_HIDDEN
+int bt_ctf_field_type_variant_get_field_name_index(
+               struct bt_ctf_field_type *type, const char *name)
+{
+       int ret;
+       size_t index;
+       GQuark name_quark;
+       struct bt_ctf_field_type_variant *variant;
+
+       if (!type || !name ||
+               bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
+               ret = -1;
+               goto end;
+       }
+
+       name_quark = g_quark_try_string(name);
+       if (!name_quark) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant,
+               parent);
+       if (!g_hash_table_lookup_extended(variant->field_name_to_index,
+               GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
+               ret = -1;
+               goto end;
+       }
+       ret = (int) index;
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_sequence_set_length_field_path(
+               struct bt_ctf_field_type *type,
+               struct bt_ctf_field_path *path)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_sequence *sequence;
+
+       if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_SEQUENCE) {
+               ret = -1;
+               goto end;
+       }
+
+       sequence = container_of(type, struct bt_ctf_field_type_sequence,
+               parent);
+       if (sequence->length_field_path) {
+               bt_ctf_field_path_destroy(sequence->length_field_path);
+       }
+       sequence->length_field_path = path;
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
+               struct bt_ctf_field_path *path)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_variant *variant;
+
+       if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant,
+               parent);
+       if (variant->tag_path) {
+               bt_ctf_field_path_destroy(variant->tag_path);
+       }
+       variant->tag_path = path;
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_variant_set_tag(struct bt_ctf_field_type *type,
+               struct bt_ctf_field_type *tag)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_variant *variant;
+
+       if (!type || !tag || type->frozen ||
+               bt_ctf_field_type_get_type_id(tag) != CTF_TYPE_ENUM) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant,
+               parent);
+       bt_ctf_field_type_get(tag);
+       if (variant->tag) {
+               bt_ctf_field_type_put(&variant->tag->parent);
+       }
+       variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
+               parent);
+end:
+       return ret;
+}
+
 static
 void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *ref)
 {
@@ -2071,6 +2225,7 @@ void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *ref)
        g_hash_table_destroy(variant->field_name_to_index);
        g_string_free(variant->tag_name, TRUE);
        bt_ctf_field_type_put(&variant->tag->parent);
+       bt_ctf_field_path_destroy(variant->tag_path);
        g_free(variant);
 }
 
@@ -2104,6 +2259,7 @@ void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *ref)
                struct bt_ctf_field_type_sequence, parent);
        bt_ctf_field_type_put(sequence->element_type);
        g_string_free(sequence->length_field_name, TRUE);
+       bt_ctf_field_path_destroy(sequence->length_field_path);
        g_free(sequence);
 }
 
@@ -2887,6 +3043,13 @@ struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
        }
 
        copy_variant->declaration = variant->declaration;
+       if (variant->tag_path) {
+               copy_variant->tag_path = bt_ctf_field_path_copy(
+                       variant->tag_path);
+               if (!copy_variant->tag_path) {
+                       goto error;
+               }
+       }
 end:
        if (copy_tag) {
                bt_ctf_field_type_put(copy_tag);
@@ -2956,12 +3119,25 @@ struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
        copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
                parent);
        copy_sequence->declaration = sequence->declaration;
+       if (sequence->length_field_path) {
+               copy_sequence->length_field_path = bt_ctf_field_path_copy(
+                       sequence->length_field_path);
+               if (!copy_sequence->length_field_path) {
+                       goto error;
+               }
+       }
 end:
        if (copy_element) {
                bt_ctf_field_type_put(copy_element);
        }
 
        return copy;
+error:
+       if (copy) {
+               bt_ctf_field_type_put(copy);
+               copy = NULL;
+       }
+       goto end;
 }
 
 static
This page took 0.025003 seconds and 4 git commands to generate.