Fix type free memleak
[babeltrace.git] / types / enum.c
1 /*
2 * BabelTrace - Enumeration Type
3 *
4 * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <babeltrace/compiler.h>
22 #include <babeltrace/types.h>
23 #include <stdint.h>
24 #include <glib.h>
25
26 struct enum_table {
27 GHashTable *value_to_quark; /* Tuples (value, GQuark) */
28 GHashTable *quark_to_value; /* Tuples (GQuark, value) */
29 };
30
31 #if (__WORDSIZE == 32)
32 GQuark enum_uint_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 GQuark enum_int_to_quark(const struct type_class_enum *enum_class, uint64_t v)
40 {
41 gconstpointer q = g_hash_table_lookup(enum_class->table.value_to_quark,
42 &v);
43 return (GQuark) (unsigned long) q;
44 }
45
46 uint64_t enum_quark_to_uint(const struct type_class_enum *enum_class,
47 size_t len, int byte_order, GQuark q)
48 {
49 gconstpointer v = g_hash_table_lookup(enum_class->table.quark_to_value,
50 (gconstpointer) q);
51 return *(const uint64_t *) v;
52 }
53
54 int64_t enum_quark_to_int(const struct type_class_enum *enum_class,
55 size_t len, int byte_order, GQuark q)
56 {
57 gconstpointer v = g_hash_table_lookup(enum_class->table.quark_to_value,
58 (gconstpointer) q);
59 return *(const int64_t *) v;
60 }
61
62 guint enum_val_hash(gconstpointer key)
63 {
64 int64_t ukey = *(const int64_t *)key;
65
66 return (guint)ukey ^ (guint)(ukey >> 32);
67 }
68
69 gboolean enum_val_equal(gconstpointer a, gconstpointer b)
70 {
71 int64_t ua = *(const int64_t *)a;
72 int64_t ub = *(const int64_t *)b;
73
74 return ua == ub;
75 }
76
77 void enum_val_free(void *ptr)
78 {
79 g_free(ptr);
80 }
81
82 void enum_signed_insert(struct type_class_enum *enum_class, int64_t v, GQuark q)
83 {
84 int64_t *valuep = g_new(int64_t, 1);
85
86 g_hash_table_insert(enum_class->table>value_to_quark, valuep,
87 (gpointer) (unsigned long) q);
88 g_hash_table_insert(enum_class->table.quark_to_value,
89 (gpointer) (unsigned long) q,
90 valuep);
91 }
92
93 void enum_unsigned_insert(struct type_class_enum *enum_class, uint64_t v, GQuark q)
94 {
95 uint64_t *valuep = g_new(uint64_t, 1);
96
97 g_hash_table_insert(enum_class->table.value_to_quark, valuep,
98 (gpointer) (unsigned long) q);
99 g_hash_table_insert(enum_class->table.quark_to_value,
100 (gpointer) (unsigned long) q,
101 valuep);
102 }
103 #else /* __WORDSIZE != 32 */
104 GQuark enum_uint_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 GQuark enum_int_to_quark(const struct type_class_enum *enum_class, uint64_t v)
112 {
113 gconstpointer q = g_hash_table_lookup(enum_class->table.value_to_quark,
114 (gconstpointer) v);
115 return (GQuark) (unsigned long) q;
116 }
117
118 uint64_t enum_quark_to_uint(const struct type_class_enum *enum_class,
119 size_t len, int byte_order, GQuark q)
120 {
121 gconstpointer v = g_hash_table_lookup(enum_class->table.quark_to_value,
122 (gconstpointer) (unsigned long) q);
123 return *(const uint64_t *) v;
124 }
125
126 int64_t enum_quark_to_int(const struct type_class_enum *enum_class,
127 size_t len, int byte_order, GQuark q)
128 {
129 gconstpointer v = g_hash_table_lookup(enum_class->table.quark_to_value,
130 (gconstpointer) (unsigned long) q);
131 return *(const int64_t *) v;
132 }
133
134 guint enum_val_hash(gconstpointer key)
135 {
136 return g_direct_hash(key);
137 }
138
139 gboolean enum_val_equal(gconstpointer a, gconstpointer b)
140 {
141 return g_direct_equal(a, b);
142 }
143
144 void enum_val_free(void *ptr)
145 {
146 }
147
148 void enum_signed_insert(struct type_class_enum *enum_class,
149 int64_t v, GQuark q)
150 {
151 g_hash_table_insert(enum_class->table.value_to_quark, (gpointer) v,
152 (gpointer) (unsigned long) q);
153 g_hash_table_insert(enum_class->table.quark_to_value,
154 (gpointer) (unsigned long) q,
155 valuep);
156 }
157
158 void enum_unsigned_insert(struct type_class_enum *enum_class,
159 uint64_t v, GQuark q)
160 {
161 g_hash_table_insert(enum_class->table.value_to_quark, (gpointer) v,
162 (gpointer) (unsigned long) q);
163 g_hash_table_insert(enum_class->table.quark_to_value,
164 (gpointer) (unsigned long) q,
165 valuep);
166 }
167 #endif /* __WORDSIZE != 32 */
168
169 size_t enum_copy(unsigned char *dest, const struct format *fdest,
170 const unsigned char *src, const struct format *fsrc,
171 const struct type_class *type_class)
172 {
173 struct type_class_enum *enum_class =
174 container_of(type_class, struct type_class_enum, p);
175 struct type_class_bitfield *bitfield_class = &enum_class->p;
176 struct type_class_integer *int_class = &bitfield_class->p;
177 GQuark v;
178
179 v = fsrc->enum_read(src, enum_class)
180 return fdest->enum_write(dest, enum_class, v);
181 }
182
183 void enum_type_free(struct type_class_enum *enum_class)
184 {
185 g_hash_table_destroy(enum_class->table.value_to_quark);
186 g_hash_table_destroy(enum_class->table.quark_to_value);
187 g_free(enum_class);
188 }
189
190 static
191 void _enum_type_free(struct type_class *type_class)
192 {
193 struct type_class_enum *enum_class =
194 container_of(type_class, struct type_class_enum, p);
195 enum_type_free(enum_class);
196 }
197
198 struct type_class_enum *enum_type_new(const char *name,
199 size_t start_offset,
200 size_t len, int byte_order,
201 int signedness,
202 size_t alignment)
203 {
204 struct type_class_bitfield *bitfield_class;
205 struct type_class_integer *int_class;
206 int ret;
207
208 enum_class = g_new(struct type_class_bitfield, 1);
209 enum_class->table.value_to_quark = g_hash_table(enum_val_hash,
210 enum_val_equal);
211 enum_class->table.quark_to_value = g_hash_table_new_full(g_direct_hash,
212 g_direct_equal,
213 NULL, enum_val_free);
214 bitfield_class = &enum_class->p;
215 bitfield_class->start_offset = start_offset;
216 int_class = &bitfield_class->p;
217 int_class->p.name = g_quark_from_string(name);
218 int_class->p.alignment = alignment;
219 int_class->p.copy = enum_copy;
220 int_class->p.free = _enum_type_free;
221 int_class->len = len;
222 int_class->byte_order = byte_order;
223 int_class->signedness = signedness;
224 bitfield_class->start_offset = start_offset;
225 if (int_class->p.name) {
226 ret = register_type(&int_class->p);
227 if (ret) {
228 g_hash_table_destroy(enum_class->table.value_to_quark);
229 g_hash_table_destroy(enum_class->table.quark_to_value);
230 g_free(enum_class);
231 return NULL;
232 }
233 }
234 return enum_class;
235 }
This page took 0.033641 seconds and 5 git commands to generate.