4 * BabelTrace - Enumeration Type
6 * Copyright 2010, 2011 - 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 struct type_enum
*_enum_type_new(struct type_class
*type_class
,
26 struct declaration_scope
*parent_scope
);
28 void _enum_type_free(struct type
*type
);
31 void enum_range_set_free(void *ptr
)
37 * Returns a GArray or NULL.
38 * Caller must release the GArray with g_array_unref().
40 GArray
*enum_uint_to_quark_set(const struct type_class_enum
*enum_class
,
43 struct enum_range_to_quark
*iter
;
44 GArray
*qs
, *ranges
= NULL
;
46 /* Single values lookup */
47 qs
= g_hash_table_lookup(enum_class
->table
.value_to_quark_set
, &v
);
50 cds_list_for_each_entry(iter
, &enum_class
->table
.range_to_quark
, node
) {
51 if (iter
->range
.start
._unsigned
> v
|| iter
->range
.end
._unsigned
< v
)
58 ranges
= g_array_sized_new(FALSE
, TRUE
,
59 sizeof(struct enum_range
),
61 g_array_set_size(ranges
, qs_len
+ 1);
63 memcpy(ranges
->data
, qs
->data
,
64 sizeof(struct enum_range
) * qs_len
);
65 g_array_index(ranges
, struct enum_range
, qs_len
) = iter
->range
;
67 g_array_set_size(ranges
, ranges
->len
+ 1);
68 g_array_index(ranges
, struct enum_range
, ranges
->len
) = iter
->range
;
79 * Returns a GArray or NULL.
80 * Caller must release the GArray with g_array_unref().
82 GArray
*enum_int_to_quark_set(const struct type_class_enum
*enum_class
, uint64_t v
)
84 struct enum_range_to_quark
*iter
;
85 GArray
*qs
, *ranges
= NULL
;
87 /* Single values lookup */
88 qs
= g_hash_table_lookup(enum_class
->table
.value_to_quark_set
, &v
);
91 cds_list_for_each_entry(iter
, &enum_class
->table
.range_to_quark
, node
) {
92 if (iter
->range
.start
._signed
> v
|| iter
->range
.end
._signed
< v
)
99 ranges
= g_array_sized_new(FALSE
, TRUE
,
100 sizeof(struct enum_range
),
102 g_array_set_size(ranges
, qs_len
+ 1);
104 memcpy(ranges
->data
, qs
->data
,
105 sizeof(struct enum_range
) * qs_len
);
106 g_array_index(ranges
, struct enum_range
, qs_len
) = iter
->range
;
108 g_array_set_size(ranges
, ranges
->len
+ 1);
109 g_array_index(ranges
, struct enum_range
, ranges
->len
) = iter
->range
;
119 #if (__WORDSIZE == 32)
121 guint
enum_val_hash(gconstpointer key
)
123 int64_t ukey
= *(const int64_t *)key
;
125 return (guint
)ukey
^ (guint
)(ukey
>> 32);
129 gboolean
enum_val_equal(gconstpointer a
, gconstpointer b
)
131 int64_t ua
= *(const int64_t *)a
;
132 int64_t ub
= *(const int64_t *)b
;
138 void enum_val_free(void *ptr
)
144 void enum_signed_insert_value_to_quark_set(struct type_class_enum
*enum_class
,
150 array
= g_hash_table_lookup(enum_class
->table
.value_to_quark_set
, &v
);
152 array
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
), 1);
153 g_array_set_size(array
, 1);
154 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
155 valuep
= g_new(int64_t, 1);
157 g_hash_table_insert(enum_class
->table
.value_to_quark_set
, valuep
, array
);
159 g_array_set_size(array
, array
->len
+ 1);
160 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
165 void enum_unsigned_insert_value_to_quark_set(struct type_class_enum
*enum_class
,
166 uint64_t v
, GQuark q
)
171 array
= g_hash_table_lookup(enum_class
->table
.value_to_quark_set
, &v
);
173 array
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
), 1);
174 g_array_set_size(array
, 1);
175 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
176 valuep
= g_new(uint64_t, 1);
178 g_hash_table_insert(enum_class
->table
.value_to_quark_set
, valuep
, array
);
180 g_array_set_size(array
, array
->len
+ 1);
181 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
184 #else /* __WORDSIZE != 32 */
186 guint
enum_val_hash(gconstpointer key
)
188 return g_direct_hash(key
);
192 gboolean
enum_val_equal(gconstpointer a
, gconstpointer b
)
194 return g_direct_equal(a
, b
);
198 void enum_val_free(void *ptr
)
203 void enum_signed_insert_value_to_quark_set(struct type_class_enum
*enum_class
,
208 array
= g_hash_table_lookup(enum_class
->table
.value_to_quark_set
,
211 array
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
), 1);
212 g_array_set_size(array
, 1);
213 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
214 g_hash_table_insert(enum_class
->table
.value_to_quark_set
,
215 (gpointer
) v
, array
);
217 g_array_set_size(array
, array
->len
+ 1);
218 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
223 void enum_unsigned_insert_value_to_quark_set(struct type_class_enum
*enum_class
,
224 uint64_t v
, GQuark q
)
228 array
= g_hash_table_lookup(enum_class
->table
.value_to_quark_set
,
231 array
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
), 1);
232 g_array_set_size(array
, 1);
233 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
234 g_hash_table_insert(enum_class
->table
.value_to_quark_set
,
235 (gpointer
) v
, array
);
237 g_array_set_size(array
, array
->len
+ 1);
238 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
241 #endif /* __WORDSIZE != 32 */
243 GArray
*enum_quark_to_range_set(const struct type_class_enum
*enum_class
,
246 return g_hash_table_lookup(enum_class
->table
.quark_to_range_set
,
247 (gconstpointer
) (unsigned long) q
);
251 void enum_signed_insert_range_to_quark(struct type_class_enum
*enum_class
,
252 int64_t start
, int64_t end
, GQuark q
)
254 struct enum_range_to_quark
*rtoq
;
256 rtoq
= g_new(struct enum_range_to_quark
, 1);
257 cds_list_add(&rtoq
->node
, &enum_class
->table
.range_to_quark
);
258 rtoq
->range
.start
._signed
= start
;
259 rtoq
->range
.end
._signed
= end
;
264 void enum_unsigned_insert_range_to_quark(struct type_class_enum
*enum_class
,
265 uint64_t start
, uint64_t end
, GQuark q
)
267 struct enum_range_to_quark
*rtoq
;
269 rtoq
= g_new(struct enum_range_to_quark
, 1);
270 cds_list_add(&rtoq
->node
, &enum_class
->table
.range_to_quark
);
271 rtoq
->range
.start
._unsigned
= start
;
272 rtoq
->range
.end
._unsigned
= end
;
276 void enum_signed_insert(struct type_class_enum
*enum_class
,
277 int64_t start
, int64_t end
, GQuark q
)
280 struct enum_range
*range
;
283 enum_signed_insert_value_to_quark_set(enum_class
, start
, q
);
292 enum_signed_insert_range_to_quark(enum_class
, start
, end
, q
);
295 array
= g_hash_table_lookup(enum_class
->table
.quark_to_range_set
,
296 (gconstpointer
) (unsigned long) q
);
298 array
= g_array_sized_new(FALSE
, TRUE
,
299 sizeof(struct enum_range
), 1);
300 g_hash_table_insert(enum_class
->table
.quark_to_range_set
,
301 (gpointer
) (unsigned long) q
,
304 g_array_set_size(array
, array
->len
+ 1);
305 range
= &g_array_index(array
, struct enum_range
, array
->len
- 1);
306 range
->start
._signed
= start
;
307 range
->end
._signed
= end
;
310 void enum_unsigned_insert(struct type_class_enum
*enum_class
,
311 uint64_t start
, uint64_t end
, GQuark q
)
314 struct enum_range
*range
;
318 enum_unsigned_insert_value_to_quark_set(enum_class
, start
, q
);
327 enum_unsigned_insert_range_to_quark(enum_class
, start
, end
, q
);
330 array
= g_hash_table_lookup(enum_class
->table
.quark_to_range_set
,
331 (gconstpointer
) (unsigned long) q
);
333 array
= g_array_sized_new(FALSE
, TRUE
,
334 sizeof(struct enum_range
), 1);
335 g_hash_table_insert(enum_class
->table
.quark_to_range_set
,
336 (gpointer
) (unsigned long) q
,
339 g_array_set_size(array
, array
->len
+ 1);
340 range
= &g_array_index(array
, struct enum_range
, array
->len
- 1);
341 range
->start
._unsigned
= start
;
342 range
->end
._unsigned
= end
;
345 size_t enum_get_nr_enumerators(struct type_class_enum
*enum_class
)
347 return g_hash_table_size(enum_class
->table
.quark_to_range_set
);
350 void enum_copy(struct stream_pos
*dest
, const struct format
*fdest
,
351 struct stream_pos
*src
, const struct format
*fsrc
,
354 struct type_enum
*_enum
= container_of(type
, struct type_enum
, p
);
355 struct type_class_enum
*enum_class
= _enum
->_class
;
359 array
= fsrc
->enum_read(src
, enum_class
);
361 /* unref previous array */
363 g_array_unref(_enum
->value
, TRUE
);
364 _enum
->value
= array
;
366 * Arbitrarily choose the first one.
367 * TODO: use direct underlying type read/write intead. Not doing it for
368 * now to test enum read and write code.
370 v
= g_array_index(array
, GQuark
, 0);
371 return fdest
->enum_write(dest
, enum_class
, v
);
375 void _enum_type_class_free(struct type_class
*type_class
)
377 struct type_class_enum
*enum_class
=
378 container_of(type_class
, struct enum_type_class
, p
);
379 struct enum_range_to_quark
*iter
, *tmp
;
381 g_hash_table_destroy(enum_class
->table
.value_to_quark_set
);
382 cds_list_for_each_entry_safe(iter
, tmp
, &enum_class
->table
.range_to_quark
, node
) {
383 cds_list_del(&iter
->node
);
386 g_hash_table_destroy(enum_class
->table
.quark_to_range_set
);
390 struct type_class_enum
*
391 _enum_type_class_new(const char *name
, size_t len
, int byte_order
,
392 int signedness
, size_t alignment
)
394 struct type_class_enum
*enum_class
;
395 struct type_class_integer
*int_class
;
398 enum_class
= g_new(struct type_class_enum
, 1);
399 enum_class
->table
.value_to_quark_set
= g_hash_table_new_full(enum_val_hash
,
402 enum_range_set_free
);
403 CDS_INIT_LIST_HEAD(&enum_class
->table
.range_to_quark
);
404 enum_class
->table
.quark_to_range_set
= g_hash_table_new_full(g_int_hash
,
406 NULL
, enum_range_set_free
);
407 int_class
= &enum_class
->p
;
408 int_class
->p
.name
= g_quark_from_string(name
);
409 int_class
->p
.alignment
= alignment
;
410 int_class
->p
.copy
= enum_copy
;
411 int_class
->p
.class_free
= _enum_type_class_free
;
412 int_class
->p
.type_new
= _enum_type_new
;
413 int_class
->p
.type_free
= _enum_type_free
;
414 int_class
->p
.ref
= 1;
415 int_class
->len
= len
;
416 int_class
->byte_order
= byte_order
;
417 int_class
->signedness
= signedness
;
418 if (int_class
->p
.name
) {
419 ret
= register_type(&int_class
->p
);
427 struct enum_range_to_quark
*iter
, *tmp
;
429 cds_list_for_each_entry_safe(iter
, tmp
, &enum_class
->table
.range_to_quark
, node
) {
430 cds_list_del(&iter
->node
);
434 g_hash_table_destroy(enum_class
->table
.value_to_quark_set
);
435 g_hash_table_destroy(enum_class
->table
.quark_to_range_set
);
441 struct type_enum
*_enum_type_new(struct type_class
*type_class
,
442 struct declaration_scope
*parent_scope
)
444 struct type_class_enum
*enum_class
=
445 container_of(type_class
, struct type_class_enum
, p
);
446 struct type_enum
*_enum
;
448 _enum
= g_new(struct type_enum
, 1);
449 type_class_ref(&enum_class
->p
);
450 _enum
->p
._class
= enum_class
;
457 void _enum_type_free(struct type
*type
)
459 struct type_enum
*_enum
= container_of(type
, struct type_enum
, p
);
461 type_class_unref(_enum
->p
._class
);
463 g_array_unref(_enum
->value
, TRUE
);
This page took 0.039032 seconds and 4 git commands to generate.