3 /* dict_multi - dictionnaries of dictionnaries of ... of data */
5 /* Copyright (c) 2003, 2004 Martin Quinson. All rights reserved. */
7 /* This program is free software; you can redistribute it and/or modify it
8 * under the terms of the license (GNU LGPL) which comes with this package. */
10 #include "gras_private.h"
12 #include <stdlib.h> /* malloc() */
13 #include <string.h> /* strlen() */
15 /*####[ Multi dict functions ]##############################################*/
16 /*###############################"##########################################*/
20 * @head: the head of dict
21 * @keycount: the number of the key
23 * @data: the data to set
24 * @Returns: gras_error_t
26 * set the data in the structure under the @keycount @key.
30 gras_multidict_set_ext(gras_dict_t **pp_head,
35 void_f_pvoid_t *free_ctn) {
36 gras_error_t errcode = no_error;
37 gras_dictelm_t *p_elm = NULL;
38 gras_dictelm_t *p_subdict = NULL;
41 CDEBUG2(dict_multi, "fast_multidict_set(%p,%d). Keys:", *pp_head, keycount);
44 for (i = 0; i < keycount; i++) {
45 CDEBUG1(dict_multi, "\"%s\"", key[i]);
49 gras_assert0(keycount >= 1, "Can't set less than one key in a multidict");
52 return gras_dict_set_ext(pp_head, key[0], key_len[0], data, free_ctn);
55 TRY(_gras_dict_alloc(NULL, 0, 0, NULL, NULL, pp_head));
60 for (i = 0; i < keycount-1; i++) {
62 /* search the dict of next level */
63 TRYCATCH(gras_dict_get(p_elm, key[i], (void*)&p_subdict), mismatch_error);
65 /* make sure the dict of next level exists */
66 if (errcode == mismatch_error) {
67 TRY(_gras_dict_alloc(NULL, 0, 0, NULL, NULL, &p_subdict));
68 TRY(gras_dict_set_ext(&p_elm, key[i], key_len[i], &p_subdict,
75 return gras_dict_set_ext(&p_elm, key[i], key_len[i], data, free_ctn);
79 gras_multidict_set(gras_dictelm_t **pp_head,
83 void_f_pvoid_t *free_ctn) {
84 gras_error_t errcode = no_error;
88 key_len = malloc(keycount * sizeof (int));
92 for (i = 0; i < keycount; i++) {
93 key_len[i] = 1+strlen(key[i]);
96 TRYCLEAN(gras_multidict_set_ext(pp_head, keycount, key, key_len, data, free_ctn),
107 * @head: the head of dict
108 * @keycount: the number of the key
110 * @data: where to put the got data
111 * @Returns: gras_error_t
113 * Search the given @key. data=NULL when not found
118 gras_multidict_get_ext(gras_dictelm_t *p_head,
122 /* OUT */void **data) {
123 gras_error_t errcode = no_error;
124 gras_dictelm_t *p_elm = p_head;
127 CDEBUG2(dict_multi, "fast_multidict_get(%p, %d). Keys:", p_head, keycount);
130 for (i = 0; i < keycount; i++) {
131 CDEBUG1(dict_multi, "\"%s\"", key[i]);
137 while (p_elm && i < keycount-1) {
139 TRY(gras_dict_get_ext(p_elm, key[i], key_len[i], (void**)p_elm));
143 CDEBUG3(dict_multi,"Found level %d for key %s in multitree %", i, key[i], p_head);
145 CDEBUG3(dict_multi,"NOT found level %d for key %s in multitree %p", i, key[i], p_head);
152 if (p_elm) { /* Found all dicts to the data */
154 /* gras_dict_dump(dict,&gras_dict_prints); */
155 return gras_dict_get_ext(p_elm, key[i], key_len[i], data);
167 gras_multidict_get(gras_dictelm_t *p_head,
170 /* OUT */void **data) {
171 gras_error_t errcode = no_error;
175 key_len = malloc(keycount * sizeof (int));
179 for (i = 0; i < keycount; i++) {
180 key_len[i] = 1+strlen(key[i]);
183 TRYCLEAN(gras_multidict_get_ext(p_head, keycount, key, key_len, data),
192 * gras_mutidict_remove:
194 * @head: the head of dict
195 * @keycount: the number of the key
197 * @Returns: gras_error_t
199 * Remove the entry associated with the given @key
200 * Removing a non-existant key is ok.
204 gras_multidict_remove_ext(gras_dictelm_t *p_head,
208 gras_dictelm_t *p_elm = p_head;
211 while (p_elm && i < keycount-1) {
212 if (!gras_dict_get_ext(p_elm, key[i], key_len[i], (void**)&p_elm)) {
218 /* Found all dicts to the data */
219 return gras_dict_remove_ext(p_elm, key[i], key_len[i]);
227 gras_multidict_remove(gras_dictelm_t *p_head,
230 gras_error_t errcode = no_error;
234 key_len = malloc(keycount * sizeof (int));
238 for (i = 0; i < keycount; i++) {
239 key_len[i] = 1+strlen(key[i]);
242 TRYCLEAN(gras_multidict_remove_ext(p_head, keycount, key, key_len),