489667a3abf8dd09c84e63c3f5c7bd0bae1d155b
[babeltrace.git] / types / enum.c
1 /*
2 * enum.c
3 *
4 * BabelTrace - Enumeration Type
5 *
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
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:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 */
18
19 #include <babeltrace/compiler.h>
20 #include <babeltrace/types.h>
21 #include <stdint.h>
22 #include <glib.h>
23
24 struct enum_table {
25 GHashTable *value_to_quark; /* Tuples (value, GQuark) */
26 GHashTable *quark_to_value; /* Tuples (GQuark, value) */
27 };
28
29 #if (__WORDSIZE == 32)
30 GQuark enum_uint_to_quark(const struct type_class_enum *enum_class, uint64_t v)
31 {
32 gconstpointer q = g_hash_table_lookup(enum_class->table.value_to_quark,
33 &v);
34 return (GQuark) (unsigned long) q;
35 }
36
37 GQuark enum_int_to_quark(const struct type_class_enum *enum_class, uint64_t v)
38 {
39 gconstpointer q = g_hash_table_lookup(enum_class->table.value_to_quark,
40 &v);
41 return (GQuark) (unsigned long) q;
42 }
43
44 uint64_t enum_quark_to_uint(const struct type_class_enum *enum_class,
45 size_t len, int byte_order, GQuark q)
46 {
47 gconstpointer v = g_hash_table_lookup(enum_class->table.quark_to_value,
48 (gconstpointer) q);
49 return *(const uint64_t *) v;
50 }
51
52 int64_t enum_quark_to_int(const struct type_class_enum *enum_class,
53 size_t len, int byte_order, GQuark q)
54 {
55 gconstpointer v = g_hash_table_lookup(enum_class->table.quark_to_value,
56 (gconstpointer) q);
57 return *(const int64_t *) v;
58 }
59
60 guint enum_val_hash(gconstpointer key)
61 {
62 int64_t ukey = *(const int64_t *)key;
63
64 return (guint)ukey ^ (guint)(ukey >> 32);
65 }
66
67 gboolean enum_val_equal(gconstpointer a, gconstpointer b)
68 {
69 int64_t ua = *(const int64_t *)a;
70 int64_t ub = *(const int64_t *)b;
71
72 return ua == ub;
73 }
74
75 void enum_val_free(void *ptr)
76 {
77 g_free(ptr);
78 }
79
80 void enum_signed_insert(struct type_class_enum *enum_class, int64_t v, GQuark q)
81 {
82 int64_t *valuep = g_new(int64_t, 1);
83
84 g_hash_table_insert(enum_class->table>value_to_quark, valuep,
85 (gpointer) (unsigned long) q);
86 g_hash_table_insert(enum_class->table.quark_to_value,
87 (gpointer) (unsigned long) q,
88 valuep);
89 }
90
91 void enum_unsigned_insert(struct type_class_enum *enum_class, uint64_t v, GQuark q)
92 {
93 uint64_t *valuep = g_new(uint64_t, 1);
94
95 g_hash_table_insert(enum_class->table.value_to_quark, valuep,
96 (gpointer) (unsigned long) q);
97 g_hash_table_insert(enum_class->table.quark_to_value,
98 (gpointer) (unsigned long) q,
99 valuep);
100 }
101 #else /* __WORDSIZE != 32 */
102 GQuark enum_uint_to_quark(const struct type_class_enum *enum_class, uint64_t v)
103 {
104 gconstpointer q = g_hash_table_lookup(enum_class->table.value_to_quark,
105 (gconstpointer) v);
106 return (GQuark) (unsigned long) q;
107 }
108
109 GQuark enum_int_to_quark(const struct type_class_enum *enum_class, uint64_t v)
110 {
111 gconstpointer q = g_hash_table_lookup(enum_class->table.value_to_quark,
112 (gconstpointer) v);
113 return (GQuark) (unsigned long) q;
114 }
115
116 uint64_t enum_quark_to_uint(const struct type_class_enum *enum_class,
117 size_t len, int byte_order, GQuark q)
118 {
119 gconstpointer v = g_hash_table_lookup(enum_class->table.quark_to_value,
120 (gconstpointer) (unsigned long) q);
121 return *(const uint64_t *) v;
122 }
123
124 int64_t enum_quark_to_int(const struct type_class_enum *enum_class,
125 size_t len, int byte_order, GQuark q)
126 {
127 gconstpointer v = g_hash_table_lookup(enum_class->table.quark_to_value,
128 (gconstpointer) (unsigned long) q);
129 return *(const int64_t *) v;
130 }
131
132 guint enum_val_hash(gconstpointer key)
133 {
134 return g_direct_hash(key);
135 }
136
137 gboolean enum_val_equal(gconstpointer a, gconstpointer b)
138 {
139 return g_direct_equal(a, b);
140 }
141
142 void enum_val_free(void *ptr)
143 {
144 }
145
146 void enum_signed_insert(struct type_class_enum *enum_class,
147 int64_t v, GQuark q)
148 {
149 g_hash_table_insert(enum_class->table.value_to_quark, (gpointer) v,
150 (gpointer) (unsigned long) q);
151 g_hash_table_insert(enum_class->table.quark_to_value,
152 (gpointer) (unsigned long) q,
153 valuep);
154 }
155
156 void enum_unsigned_insert(struct type_class_enum *enum_class,
157 uint64_t v, GQuark q)
158 {
159 g_hash_table_insert(enum_class->table.value_to_quark, (gpointer) v,
160 (gpointer) (unsigned long) q);
161 g_hash_table_insert(enum_class->table.quark_to_value,
162 (gpointer) (unsigned long) q,
163 valuep);
164 }
165 #endif /* __WORDSIZE != 32 */
166
167 size_t enum_copy(unsigned char *dest, const struct format *fdest,
168 const unsigned char *src, const struct format *fsrc,
169 const struct type_class *type_class)
170 {
171 struct type_class_enum *enum_class =
172 container_of(type_class, struct type_class_enum, p);
173 struct type_class_integer *int_class = &enum_class->p;
174 GQuark v;
175
176 v = fsrc->enum_read(src, enum_class)
177 return fdest->enum_write(dest, enum_class, v);
178 }
179
180 void enum_type_free(struct type_class_enum *enum_class)
181 {
182 g_hash_table_destroy(enum_class->table.value_to_quark);
183 g_hash_table_destroy(enum_class->table.quark_to_value);
184 g_free(enum_class);
185 }
186
187 static
188 void _enum_type_free(struct type_class *type_class)
189 {
190 struct type_class_enum *enum_class =
191 container_of(type_class, struct type_class_enum, p);
192 enum_type_free(enum_class);
193 }
194
195 struct type_class_enum *enum_type_new(const char *name,
196 size_t len, int byte_order,
197 int signedness,
198 size_t alignment)
199 {
200 struct type_class_integer *int_class;
201 int ret;
202
203 enum_class = g_new(struct type_class_enum, 1);
204 enum_class->table.value_to_quark = g_hash_table_new(enum_val_hash,
205 enum_val_equal);
206 enum_class->table.quark_to_value = g_hash_table_new_full(g_direct_hash,
207 g_direct_equal,
208 NULL, enum_val_free);
209 int_class = &enum_class->p;
210 int_class->p.name = g_quark_from_string(name);
211 int_class->p.alignment = alignment;
212 int_class->p.copy = enum_copy;
213 int_class->p.free = _enum_type_free;
214 int_class->len = len;
215 int_class->byte_order = byte_order;
216 int_class->signedness = signedness;
217 if (int_class->p.name) {
218 ret = register_type(&int_class->p);
219 if (ret) {
220 g_hash_table_destroy(enum_class->table.value_to_quark);
221 g_hash_table_destroy(enum_class->table.quark_to_value);
222 g_free(enum_class);
223 return NULL;
224 }
225 }
226 return enum_class;
227 }
This page took 0.048516 seconds and 3 git commands to generate.