create directories branches, tags, trunk
[lttv.git] / ltt / branches / poly / lttv / lttv / attribute.c
index ff69db2537bb3998ae100ec6772a88fcf723e45c..eab857be844f1997b4dcea3635c6d913f7f0beb0 100644 (file)
  * MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
 #include <lttv/attribute.h>
 #include <ltt/ltt.h>
+#include <ltt/compiler.h>
 
 typedef union _AttributeValue {
   int dv_int;
@@ -37,10 +43,12 @@ typedef struct _Attribute {
   LttvAttributeName name;
   LttvAttributeType type;
   AttributeValue value;
+       gboolean is_named;
 } Attribute;
 
 
-LttvAttributeValue address_of_value(LttvAttributeType t, AttributeValue *v)
+static __inline__ LttvAttributeValue address_of_value(LttvAttributeType t,
+                                                      AttributeValue *v)
 {
   LttvAttributeValue va;
 
@@ -55,6 +63,7 @@ LttvAttributeValue address_of_value(LttvAttributeType t, AttributeValue *v)
   case LTTV_POINTER: va.v_pointer = &v->dv_pointer; break;
   case LTTV_STRING: va.v_string = &v->dv_string; break;
   case LTTV_GOBJECT: va.v_gobject = &v->dv_gobject; break;
+  case LTTV_NONE: break;
   }
   return va;
 }
@@ -75,6 +84,7 @@ AttributeValue init_value(LttvAttributeType t)
   case LTTV_POINTER: v.dv_pointer = NULL; break;
   case LTTV_STRING: v.dv_string = NULL; break;
   case LTTV_GOBJECT: v.dv_gobject = NULL; break;
+  case LTTV_NONE: break;
   }
   return v;
 }
@@ -86,7 +96,6 @@ lttv_attribute_get_number(LttvAttribute *self)
   return self->attributes->len;
 }
 
-
 gboolean 
 lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous)
 {
@@ -94,16 +103,16 @@ lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous)
   return TRUE;
 }
 
-
 LttvAttributeType 
 lttv_attribute_get(LttvAttribute *self, unsigned i, LttvAttributeName *name, 
-    LttvAttributeValue *v)
+    LttvAttributeValue *v, gboolean *is_named)
 {
   Attribute *a;
 
   a = &g_array_index(self->attributes, Attribute, i);
   *name = a->name;
   *v = address_of_value(a->type, &(a->value));
+       *is_named = a->is_named;
   return a->type;
 }
 
@@ -141,6 +150,30 @@ lttv_attribute_add(LttvAttribute *self, LttvAttributeName name,
   if(i != 0) g_error("duplicate entry in attribute table");
 
   a.name = name;
+       a.is_named = 1;
+  a.type = t;
+  a.value = init_value(t);
+  g_array_append_val(self->attributes, a);
+  i = self->attributes->len - 1;
+  pa = &g_array_index(self->attributes, Attribute, i);
+  g_hash_table_insert(self->names, GUINT_TO_POINTER(name), 
+      GUINT_TO_POINTER(i + 1));
+  return address_of_value(t, &(pa->value));
+}
+
+LttvAttributeValue 
+lttv_attribute_add_unnamed(LttvAttribute *self, LttvAttributeName name, 
+    LttvAttributeType t)
+{
+  unsigned i;
+
+  Attribute a, *pa;
+
+  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(i != 0) g_error("duplicate entry in attribute table");
+
+  a.name = name;
+       a.is_named = 0;
   a.type = t;
   a.value = init_value(t);
   g_array_append_val(self->attributes, a);
@@ -161,6 +194,10 @@ lttv_attribute_remove(LttvAttribute *self, unsigned i)
 
   a = &g_array_index(self->attributes, Attribute, i);
 
+  /* If the element is a gobject, unreference it. */
+  if(a->type == LTTV_GOBJECT && a->value.dv_gobject != NULL)
+    g_object_unref(a->value.dv_gobject);
+  
   /* Remove the array element and its entry in the name index */
 
   g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name));
@@ -169,7 +206,7 @@ lttv_attribute_remove(LttvAttribute *self, unsigned i)
   /* The element used to replace the removed element has its index entry
      all wrong now. Reinsert it with its new position. */
 
-  if(self->attributes->len != i){
+  if(likely(self->attributes->len != i)){
     g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name));
     g_hash_table_insert(self->names, GUINT_TO_POINTER(a->name), GUINT_TO_POINTER(i + 1));
   }
@@ -181,7 +218,7 @@ lttv_attribute_remove_by_name(LttvAttribute *self, LttvAttributeName name)
   unsigned i;
 
   i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
-  if(i == 0) g_error("remove by name non existent attribute");
+  if(unlikely(i == 0)) g_error("remove by name non existent attribute");
 
   lttv_attribute_remove(self, i - 1);
 }
