Add structures
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 5 Oct 2010 02:50:13 +0000 (22:50 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 5 Oct 2010 02:50:13 +0000 (22:50 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
formats/ctf/ctf.c
formats/ctf/types/struct.c
include/babeltrace/ctf/types.h
include/babeltrace/format.h
include/babeltrace/types.h
types/enum.c
types/struct.c [new file with mode: 0644]

index eec36148573eef6a3283808aff916ba22d08ef58..63fe47e3cd6382b8f2a31eac7c8e31acc4d7468d 100644 (file)
@@ -39,6 +39,8 @@ static const struct format ctf_format = {
        .string_free_temp = ctf_string_free_temp,
        .enum_read = ctf_enum_read,
        .enum_write = ctf_enum_write,
+       .struct_begin = ctf_struct_begin,
+       .struct_end = ctf_struct_end,
 };
 
 void ctf_init(void)
index 8d248da146bac3d109e77edec789b3a0ade39d25..729c456e63c5769663ce720fadf7aa7a2b7e0ccb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Common Trace Format
  *
- * Structure write/access functions.
+ * Structure format access functions.
  *
  * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  *
 #include <babeltrace/ctf/types.h>
 #include <glib.h>
 
+void ctf_struct_begin(struct stream_pos *pos,
+                     const struct type_class_struct *struct_class)
+{
+       align_pos(pos, struct_class->p.alignment);
+}
 
+void ctf_struct_end(struct stream_pos *pos,
+                   const struct type_class_struct *struct_class)
+{
+}
index 49427a5bba4d3d33116528b34f7b82c9e5ae6f3d..75b8bd3e28932f3f1d355a498d6bac82378ac457 100644 (file)
@@ -72,5 +72,9 @@ GQuark ctf_enum_read(struct stream_pos *pos,
 void ctf_enum_write(struct stream_pos *pos,
                const struct type_class_enum *dest,
                GQuark q);
+void ctf_struct_begin(struct stream_pos *pos,
+                     const struct type_class_struct *struct_class);
+void ctf_struct_end(struct stream_pos *pos,
+                   const struct type_class_struct *struct_class);
 
 #endif /* _BABELTRACE_CTF_TYPES_H */
index 5909ce39f0bf3599ea720829d15cf3f050a449ff..bc2bdb067c0b75b1041738d2317ccd1a4bf7e03c 100644 (file)
@@ -62,7 +62,10 @@ struct format {
        void (*enum_write)(struct stream_pos *pos,
                           const struct type_class_enum *dest,
                           GQuark q);
-
+       void (*struct_begin)(struct stream_pos *pos,
+                            const struct type_class_struct *struct_class);
+       void (*struct_end)(struct stream_pos *pos,
+                          const struct type_class_struct *struct_class);
 };
 
 struct format *bt_lookup_format(GQuark qname);
index 305d553d700d9a8a9588f22bac9c02580b603791..ada6c6d1513d0e93ed880a3465e94fc68ed1dc20 100644 (file)
@@ -27,6 +27,9 @@
 #include <babeltrace/align.h>
 #include <string.h>
 
+/* Preallocate this many fields for structures */
+#define DEFAULT_NR_STRUCT_FIELDS 8
+
 /*
  * Always update stream_pos with move_pos and init_pos.
  */
@@ -128,9 +131,27 @@ struct type_class_string {
        struct type_class p;
 };
 
+struct field {
+       GQuark name;
+       struct type_class *type_class;
+};
+
 struct type_class_struct {
        struct type_class p;
-       /* TODO */
+       GHashTable *fields_by_name;     /* Tuples (field name, field index) */
+       GArray *fields;                 /* Array of fields */
+};
+
+struct type_class_array {
+       struct type_class p;
+       size_t len;
+       struct type_class *elem;
+};
+
+struct type_class_sequence {
+       struct type_class p;
+       struct type_class_integer *len;
+       struct type_class *elem;
 };
 
 struct type_class *ctf_lookup_type(GQuark qname);
@@ -175,4 +196,32 @@ struct type_class_enum *enum_type_new(const char *name,
                                      size_t alignment);
 void enum_type_free(struct type_class_enum *enum_class);
 
+struct type_class_struct *struct_type_new(const char *name);
+void struct_type_free(struct type_class_struct *struct_class);
+void struct_type_add_field(struct type_class_struct *struct_class,
+                          GQuark field_name,
+                          struct type_class *type_class);
+/*
+ * Returns the index of a field within a structure.
+ */
+unsigned long
+struct_type_lookup_field_index(struct type_class_struct *struct_class,
+                              GQuark field_name);
+/*
+ * field returned only valid as long as the field structure is not appended to.
+ */
+struct field *
+struct_type_get_field_from_index(struct type_class_struct *struct_class,
+                                unsigned long index);
+
+struct type_class_array *array_type_new(const char *name,
+                                       size_t len,
+                                       struct type_class *elem_class);
+void array_type_free(struct type_class_array *array_class);
+
+struct type_class_sequence *sequence_type_new(const char *name,
+                                       struct type_class_integer *int_class, 
+                                       struct type_class *elem_class);
+void array_type_free(struct type_class_array *array_class);
+
 #endif /* _BABELTRACE_TYPES_H */
index 8e8ef694fc4100c865dc0df5cfb7d211be9f90dc..57ecbdd179f484c771fea4b27d95ac597d14233a 100644 (file)
@@ -203,8 +203,8 @@ struct type_class_enum *enum_type_new(const char *name,
        int ret;
 
        enum_class = g_new(struct type_class_enum, 1);
-       enum_class->table.value_to_quark = g_hash_table(enum_val_hash,
-                                                       enum_val_equal);
+       enum_class->table.value_to_quark = g_hash_table_new(enum_val_hash,
+                                                           enum_val_equal);
        enum_class->table.quark_to_value = g_hash_table_new_full(g_direct_hash,
                                                        g_direct_equal,
                                                        NULL, enum_val_free);
diff --git a/types/struct.c b/types/struct.c
new file mode 100644 (file)
index 0000000..8c1a583
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * BabelTrace - Structure Type Converter
+ *
+ * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <babeltrace/compiler.h>
+#include <babeltrace/types.h>
+
+void struct_copy(struct stream_pos *dest, const struct format *fdest, 
+                struct stream_pos *src, const struct format *fsrc,
+                const struct type_class *type_class)
+{
+       struct type_class_struct *struct_class =
+               container_of(type_class, struct type_class_struct, p);
+       unsigned int i;
+
+       fsrc->struct_begin(src, struct_class);
+       fdest->struct_begin(dest, struct_class);
+
+       for (i = 0; i < struct_class->fields->len; i++) {
+               struct field *field = &g_array_index(struct_class->fields,
+                                                    struct field, i);
+               struct type_class *field_class = field->type_class;
+
+               field_class->copy(dest, fdest, src, fsrc, type_class);
+
+       }
+       fsrc->struct_end(src, struct_class);
+       fdest->struct_end(dest, struct_class);
+}
+
+void struct_type_free(struct type_class_struct *struct_class)
+{
+       g_hash_table_destroy(struct_class->fields_by_name);
+       g_array_free(struct_class->fields, true);
+       g_free(struct_class);
+}
+
+static void _struct_type_free(struct type_class *type_class)
+{
+       struct type_class_struct *struct_class =
+               container_of(type_class, struct type_class_struct, p);
+       struct_type_free(struct_class);
+}
+
+struct type_class_struct *struct_type_new(const char *name)
+{
+       struct type_class_struct *struct_class;
+       int ret;
+
+       struct_class = g_new(struct type_class_struct, 1);
+       type_class = &float_class->p;
+
+       struct_class->fields_by_name = g_hash_table_new(g_direct_hash,
+                                                       g_direct_equal);
+       struct_class->fields = g_array_sized_new(false, false,
+                                                sizeof(struct field),
+                                                DEFAULT_NR_STRUCT_FIELDS)
+       type_class->name = g_quark_from_string(name);
+       type_class->alignment = 1;
+       type_class->copy = struct_copy;
+       type_class->free = _struct_type_free;
+
+       if (type_class->name) {
+               ret = ctf_register_type(type_class);
+               if (ret)
+                       goto error_register;
+       }
+       return struct_class;
+
+error_register:
+       g_free(struct_class);
+       return NULL;
+}
+
+void struct_type_add_field(struct type_class_struct *struct_class,
+                          const char *field_name,
+                          struct type_class *type_class)
+{
+       struct field *field;
+       unsigned long index;
+
+       g_array_set_size(struct_class->fields, struct_class->fields->len + 1);
+       index = struct_class->fields->len - 1;  /* last field (new) */
+       field = &g_array_index(struct_class->fields, struct field, index);
+       field->name = g_quark_from_string(field_name);
+       field->type_class = type_class;
+       /* Keep index in hash rather than pointer, because array can relocate */
+       g_hash_table_insert(struct_class->fields_by_name,
+                           (gpointer) (unsigned long) field->name,
+                           (gpointer) index);
+       /*
+        * Alignment of structure is the max alignment of types contained
+        * therein.
+        */
+       struct_class->p.alignment = max(struct_class->p.alignment,
+                                       type_class->alignment);
+}
+
+unsigned long
+struct_type_lookup_field_index(struct type_class_struct *struct_class,
+                              GQuark field_name)
+{
+       unsigned long index;
+
+       index = (unsigned long) g_hash_table_lookup(struct_class->fields_by_name,
+                                                   field_name);
+       return index;
+}
+
+/*
+ * field returned only valid as long as the field structure is not appended to.
+ */
+struct field *
+struct_type_get_field_from_index(struct type_class_struct *struct_class,
+                                unsigned long index)
+{
+       return &g_array_index(struct_class->fields, struct field, index);
+}
This page took 0.041866 seconds and 4 git commands to generate.