Relicense BabelTrace library to MIT (BSD-style)
[babeltrace.git] / types / enum.c
CommitLineData
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>
20#include <babeltrace/types.h>
21#include <stdint.h>
22#include <glib.h>
23
24struct enum_table {
25 GHashTable *value_to_quark; /* Tuples (value, GQuark) */
26 GHashTable *quark_to_value; /* Tuples (GQuark, value) */
27};
28
29#if (__WORDSIZE == 32)
30GQuark 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
37GQuark 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
44uint64_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
52int64_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
60guint enum_val_hash(gconstpointer key)
61{
62 int64_t ukey = *(const int64_t *)key;
63
64 return (guint)ukey ^ (guint)(ukey >> 32);
65}
66
67gboolean 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
75void enum_val_free(void *ptr)
76{
77 g_free(ptr);
78}
79
80void 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
91void 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 */
102GQuark 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
109GQuark 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
116uint64_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
124int64_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
132guint enum_val_hash(gconstpointer key)
133{
134 return g_direct_hash(key);
135}
136
137gboolean enum_val_equal(gconstpointer a, gconstpointer b)
138{
139 return g_direct_equal(a, b);
140}
141
142void enum_val_free(void *ptr)
143{
144}
145
146void 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
156void 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
167size_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);
7fe00194 173 struct type_class_integer *int_class = &enum_class->p;
448d3cc7
MD
174 GQuark v;
175
176 v = fsrc->enum_read(src, enum_class)
177 return fdest->enum_write(dest, enum_class, v);
178}
179
90b676d7
MD
180void 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
187static
188void _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
448d3cc7 195struct type_class_enum *enum_type_new(const char *name,
448d3cc7
MD
196 size_t len, int byte_order,
197 int signedness,
198 size_t alignment)
199{
448d3cc7
MD
200 struct type_class_integer *int_class;
201 int ret;
202
7fe00194 203 enum_class = g_new(struct type_class_enum, 1);
11796b96
MD
204 enum_class->table.value_to_quark = g_hash_table_new(enum_val_hash,
205 enum_val_equal);
448d3cc7
MD
206 enum_class->table.quark_to_value = g_hash_table_new_full(g_direct_hash,
207 g_direct_equal,
208 NULL, enum_val_free);
7fe00194 209 int_class = &enum_class->p;
448d3cc7
MD
210 int_class->p.name = g_quark_from_string(name);
211 int_class->p.alignment = alignment;
90b676d7
MD
212 int_class->p.copy = enum_copy;
213 int_class->p.free = _enum_type_free;
448d3cc7
MD
214 int_class->len = len;
215 int_class->byte_order = byte_order;
216 int_class->signedness = signedness;
448d3cc7
MD
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.031199 seconds and 4 git commands to generate.