root / qdict.c @ 60398748
History | View | Annotate | Download (6.8 kB)
1 | fb08dde0 | Luiz Capitulino | /*
|
---|---|---|---|
2 | fb08dde0 | Luiz Capitulino | * QDict data type.
|
3 | fb08dde0 | Luiz Capitulino | *
|
4 | fb08dde0 | Luiz Capitulino | * Copyright (C) 2009 Red Hat Inc.
|
5 | fb08dde0 | Luiz Capitulino | *
|
6 | fb08dde0 | Luiz Capitulino | * Authors:
|
7 | fb08dde0 | Luiz Capitulino | * Luiz Capitulino <lcapitulino@redhat.com>
|
8 | fb08dde0 | Luiz Capitulino | *
|
9 | fb08dde0 | Luiz Capitulino | * This work is licensed under the terms of the GNU GPL, version 2. See
|
10 | fb08dde0 | Luiz Capitulino | * the COPYING file in the top-level directory.
|
11 | fb08dde0 | Luiz Capitulino | */
|
12 | fb08dde0 | Luiz Capitulino | |
13 | fb08dde0 | Luiz Capitulino | #include "qint.h" |
14 | fb08dde0 | Luiz Capitulino | #include "qdict.h" |
15 | fb08dde0 | Luiz Capitulino | #include "qstring.h" |
16 | fb08dde0 | Luiz Capitulino | #include "qobject.h" |
17 | 72cf2d4f | Blue Swirl | #include "qemu-queue.h" |
18 | fb08dde0 | Luiz Capitulino | #include "qemu-common.h" |
19 | fb08dde0 | Luiz Capitulino | |
20 | aa43d9cc | Blue Swirl | static void qdict_destroy_obj(QObject *obj); |
21 | aa43d9cc | Blue Swirl | |
22 | aa43d9cc | Blue Swirl | static const QType qdict_type = { |
23 | aa43d9cc | Blue Swirl | .code = QTYPE_QDICT, |
24 | aa43d9cc | Blue Swirl | .destroy = qdict_destroy_obj, |
25 | aa43d9cc | Blue Swirl | }; |
26 | fb08dde0 | Luiz Capitulino | |
27 | fb08dde0 | Luiz Capitulino | /**
|
28 | fb08dde0 | Luiz Capitulino | * qdict_new(): Create a new QDict
|
29 | fb08dde0 | Luiz Capitulino | *
|
30 | fb08dde0 | Luiz Capitulino | * Return strong reference.
|
31 | fb08dde0 | Luiz Capitulino | */
|
32 | fb08dde0 | Luiz Capitulino | QDict *qdict_new(void)
|
33 | fb08dde0 | Luiz Capitulino | { |
34 | fb08dde0 | Luiz Capitulino | QDict *qdict; |
35 | fb08dde0 | Luiz Capitulino | |
36 | fb08dde0 | Luiz Capitulino | qdict = qemu_mallocz(sizeof(*qdict));
|
37 | fb08dde0 | Luiz Capitulino | QOBJECT_INIT(qdict, &qdict_type); |
38 | fb08dde0 | Luiz Capitulino | |
39 | fb08dde0 | Luiz Capitulino | return qdict;
|
40 | fb08dde0 | Luiz Capitulino | } |
41 | fb08dde0 | Luiz Capitulino | |
42 | fb08dde0 | Luiz Capitulino | /**
|
43 | fb08dde0 | Luiz Capitulino | * qobject_to_qdict(): Convert a QObject into a QDict
|
44 | fb08dde0 | Luiz Capitulino | */
|
45 | fb08dde0 | Luiz Capitulino | QDict *qobject_to_qdict(const QObject *obj)
|
46 | fb08dde0 | Luiz Capitulino | { |
47 | fb08dde0 | Luiz Capitulino | if (qobject_type(obj) != QTYPE_QDICT)
|
48 | fb08dde0 | Luiz Capitulino | return NULL; |
49 | fb08dde0 | Luiz Capitulino | |
50 | fb08dde0 | Luiz Capitulino | return container_of(obj, QDict, base);
|
51 | fb08dde0 | Luiz Capitulino | } |
52 | fb08dde0 | Luiz Capitulino | |
53 | fb08dde0 | Luiz Capitulino | /**
|
54 | fb08dde0 | Luiz Capitulino | * tdb_hash(): based on the hash agorithm from gdbm, via tdb
|
55 | fb08dde0 | Luiz Capitulino | * (from module-init-tools)
|
56 | fb08dde0 | Luiz Capitulino | */
|
57 | fb08dde0 | Luiz Capitulino | static unsigned int tdb_hash(const char *name) |
58 | fb08dde0 | Luiz Capitulino | { |
59 | fb08dde0 | Luiz Capitulino | unsigned value; /* Used to compute the hash value. */ |
60 | fb08dde0 | Luiz Capitulino | unsigned i; /* Used to cycle through random values. */ |
61 | fb08dde0 | Luiz Capitulino | |
62 | fb08dde0 | Luiz Capitulino | /* Set the initial value from the key size. */
|
63 | fb08dde0 | Luiz Capitulino | for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++) |
64 | fb08dde0 | Luiz Capitulino | value = (value + (((const unsigned char *)name)[i] << (i*5 % 24))); |
65 | fb08dde0 | Luiz Capitulino | |
66 | fb08dde0 | Luiz Capitulino | return (1103515243 * value + 12345); |
67 | fb08dde0 | Luiz Capitulino | } |
68 | fb08dde0 | Luiz Capitulino | |
69 | fb08dde0 | Luiz Capitulino | /**
|
70 | fb08dde0 | Luiz Capitulino | * alloc_entry(): allocate a new QDictEntry
|
71 | fb08dde0 | Luiz Capitulino | */
|
72 | fb08dde0 | Luiz Capitulino | static QDictEntry *alloc_entry(const char *key, QObject *value) |
73 | fb08dde0 | Luiz Capitulino | { |
74 | fb08dde0 | Luiz Capitulino | QDictEntry *entry; |
75 | fb08dde0 | Luiz Capitulino | |
76 | fb08dde0 | Luiz Capitulino | entry = qemu_mallocz(sizeof(*entry));
|
77 | fb08dde0 | Luiz Capitulino | entry->key = qemu_strdup(key); |
78 | fb08dde0 | Luiz Capitulino | entry->value = value; |
79 | fb08dde0 | Luiz Capitulino | |
80 | fb08dde0 | Luiz Capitulino | return entry;
|
81 | fb08dde0 | Luiz Capitulino | } |
82 | fb08dde0 | Luiz Capitulino | |
83 | fb08dde0 | Luiz Capitulino | /**
|
84 | fb08dde0 | Luiz Capitulino | * qdict_find(): List lookup function
|
85 | fb08dde0 | Luiz Capitulino | */
|
86 | fb08dde0 | Luiz Capitulino | static QDictEntry *qdict_find(const QDict *qdict, |
87 | fb08dde0 | Luiz Capitulino | const char *key, unsigned int hash) |
88 | fb08dde0 | Luiz Capitulino | { |
89 | fb08dde0 | Luiz Capitulino | QDictEntry *entry; |
90 | fb08dde0 | Luiz Capitulino | |
91 | 72cf2d4f | Blue Swirl | QLIST_FOREACH(entry, &qdict->table[hash], next) |
92 | fb08dde0 | Luiz Capitulino | if (!strcmp(entry->key, key))
|
93 | fb08dde0 | Luiz Capitulino | return entry;
|
94 | fb08dde0 | Luiz Capitulino | |
95 | fb08dde0 | Luiz Capitulino | return NULL; |
96 | fb08dde0 | Luiz Capitulino | } |
97 | fb08dde0 | Luiz Capitulino | |
98 | fb08dde0 | Luiz Capitulino | /**
|
99 | fb08dde0 | Luiz Capitulino | * qdict_put_obj(): Put a new QObject into the dictionary
|
100 | fb08dde0 | Luiz Capitulino | *
|
101 | fb08dde0 | Luiz Capitulino | * Insert the pair 'key:value' into 'qdict', if 'key' already exists
|
102 | fb08dde0 | Luiz Capitulino | * its 'value' will be replaced.
|
103 | fb08dde0 | Luiz Capitulino | *
|
104 | fb08dde0 | Luiz Capitulino | * This is done by freeing the reference to the stored QObject and
|
105 | fb08dde0 | Luiz Capitulino | * storing the new one in the same entry.
|
106 | fb08dde0 | Luiz Capitulino | *
|
107 | fb08dde0 | Luiz Capitulino | * NOTE: ownership of 'value' is transferred to the QDict
|
108 | fb08dde0 | Luiz Capitulino | */
|
109 | fb08dde0 | Luiz Capitulino | void qdict_put_obj(QDict *qdict, const char *key, QObject *value) |
110 | fb08dde0 | Luiz Capitulino | { |
111 | fb08dde0 | Luiz Capitulino | unsigned int hash; |
112 | fb08dde0 | Luiz Capitulino | QDictEntry *entry; |
113 | fb08dde0 | Luiz Capitulino | |
114 | fb08dde0 | Luiz Capitulino | hash = tdb_hash(key) % QDICT_HASH_SIZE; |
115 | fb08dde0 | Luiz Capitulino | entry = qdict_find(qdict, key, hash); |
116 | fb08dde0 | Luiz Capitulino | if (entry) {
|
117 | fb08dde0 | Luiz Capitulino | /* replace key's value */
|
118 | fb08dde0 | Luiz Capitulino | qobject_decref(entry->value); |
119 | fb08dde0 | Luiz Capitulino | entry->value = value; |
120 | fb08dde0 | Luiz Capitulino | } else {
|
121 | fb08dde0 | Luiz Capitulino | /* allocate a new entry */
|
122 | fb08dde0 | Luiz Capitulino | entry = alloc_entry(key, value); |
123 | 72cf2d4f | Blue Swirl | QLIST_INSERT_HEAD(&qdict->table[hash], entry, next); |
124 | fb08dde0 | Luiz Capitulino | } |
125 | fb08dde0 | Luiz Capitulino | |
126 | fb08dde0 | Luiz Capitulino | qdict->size++; |
127 | fb08dde0 | Luiz Capitulino | } |
128 | fb08dde0 | Luiz Capitulino | |
129 | fb08dde0 | Luiz Capitulino | /**
|
130 | fb08dde0 | Luiz Capitulino | * qdict_get(): Lookup for a given 'key'
|
131 | fb08dde0 | Luiz Capitulino | *
|
132 | fb08dde0 | Luiz Capitulino | * Return a weak reference to the QObject associated with 'key' if
|
133 | fb08dde0 | Luiz Capitulino | * 'key' is present in the dictionary, NULL otherwise.
|
134 | fb08dde0 | Luiz Capitulino | */
|
135 | fb08dde0 | Luiz Capitulino | QObject *qdict_get(const QDict *qdict, const char *key) |
136 | fb08dde0 | Luiz Capitulino | { |
137 | fb08dde0 | Luiz Capitulino | QDictEntry *entry; |
138 | fb08dde0 | Luiz Capitulino | |
139 | fb08dde0 | Luiz Capitulino | entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE); |
140 | fb08dde0 | Luiz Capitulino | return (entry == NULL ? NULL : entry->value); |
141 | fb08dde0 | Luiz Capitulino | } |
142 | fb08dde0 | Luiz Capitulino | |
143 | fb08dde0 | Luiz Capitulino | /**
|
144 | fb08dde0 | Luiz Capitulino | * qdict_haskey(): Check if 'key' exists
|
145 | fb08dde0 | Luiz Capitulino | *
|
146 | fb08dde0 | Luiz Capitulino | * Return 1 if 'key' exists in the dict, 0 otherwise
|
147 | fb08dde0 | Luiz Capitulino | */
|
148 | fb08dde0 | Luiz Capitulino | int qdict_haskey(const QDict *qdict, const char *key) |
149 | fb08dde0 | Luiz Capitulino | { |
150 | fb08dde0 | Luiz Capitulino | unsigned int hash = tdb_hash(key) % QDICT_HASH_SIZE; |
151 | fb08dde0 | Luiz Capitulino | return (qdict_find(qdict, key, hash) == NULL ? 0 : 1); |
152 | fb08dde0 | Luiz Capitulino | } |
153 | fb08dde0 | Luiz Capitulino | |
154 | fb08dde0 | Luiz Capitulino | /**
|
155 | fb08dde0 | Luiz Capitulino | * qdict_size(): Return the size of the dictionary
|
156 | fb08dde0 | Luiz Capitulino | */
|
157 | fb08dde0 | Luiz Capitulino | size_t qdict_size(const QDict *qdict)
|
158 | fb08dde0 | Luiz Capitulino | { |
159 | fb08dde0 | Luiz Capitulino | return qdict->size;
|
160 | fb08dde0 | Luiz Capitulino | } |
161 | fb08dde0 | Luiz Capitulino | |
162 | fb08dde0 | Luiz Capitulino | /**
|
163 | fb08dde0 | Luiz Capitulino | * qdict_get_obj(): Get a QObject of a specific type
|
164 | fb08dde0 | Luiz Capitulino | */
|
165 | fb08dde0 | Luiz Capitulino | static QObject *qdict_get_obj(const QDict *qdict, const char *key, |
166 | fb08dde0 | Luiz Capitulino | qtype_code type) |
167 | fb08dde0 | Luiz Capitulino | { |
168 | fb08dde0 | Luiz Capitulino | QObject *obj; |
169 | fb08dde0 | Luiz Capitulino | |
170 | fb08dde0 | Luiz Capitulino | obj = qdict_get(qdict, key); |
171 | fb08dde0 | Luiz Capitulino | assert(obj != NULL);
|
172 | fb08dde0 | Luiz Capitulino | assert(qobject_type(obj) == type); |
173 | fb08dde0 | Luiz Capitulino | |
174 | fb08dde0 | Luiz Capitulino | return obj;
|
175 | fb08dde0 | Luiz Capitulino | } |
176 | fb08dde0 | Luiz Capitulino | |
177 | fb08dde0 | Luiz Capitulino | /**
|
178 | fb08dde0 | Luiz Capitulino | * qdict_get_int(): Get an integer mapped by 'key'
|
179 | fb08dde0 | Luiz Capitulino | *
|
180 | fb08dde0 | Luiz Capitulino | * This function assumes that 'key' exists and it stores a
|
181 | fb08dde0 | Luiz Capitulino | * QInt object.
|
182 | fb08dde0 | Luiz Capitulino | *
|
183 | fb08dde0 | Luiz Capitulino | * Return integer mapped by 'key'.
|
184 | fb08dde0 | Luiz Capitulino | */
|
185 | fb08dde0 | Luiz Capitulino | int64_t qdict_get_int(const QDict *qdict, const char *key) |
186 | fb08dde0 | Luiz Capitulino | { |
187 | fb08dde0 | Luiz Capitulino | QObject *obj = qdict_get_obj(qdict, key, QTYPE_QINT); |
188 | fb08dde0 | Luiz Capitulino | return qint_get_int(qobject_to_qint(obj));
|
189 | fb08dde0 | Luiz Capitulino | } |
190 | fb08dde0 | Luiz Capitulino | |
191 | fb08dde0 | Luiz Capitulino | /**
|
192 | fb08dde0 | Luiz Capitulino | * qdict_get_str(): Get a pointer to the stored string mapped
|
193 | fb08dde0 | Luiz Capitulino | * by 'key'
|
194 | fb08dde0 | Luiz Capitulino | *
|
195 | fb08dde0 | Luiz Capitulino | * This function assumes that 'key' exists and it stores a
|
196 | fb08dde0 | Luiz Capitulino | * QString object.
|
197 | fb08dde0 | Luiz Capitulino | *
|
198 | fb08dde0 | Luiz Capitulino | * Return pointer to the string mapped by 'key'.
|
199 | fb08dde0 | Luiz Capitulino | */
|
200 | fb08dde0 | Luiz Capitulino | const char *qdict_get_str(const QDict *qdict, const char *key) |
201 | fb08dde0 | Luiz Capitulino | { |
202 | fb08dde0 | Luiz Capitulino | QObject *obj = qdict_get_obj(qdict, key, QTYPE_QSTRING); |
203 | fb08dde0 | Luiz Capitulino | return qstring_get_str(qobject_to_qstring(obj));
|
204 | fb08dde0 | Luiz Capitulino | } |
205 | fb08dde0 | Luiz Capitulino | |
206 | fb08dde0 | Luiz Capitulino | /**
|
207 | fb08dde0 | Luiz Capitulino | * qdict_get_try_int(): Try to get integer mapped by 'key'
|
208 | fb08dde0 | Luiz Capitulino | *
|
209 | fb08dde0 | Luiz Capitulino | * Return integer mapped by 'key', if it is not present in
|
210 | fb08dde0 | Luiz Capitulino | * the dictionary or if the stored object is not of QInt type
|
211 | fb08dde0 | Luiz Capitulino | * 'err_value' will be returned.
|
212 | fb08dde0 | Luiz Capitulino | */
|
213 | fb08dde0 | Luiz Capitulino | int64_t qdict_get_try_int(const QDict *qdict, const char *key, |
214 | fb08dde0 | Luiz Capitulino | int64_t err_value) |
215 | fb08dde0 | Luiz Capitulino | { |
216 | fb08dde0 | Luiz Capitulino | QObject *obj; |
217 | fb08dde0 | Luiz Capitulino | |
218 | fb08dde0 | Luiz Capitulino | obj = qdict_get(qdict, key); |
219 | fb08dde0 | Luiz Capitulino | if (!obj || qobject_type(obj) != QTYPE_QINT)
|
220 | fb08dde0 | Luiz Capitulino | return err_value;
|
221 | fb08dde0 | Luiz Capitulino | |
222 | fb08dde0 | Luiz Capitulino | return qint_get_int(qobject_to_qint(obj));
|
223 | fb08dde0 | Luiz Capitulino | } |
224 | fb08dde0 | Luiz Capitulino | |
225 | fb08dde0 | Luiz Capitulino | /**
|
226 | fb08dde0 | Luiz Capitulino | * qdict_get_try_str(): Try to get a pointer to the stored string
|
227 | fb08dde0 | Luiz Capitulino | * mapped by 'key'
|
228 | fb08dde0 | Luiz Capitulino | *
|
229 | fb08dde0 | Luiz Capitulino | * Return a pointer to the string mapped by 'key', if it is not present
|
230 | fb08dde0 | Luiz Capitulino | * in the dictionary or if the stored object is not of QString type
|
231 | fb08dde0 | Luiz Capitulino | * NULL will be returned.
|
232 | fb08dde0 | Luiz Capitulino | */
|
233 | fb08dde0 | Luiz Capitulino | const char *qdict_get_try_str(const QDict *qdict, const char *key) |
234 | fb08dde0 | Luiz Capitulino | { |
235 | fb08dde0 | Luiz Capitulino | QObject *obj; |
236 | fb08dde0 | Luiz Capitulino | |
237 | fb08dde0 | Luiz Capitulino | obj = qdict_get(qdict, key); |
238 | fb08dde0 | Luiz Capitulino | if (!obj || qobject_type(obj) != QTYPE_QSTRING)
|
239 | fb08dde0 | Luiz Capitulino | return NULL; |
240 | fb08dde0 | Luiz Capitulino | |
241 | fb08dde0 | Luiz Capitulino | return qstring_get_str(qobject_to_qstring(obj));
|
242 | fb08dde0 | Luiz Capitulino | } |
243 | fb08dde0 | Luiz Capitulino | |
244 | fb08dde0 | Luiz Capitulino | /**
|
245 | fb08dde0 | Luiz Capitulino | * qentry_destroy(): Free all the memory allocated by a QDictEntry
|
246 | fb08dde0 | Luiz Capitulino | */
|
247 | fb08dde0 | Luiz Capitulino | static void qentry_destroy(QDictEntry *e) |
248 | fb08dde0 | Luiz Capitulino | { |
249 | fb08dde0 | Luiz Capitulino | assert(e != NULL);
|
250 | fb08dde0 | Luiz Capitulino | assert(e->key != NULL);
|
251 | fb08dde0 | Luiz Capitulino | assert(e->value != NULL);
|
252 | fb08dde0 | Luiz Capitulino | |
253 | fb08dde0 | Luiz Capitulino | qobject_decref(e->value); |
254 | fb08dde0 | Luiz Capitulino | qemu_free(e->key); |
255 | fb08dde0 | Luiz Capitulino | qemu_free(e); |
256 | fb08dde0 | Luiz Capitulino | } |
257 | fb08dde0 | Luiz Capitulino | |
258 | fb08dde0 | Luiz Capitulino | /**
|
259 | fb08dde0 | Luiz Capitulino | * qdict_del(): Delete a 'key:value' pair from the dictionary
|
260 | fb08dde0 | Luiz Capitulino | *
|
261 | fb08dde0 | Luiz Capitulino | * This will destroy all data allocated by this entry.
|
262 | fb08dde0 | Luiz Capitulino | */
|
263 | fb08dde0 | Luiz Capitulino | void qdict_del(QDict *qdict, const char *key) |
264 | fb08dde0 | Luiz Capitulino | { |
265 | fb08dde0 | Luiz Capitulino | QDictEntry *entry; |
266 | fb08dde0 | Luiz Capitulino | |
267 | fb08dde0 | Luiz Capitulino | entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE); |
268 | fb08dde0 | Luiz Capitulino | if (entry) {
|
269 | 72cf2d4f | Blue Swirl | QLIST_REMOVE(entry, next); |
270 | fb08dde0 | Luiz Capitulino | qentry_destroy(entry); |
271 | fb08dde0 | Luiz Capitulino | qdict->size--; |
272 | fb08dde0 | Luiz Capitulino | } |
273 | fb08dde0 | Luiz Capitulino | } |
274 | fb08dde0 | Luiz Capitulino | |
275 | fb08dde0 | Luiz Capitulino | /**
|
276 | fb08dde0 | Luiz Capitulino | * qdict_destroy_obj(): Free all the memory allocated by a QDict
|
277 | fb08dde0 | Luiz Capitulino | */
|
278 | fb08dde0 | Luiz Capitulino | static void qdict_destroy_obj(QObject *obj) |
279 | fb08dde0 | Luiz Capitulino | { |
280 | fb08dde0 | Luiz Capitulino | int i;
|
281 | fb08dde0 | Luiz Capitulino | QDict *qdict; |
282 | fb08dde0 | Luiz Capitulino | |
283 | fb08dde0 | Luiz Capitulino | assert(obj != NULL);
|
284 | fb08dde0 | Luiz Capitulino | qdict = qobject_to_qdict(obj); |
285 | fb08dde0 | Luiz Capitulino | |
286 | fb08dde0 | Luiz Capitulino | for (i = 0; i < QDICT_HASH_SIZE; i++) { |
287 | 72cf2d4f | Blue Swirl | QDictEntry *entry = QLIST_FIRST(&qdict->table[i]); |
288 | fb08dde0 | Luiz Capitulino | while (entry) {
|
289 | 72cf2d4f | Blue Swirl | QDictEntry *tmp = QLIST_NEXT(entry, next); |
290 | 72cf2d4f | Blue Swirl | QLIST_REMOVE(entry, next); |
291 | fb08dde0 | Luiz Capitulino | qentry_destroy(entry); |
292 | fb08dde0 | Luiz Capitulino | entry = tmp; |
293 | fb08dde0 | Luiz Capitulino | } |
294 | fb08dde0 | Luiz Capitulino | } |
295 | fb08dde0 | Luiz Capitulino | |
296 | fb08dde0 | Luiz Capitulino | qemu_free(qdict); |
297 | fb08dde0 | Luiz Capitulino | } |