Changed automake files to reflect the new header files.
[lttv.git] / ltt / branches / poly / lttv / attribute.c
CommitLineData
dc877563 1
fcdf0ec2 2#include <lttv/attribute.h>
f32847a1 3
dc877563 4typedef union _AttributeValue {
5 int dv_int;
6 unsigned dv_uint;
7 long dv_long;
8 unsigned long dv_ulong;
9 float dv_float;
10 double dv_double;
11 timespec dv_timespec;
12 gpointer dv_pointer;
13 char *dv_string;
14 gobject *dv_gobject;
15} AttributeValue;
16
17
18typedef struct _Attribute {
19 LttvAttributeName name;
20 LttvAttributeType type;
21 AttributeValue value;
22} Attribute;
23
24
25GType
26lttv_attribute_get_type (void)
27{
28 static GType type = 0;
29 if (type == 0) {
30 static const GTypeInfo info = {
31 sizeof (LttvAttributeClass),
32 NULL, /* base_init */
33 NULL, /* base_finalize */
34 attribute_class_init, /* class_init */
35 NULL, /* class_finalize */
36 NULL, /* class_data */
37 sizeof (LttvAttribute),
38 0, /* n_preallocs */
39 attribute_instance_init /* instance_init */
40 };
41
42 static const GInterfaceInfo iattribute_info = {
43 (GInterfaceInitFunc) attribute_interface_init, /* interface_init */
44 NULL, /* interface_finalize */
45 NULL /* interface_data */
46 };
47
48 type = g_type_register_static (G_TYPE_OBJECT, "LttvAttributeType", &info,
49 0);
50 g_type_add_interface_static (type, LTTV_IATTRIBUTE_TYPE, &iattribute_info);
51 }
52 return type;
f32847a1 53}
54
55
dc877563 56unsigned int
57lttv_attribute_get_number(LttvAttribute *self)
58{
59 return self->attributes->len;
f32847a1 60}
61
62
dc877563 63gboolean
64lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous)
65{
66 *homogeneous = FALSE;
67 return TRUE;
f32847a1 68}
69
70
dc877563 71LttvAttributeType
72lttv_attribute_get(LttvAttribute *self, unsigned i, LttvAttributeName *name,
73 LttvAttributeValue *v)
74{
75 Attribute *a;
f32847a1 76
dc877563 77 a = &g_array_index(self->attributes, Attribute, i);
78 *name = a->name;
79 *v = address_of_value(a->type, a->value);
80 return a->type;
f32847a1 81}
82
83
dc877563 84LttvAttributeType
85lttv_attribute_get_by_name(LttvAttribute *self, LttvAttributeName name,
86 LttvAttributeValue *v)
87{
88 Attribute *a;
f32847a1 89
dc877563 90 unsigned i;
f32847a1 91
dc877563 92 i = (unsigned)g_hash_table_lookup(self->names, (gconstpointer)name);
93 if(i == 0) return LTTV_NONE;
f32847a1 94
dc877563 95 i--;
96 a = &g_array_index(self->attributes, Attribute, i);
97 *v = address_of_value(a->type, a->value);
98 return a->type;
f32847a1 99}
100
f32847a1 101
dc877563 102LttvAttributeValue
103lttv_attribute_add(LttvAttribute *self, LttvAttributeName name,
104 LttvAttributeType t)
105{
106 unsigned i;
f32847a1 107
dc877563 108 Attribute a, *pa;
f32847a1 109
dc877563 110 i = (unsigned)g_hash_table_lookup(self->names, (gconstpointer)name);
111 if(i != 0) g_error("duplicate entry in attribute table");
f32847a1 112
dc877563 113 a->name = name;
114 a->type = t;
115 a->value = init_value(t);
116 g_array_append_val(self->attributes, a);
117 i = self->attributes->len - 1;
118 pa = &g_array_index(self->attributes, Attribute, i)
119 g_hash_table_insert(self->names, (gconstpointer)name, (gconstpointer)i + 1);
120 return address_of_value(pa->value, t);
f32847a1 121}
122
123
dc877563 124/* Remove an attribute */
f32847a1 125
dc877563 126void
127lttv_attribute_remove(LttvAttribute *self, unsigned i)
f32847a1 128{
dc877563 129 Attribute *a;
f32847a1 130
dc877563 131 a = &g_array_index(self->attributes, Attribute, i);
f32847a1 132
dc877563 133 /* Remove the array element and its entry in the name index */
f32847a1 134
dc877563 135 g_hash_table_remove(self->names, (gconspointer)a->name);
136 g_array_remove_index_fast(self->attributes, i);
f32847a1 137
dc877563 138 /* The element used to replace the removed element has its index entry
139 all wrong now. Reinsert it with its new position. */
f32847a1 140
dc877563 141 g_hash_table_remove(self->names, (gconstpointer)a->name);
142 g_hash_table_insert(self->names, (gconstpointer)a->name, i + 1);
f32847a1 143}
144
dc877563 145void
146lttv_attribute_remove_by_name(LttvAttribute *self, LttvAttributeName name)
147{
148 unsigned i;
f32847a1 149
dc877563 150 i = (unsigned)g_hash_table_lookup(self->names, (gconstpointer)name);
151 if(i == 0) g_error("remove by name non existent attribute");
f32847a1 152
dc877563 153 lttv_attribute_remove(self, i - 1);
f32847a1 154}
155
dc877563 156/* Create an empty iattribute object and add it as an attribute under the
157 specified name, or return an existing iattribute attribute. If an
158 attribute of that name already exists but is not a GObject supporting the
159 iattribute interface, return NULL. */
f32847a1 160
dc877563 161LttvIAttribute*
162lttv_attribute_create_subdir(LttvAttribute *self, LttvAttributeName name)
f32847a1 163{
dc877563 164 unsigned i;
f32847a1 165
dc877563 166 Attribute a;
f32847a1 167
dc877563 168 LttvAttribute *new;
f32847a1 169
dc877563 170 i = (unsigned)g_hash_table_lookup(self->names, (gconstpointer)name);
171 if(i != 0) {
172 a = g_array_index(self->attributes, Attribute, i - 1);
173 if(a->type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a->value->dv_gobject)) {
174 return LTTV_IATTRIBUTE(a->value->dv_gobject);
175 }
176 else return NULL;
f32847a1 177 }
dc877563 178 new = g_object_new(LTTV_ATTRIBUTE_TYPE);
179 *(lttv_attribute_add(self, name, LTTV_GOBJECT)->v_gobject) = new;
180 return new;
f32847a1 181}
182
dc877563 183gboolean
184lttv_attribute_find(LttvAttribute *self, LttvAttributeName name,
185 LttvAttributeType t, LttvAttributeValue *v)
f32847a1 186{
dc877563 187 unsigned i;
f32847a1 188
dc877563 189 Attribute *a;
f32847a1 190
dc877563 191 i = (unsigned)g_hash_table_lookup(self->names, (gconstpointer)name);
192 if(i != 0) {
193 a = &g_array_index(self->attributes, Attribute, i - 1);
194 if(a->type != t) return FALSE;
195 *v = address_of_value(a->value, t);
196 return TRUE;
197 }
f32847a1 198
dc877563 199 *v = lttv_attribute_add(self, name, t);
200 return TRUE;
f32847a1 201}
202
f32847a1 203
dc877563 204static void
205attribute_interface_init (gpointer g_iface, gpointer iface_data)
f32847a1 206{
dc877563 207 LttvIAttributeClass *klass = (LttvIAttributeClass *)g_iface;
f32847a1 208
dc877563 209 klass->get_number = (unsigned int (*) (LttvIAttribute *self))
210 lttv_attribute_get_number;
f32847a1 211
dc877563 212 klass->named = (gboolean (*) (LttvIAttribute *self, gboolean *homogeneous))
213 lttv_attribute_named;
f32847a1 214
dc877563 215 klass->get = (LttvAttributeType (*) (LttvIAttribute *self, unsigned i,
216 LttvAttributeName *name, LttvAttributeValue *v)) lttv_attribute_get;
f32847a1 217
dc877563 218 klass->get_by_name = (LttvAttributeType (*) (LttvIAttribute *self,
219 LttvAttributeName name, LttvAttributeValue *v))
220 lttv_attribute_get_by_name;
f32847a1 221
dc877563 222 klass->add = (LttvAttributeValue (*) (LttvIAttribute *self,
223 LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add;
f32847a1 224
dc877563 225 klass->remove = (void (*) (LttvIAttribute *self, unsigned i))
226 lttv_attribute_remove;
f32847a1 227
dc877563 228 klass->remove_by_name = (void (*) (LttvIAttribute *self,
229 LttvAttributeName name)) lttv_attribute_remove_by_name;
f32847a1 230
dc877563 231 klass->create_subdir = (LttvIAttribute* (*) (LttvIAttribute *self,
232 LttvAttributeName name)) lttv_attribute_create_subdir;
f32847a1 233}
234
235
dc877563 236static guint
237quark_hash(gconstpointer key)
f32847a1 238{
dc877563 239 return (guint)key;
f32847a1 240}
241
242
dc877563 243static gboolean
244quark_equal(gconstpointer a, gconstpointer b)
f32847a1 245{
dc877563 246 return (a == b)
f32847a1 247}
248
dc877563 249static void
250attribute_instance_init (GTypeInstance *instance, gpointer g_class)
f32847a1 251{
dc877563 252 LttvAttribute *self = (LttvAttribute *)instance;
253 self->names = g_hash_table_new(quark_hash, quark_equal);
254 self->attributes = g_array_new(FALSE, FALSE,
255 sizeof(Attribute));
f32847a1 256}
257
f32847a1 258
dc877563 259static void
260attribute_finalize (LttvAttribute *self)
f32847a1 261{
dc877563 262 g_hash_table_free(self->names);
263 g_array_free(self->attributes, TRUE);
264 G_OBJECT_CLASS(g_type_class_peek_parent(LTTV_ATTRIBUTE_TYPE))->finalize(self);
f32847a1 265}
266
f32847a1 267
dc877563 268static void
269attribute_class_init (LttvAttributeClass *klass)
f32847a1 270{
dc877563 271 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
f32847a1 272
dc877563 273 gobject_class->finalize = attribute_finalize;
f32847a1 274}
275
This page took 0.035581 seconds and 4 git commands to generate.