@@ -201,9 +238,9 @@ lttv_attribute_find_subdir(LttvAttribute *self, LttvAttributeName name)
   LttvAttribute *new;
   
   i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
-  if(i != 0) {
+  if(likely(i != 0)) {
     a = g_array_index(self->attributes, Attribute, i - 1);
-    if(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject)) {
+    if(likely(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject))) {
       return LTTV_ATTRIBUTE(a.value.dv_gobject);
     }
     else return NULL;    
@@ -213,6 +250,29 @@ lttv_attribute_find_subdir(LttvAttribute *self, LttvAttributeName name)
   return (LttvAttribute *)new;
 }
 
+/*CHECK*/LttvAttribute* 
+lttv_attribute_find_subdir_unnamed(LttvAttribute *self, LttvAttributeName name)
+{
+  unsigned i;
+
+  Attribute a;
+
+  LttvAttribute *new;
+  
+  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(likely(i != 0)) {
+    a = g_array_index(self->attributes, Attribute, i - 1);
+    if(likely(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject))) {
+      return LTTV_ATTRIBUTE(a.value.dv_gobject);
+    }
+    else return NULL;    
+  }
+  new = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+  *(lttv_attribute_add_unnamed(self, name, LTTV_GOBJECT).v_gobject)
+               = G_OBJECT(new);
+  return (LttvAttribute *)new;
+}
+
 gboolean 
 lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, 
     LttvAttributeType t, LttvAttributeValue *v)
