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