4 * BabelTrace - Enumeration Type
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
19 #include <babeltrace/compiler.h>
20 #include <babeltrace/format.h>
25 void enum_range_set_free(void *ptr
)
31 * Returns a GArray or NULL.
32 * Caller must release the GArray with g_array_unref().
34 GArray
*enum_uint_to_quark_set(const struct type_class_enum
*enum_class
,
37 struct enum_range_to_quark
*iter
;
38 GArray
*qs
, *ranges
= NULL
;
40 /* Single values lookup */
41 qs
= g_hash_table_lookup(enum_class
->table
.value_to_quark_set
, &v
);
44 cds_list_for_each_entry(iter
, &enum_class
->table
.range_to_quark
, node
) {
45 if (iter
->range
.start
._unsigned
> v
|| iter
->range
.end
._unsigned
< v
)
52 ranges
= g_array_sized_new(FALSE
, TRUE
,
53 sizeof(struct enum_range
),
55 g_array_set_size(ranges
, qs_len
+ 1);
57 memcpy(ranges
->data
, qs
->data
,
58 sizeof(struct enum_range
) * qs_len
);
59 g_array_index(ranges
, struct enum_range
, qs_len
) = iter
->range
;
61 g_array_set_size(ranges
, ranges
->len
+ 1);
62 g_array_index(ranges
, struct enum_range
, ranges
->len
) = iter
->range
;
71 * Returns a GArray or NULL.
72 * Caller must release the GArray with g_array_unref().
74 GArray
*enum_int_to_quark_set(const struct type_class_enum
*enum_class
, uint64_t v
)
76 struct enum_range_to_quark
*iter
;
77 GArray
*qs
, *ranges
= NULL
;
79 /* Single values lookup */
80 qs
= g_hash_table_lookup(enum_class
->table
.value_to_quark_set
, &v
);
83 cds_list_for_each_entry(iter
, &enum_class
->table
.range_to_quark
, node
) {
84 if (iter
->range
.start
._signed
> v
|| iter
->range
.end
._signed
< v
)
91 ranges
= g_array_sized_new(FALSE
, TRUE
,
92 sizeof(struct enum_range
),
94 g_array_set_size(ranges
, qs_len
+ 1);
96 memcpy(ranges
->data
, qs
->data
,
97 sizeof(struct enum_range
) * qs_len
);
98 g_array_index(ranges
, struct enum_range
, qs_len
) = iter
->range
;
100 g_array_set_size(ranges
, ranges
->len
+ 1);
101 g_array_index(ranges
, struct enum_range
, ranges
->len
) = iter
->range
;
109 #if (__WORDSIZE == 32)
111 guint
enum_val_hash(gconstpointer key
)
113 int64_t ukey
= *(const int64_t *)key
;
115 return (guint
)ukey
^ (guint
)(ukey
>> 32);
119 gboolean
enum_val_equal(gconstpointer a
, gconstpointer b
)
121 int64_t ua
= *(const int64_t *)a
;
122 int64_t ub
= *(const int64_t *)b
;
128 void enum_val_free(void *ptr
)
134 void enum_signed_insert_value_to_quark_set(struct type_class_enum
*enum_class
,
140 array
= g_hash_table_lookup(enum_class
->table
.value_to_quark_set
, &v
);
142 array
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
), 1);
143 g_array_set_size(array
, 1);
144 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
145 valuep
= g_new(int64_t, 1);
147 g_hash_table_insert(enum_class
->table
.value_to_quark_set
, valuep
, array
);
149 g_array_set_size(array
, array
->len
+ 1);
150 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
155 void enum_unsigned_insert_value_to_quark_set(struct type_class_enum
*enum_class
,
156 uint64_t v
, GQuark q
)
161 array
= g_hash_table_lookup(enum_class
->table
.value_to_quark_set
, &v
);
163 array
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
), 1);
164 g_array_set_size(array
, 1);
165 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
166 valuep
= g_new(uint64_t, 1);
168 g_hash_table_insert(enum_class
->table
.value_to_quark_set
, valuep
, array
);
170 g_array_set_size(array
, array
->len
+ 1);
171 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
174 #else /* __WORDSIZE != 32 */
176 guint
enum_val_hash(gconstpointer key
)
178 return g_direct_hash(key
);
182 gboolean
enum_val_equal(gconstpointer a
, gconstpointer b
)
184 return g_direct_equal(a
, b
);
188 void enum_val_free(void *ptr
)
193 void enum_signed_insert_value_to_quark_set(struct type_class_enum
*enum_class
,
198 array
= g_hash_table_lookup(enum_class
->table
.value_to_quark_set
,
201 array
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
), 1);
202 g_array_set_size(array
, 1);
203 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
204 g_hash_table_insert(enum_class
->table
.value_to_quark_set
,
205 (gconstpointer
) v
, array
);
207 g_array_set_size(array
, array
->len
+ 1);
208 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
213 void enum_unsigned_insert_value_to_quark_set(struct type_class_enum
*enum_class
,
214 uint64_t v
, GQuark q
)
218 array
= g_hash_table_lookup(enum_class
->table
.value_to_quark_set
,
221 array
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
), 1);
222 g_array_set_size(array
, 1);
223 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
224 g_hash_table_insert(enum_class
->table
.value_to_quark_set
,
225 (gconstpointer
) v
, array
);
227 g_array_set_size(array
, array
->len
+ 1);
228 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
231 #endif /* __WORDSIZE != 32 */
233 GArray
*enum_quark_to_range_set(const struct type_class_enum
*enum_class
,
236 return g_hash_table_lookup(enum_class
->table
.quark_to_range_set
,
237 (gconstpointer
) (unsigned long) q
);
241 void enum_signed_insert_range_to_quark(struct type_class_enum
*enum_class
,
242 int64_t start
, int64_t end
, GQuark q
)
244 struct enum_range_to_quark
*rtoq
;
246 rtoq
= g_new(struct enum_range_to_quark
, 1);
247 cds_list_add(&rtoq
->node
, &enum_class
->table
.range_to_quark
);
248 rtoq
->range
.start
._signed
= start
;
249 rtoq
->range
.end
._signed
= end
;
254 void enum_unsigned_insert_range_to_quark(struct type_class_enum
*enum_class
,
255 uint64_t start
, uint64_t end
, GQuark q
)
257 struct enum_range_to_quark
*rtoq
;
259 rtoq
= g_new(struct enum_range_to_quark
, 1);
260 cds_list_add(&rtoq
->node
, &enum_class
->table
.range_to_quark
);
261 rtoq
->range
.start
._unsigned
= start
;
262 rtoq
->range
.end
._unsigned
= end
;
266 void enum_signed_insert(struct type_class_enum
*enum_class
,
267 int64_t start
, int64_t end
, GQuark q
)
270 struct enum_range
*range
;
273 enum_signed_insert_value_to_quark_set(enum_class
, start
, q
);
282 enum_signed_insert_range_to_quark(enum_class
, start
, end
, q
);
285 array
= g_hash_table_lookup(enum_class
->table
.quark_to_range_set
,
286 (gconstpointer
) (unsigned long) q
);
288 array
= g_array_sized_new(FALSE
, TRUE
,
289 sizeof(struct enum_range
), 1);
290 g_hash_table_insert(enum_class
->table
.quark_to_range_set
,
291 (gpointer
) (unsigned long) q
,
294 g_array_set_size(array
, array
->len
+ 1);
295 range
= &g_array_index(array
, struct enum_range
, array
->len
- 1);
296 range
->start
._signed
= start
;
297 range
->end
._signed
= end
;
300 void enum_unsigned_insert(struct type_class_enum
*enum_class
,
301 uint64_t start
, uint64_t end
, GQuark q
)
304 struct enum_range
*range
;
308 enum_unsigned_insert_value_to_quark_set(enum_class
, start
, q
);
317 enum_unsigned_insert_range_to_quark(enum_class
, start
, end
, q
);
320 array
= g_hash_table_lookup(enum_class
->table
.quark_to_range_set
,
321 (gconstpointer
) (unsigned long) q
);
323 array
= g_array_sized_new(FALSE
, TRUE
,
324 sizeof(struct enum_range
), 1);
325 g_hash_table_insert(enum_class
->table
.quark_to_range_set
,
326 (gpointer
) (unsigned long) q
,
329 g_array_set_size(array
, array
->len
+ 1);
330 range
= &g_array_index(array
, struct enum_range
, array
->len
- 1);
331 range
->start
._unsigned
= start
;
332 range
->end
._unsigned
= end
;
335 void enum_copy(struct stream_pos
*dest
, const struct format
*fdest
,
336 struct stream_pos
*src
, const struct format
*fsrc
,
337 const struct type_class
*type_class
)
339 struct type_class_enum
*enum_class
=
340 container_of(type_class
, struct type_class_enum
, p
.p
);
344 array
= fsrc
->enum_read(src
, enum_class
);
347 * Arbitrarily choose the first one.
348 * TODO: use direct underlying type read/write intead. Not doing it for
349 * now to test enum read and write code.
351 v
= g_array_index(array
, GQuark
, 0);
352 return fdest
->enum_write(dest
, enum_class
, v
);
355 void enum_type_free(struct type_class_enum
*enum_class
)
357 struct enum_range_to_quark
*iter
, *tmp
;
359 g_hash_table_destroy(enum_class
->table
.value_to_quark_set
);
360 cds_list_for_each_entry_safe(iter
, tmp
, &enum_class
->table
.range_to_quark
, node
) {
361 cds_list_del(&iter
->node
);
364 g_hash_table_destroy(enum_class
->table
.quark_to_range_set
);
369 void _enum_type_free(struct type_class
*type_class
)
371 struct type_class_enum
*enum_class
=
372 container_of(type_class
, struct type_class_enum
, p
.p
);
373 enum_type_free(enum_class
);
376 struct type_class_enum
*enum_type_new(const char *name
,
377 size_t len
, int byte_order
,
381 struct type_class_enum
*enum_class
;
382 struct type_class_integer
*int_class
;
385 enum_class
= g_new(struct type_class_enum
, 1);
386 enum_class
->table
.value_to_quark_set
= g_hash_table_new_full(enum_val_hash
,
389 enum_range_set_free
);
390 CDS_INIT_LIST_HEAD(&enum_class
->table
.range_to_quark
);
391 enum_class
->table
.quark_to_range_set
= g_hash_table_new_full(g_int_hash
,
393 NULL
, enum_range_set_free
);
394 int_class
= &enum_class
->p
;
395 int_class
->p
.name
= g_quark_from_string(name
);
396 int_class
->p
.alignment
= alignment
;
397 int_class
->p
.copy
= enum_copy
;
398 int_class
->p
.free
= _enum_type_free
;
399 int_class
->p
.ref
= 1;
400 int_class
->len
= len
;
401 int_class
->byte_order
= byte_order
;
402 int_class
->signedness
= signedness
;
403 if (int_class
->p
.name
) {
404 ret
= register_type(&int_class
->p
);
406 struct enum_range_to_quark
*iter
, *tmp
;
408 g_hash_table_destroy(enum_class
->table
.value_to_quark_set
);
409 cds_list_for_each_entry_safe(iter
, tmp
, &enum_class
->table
.range_to_quark
, node
) {
410 cds_list_del(&iter
->node
);
413 g_hash_table_destroy(enum_class
->table
.quark_to_range_set
);
This page took 0.037603 seconds and 5 git commands to generate.