@@ -222,9 +282,9 @@ lttv_attribute_find(LttvAttribute *self, LttvAttributeName name,
   Attribute *a;
 
   i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
-  if(i != 0) {
+  if(likely(i != 0)) {
     a = &g_array_index(self->attributes, Attribute, i - 1);
-    if(a->type != t) return FALSE;
+    if(unlikely(a->type != t)) return FALSE;
     *v = address_of_value(t, &(a->value));
     return TRUE;
   }
@@ -233,8 +293,28 @@ lttv_attribute_find(LttvAttribute *self, LttvAttributeName name,
   return TRUE;
 }
 
+gboolean 
+lttv_attribute_find_unnamed(LttvAttribute *self, LttvAttributeName name, 
+    LttvAttributeType t, LttvAttributeValue *v)
+{
+  unsigned i;
+
+  Attribute *a;
+
+  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(likely(i != 0)) {
+    a = &g_array_index(self->attributes, Attribute, i - 1);
+    if(unlikely(a->type != t)) return FALSE;
+    *v = address_of_value(t, &(a->value));
+    return TRUE;
+  }
+
+  *v = lttv_attribute_add_unnamed(self, name, t);
+  return TRUE;
+}
+
 
-void lttv_attribute_recursive_free(LttvAttribute *self)
+/*void lttv_attribute_recursive_free(LttvAttribute *self)
 {
   int i, nb;
 
@@ -249,7 +329,7 @@ void lttv_attribute_recursive_free(LttvAttribute *self)
     }
   }
   g_object_unref(self);
-}
+}*/
 
 
 void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src)
@@ -265,14 +345,22 @@ void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src)
   for(i = 0 ; i < nb ; i++) {
     a = &g_array_index(src->attributes, Attribute, i);
     if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
-      lttv_attribute_recursive_add(
-      /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir(dest, a->name),
-          (LttvAttribute *)(a->value.dv_gobject));
+                       if(a->is_named)
+             lttv_attribute_recursive_add(
+           /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir(dest, a->name),
+             (LttvAttribute *)(a->value.dv_gobject));
+                       else
+             lttv_attribute_recursive_add(
+           /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir_unnamed(
+                                               dest, a->name), (LttvAttribute *)(a->value.dv_gobject));
     }
     else {
-      g_assert(lttv_attribute_find(dest, a->name, a->type, &value));
+                       if(a->is_named)
+             g_assert(lttv_attribute_find(dest, a->name, a->type, &value));
+                       else
+             g_assert(lttv_attribute_find_unnamed(dest, a->name, a->type, &value));
       switch(a->type) {
-       case LTTV_INT:
+             case LTTV_INT:
           *value.v_int += a->value.dv_int;
           break;
         case LTTV_UINT:
@@ -329,7 +417,7 @@ lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent)
   for(i = 0 ; i < nb ; i++) {
     a = &g_array_index(self->attributes, Attribute, i);
     print_indent(fp, pos);
-    fprintf(fp, "<ATTR NAME=\"%s\" ", a->name);
+    fprintf(fp, "<ATTR NAME=\"%s\" ", g_quark_to_string(a->name));
     if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
       fprintf(fp, "TYPE=ATTRS>");
       lttv_attribute_write_xml((LttvAttribute *)(a->value.dv_gobject), fp,
@@ -356,7 +444,7 @@ lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent)
           fprintf(fp, "TYPE=DOUBLE VALUE=%f/>\n", a->value.dv_double);
           break;
         case LTTV_TIME:
-          fprintf(fp, "TYPE=TIME SEC=%u NSEC=%u/>\n", a->value.dv_time.tv_sec,
+          fprintf(fp, "TYPE=TIME SEC=%lu NSEC=%lu/>\n", a->value.dv_time.tv_sec,
               a->value.dv_time.tv_nsec);
           break;
         case LTTV_POINTER:
@@ -382,9 +470,7 @@ lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent)
 void 
 lttv_attribute_read_xml(LttvAttribute *self, FILE *fp)
 {
-  int i, nb, res;
-
-  Attribute *a;
+  int res;
 
   char buffer[256], type[10];
 
@@ -433,12 +519,12 @@ lttv_attribute_read_xml(LttvAttribute *self, FILE *fp)
     }
     else if(strcmp(type, "DOUBLE") == 0) {
       value = lttv_attribute_add(self, name, LTTV_DOUBLE);
-      res = fscanf(fp, " VALUE=%f/>", value.v_double);
+      res = fscanf(fp, " VALUE=%lf/>", value.v_double);
       g_assert(res == 1);
     }
     else if(strcmp(type, "TIME") == 0) {
       value = lttv_attribute_add(self, name, LTTV_TIME);
-      res = fscanf(fp, " SEC=%u NSEC=%u/>", &(value.v_time->tv_sec), 
+      res = fscanf(fp, " SEC=%lu NSEC=%lu/>", &(value.v_time->tv_sec), 
           &(value.v_time->tv_nsec));
       g_assert(res == 2);
     }
@@ -489,7 +575,8 @@ attribute_interface_init (gpointer g_iface, gpointer iface_data)
       lttv_attribute_named;
 
   klass->get = (LttvAttributeType (*) (LttvIAttribute *self, unsigned i, 
-      LttvAttributeName *name, LttvAttributeValue *v)) lttv_attribute_get;
+      LttvAttributeName *name, LttvAttributeValue *v, gboolean *is_named)) 
+                       lttv_attribute_get;
 
   klass->get_by_name = (LttvAttributeType (*) (LttvIAttribute *self,
       LttvAttributeName name, LttvAttributeValue *v)) 
@@ -498,6 +585,9 @@ attribute_interface_init (gpointer g_iface, gpointer iface_data)
   klass->add = (LttvAttributeValue (*) (LttvIAttribute *self, 
       LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add;
 
+  klass->add_unnamed = (LttvAttributeValue (*) (LttvIAttribute *self, 
+      LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add_unnamed;
+
   klass->remove = (void (*) (LttvIAttribute *self, unsigned i)) 
       lttv_attribute_remove;
 
@@ -506,14 +596,17 @@ attribute_interface_init (gpointer g_iface, gpointer iface_data)
 
   klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self, 
       LttvAttributeName name)) lttv_attribute_find_subdir;
-}
 
+  klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self, 
+      LttvAttributeName name)) lttv_attribute_find_subdir_unnamed;
+}
 
 static void
 attribute_instance_init (GTypeInstance *instance, gpointer g_class)
 {
   LttvAttribute *self = (LttvAttribute *)instance;
-  self->names = g_hash_table_new(g_direct_hash, g_direct_equal);
+  self->names = g_hash_table_new(g_direct_hash,
+                                 g_direct_equal);
   self->attributes = g_array_new(FALSE, FALSE, sizeof(Attribute));
 }
 
@@ -521,11 +614,15 @@ attribute_instance_init (GTypeInstance *instance, gpointer g_class)
 static void
 attribute_finalize (LttvAttribute *self)
 {
-  g_hash_table_destroy(self->names);
+  guint i;
   g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "attribute_finalize()");
+
+  for(i=0;i<self->attributes->len;i++) {
+    lttv_attribute_remove(self, i);
+  }
+  
+  g_hash_table_destroy(self->names);
   g_array_free(self->attributes, TRUE);
-  G_OBJECT_CLASS(g_type_class_peek_parent(
-      g_type_class_peek(LTTV_ATTRIBUTE_TYPE)))->finalize(G_OBJECT(self));
 }
 
 
@@ -551,7 +648,8 @@ lttv_attribute_get_type (void)
       NULL,   /* class_data */
       sizeof (LttvAttribute),
       0,      /* n_preallocs */
-      (GInstanceInitFunc) attribute_instance_init    /* instance_init */
+      (GInstanceInitFunc) attribute_instance_init,    /* instance_init */
+      NULL    /* value handling */
     };
 
     static const GInterfaceInfo iattribute_info = {
This page took 0.03382 seconds and 4 git commands to generate.