3 /* dict_multi - dictionnaries of dictionnaries of ... of data */
5 /* Authors: Martin Quinson */
6 /* Copyright (C) 2003,2004 Martin Quinson. */
8 /* This program is free software; you can redistribute it and/or modify it
9 under the terms of the license (GNU LGPL) which comes with this package. */
11 #include "gras_private.h"
13 #include <stdlib.h> /* malloc() */
14 #include <string.h> /* strlen() */
16 /*####[ Multi dict functions ]##############################################*/
17 /*###############################"##########################################*/
21 * @head: the head of dict
22 * @keycount: the number of the key
24 * @data: the data to set
25 * @Returns: gras_error_t
27 * set the data in the structure under the @keycount @key.
31 gras_multidict_set_ext(gras_dict_t **pp_head,
36 void_f_pvoid_t *free_ctn) {
37 gras_error_t errcode = no_error;
38 gras_dictelm_t *p_elm = NULL;
39 gras_dictelm_t *p_subdict = NULL;
42 CDEBUG2(dict_multi, "fast_multidict_set(%p,%d). Keys:", *pp_head, keycount);
45 for (i = 0; i < keycount; i++) {
46 CDEBUG1(dict_multi, "\"%s\"", key[i]);
50 gras_assert0(keycount >= 1, "Can't set less than one key in a multidict");
53 return gras_dict_set_ext(pp_head, key[0], key_len[0], data, free_ctn);
56 TRY(_gras_dict_alloc(NULL, 0, 0, NULL, NULL, pp_head));
61 for (i = 0; i < keycount-1; i++) {
63 /* search the dict of next level */
64 TRYCATCH(gras_dict_get(p_elm, key[i], (void*)&p_subdict), mismatch_error);
66 /* make sure the dict of next level exists */
67 if (errcode == mismatch_error) {
68 TRY(_gras_dict_alloc(NULL, 0, 0, NULL, NULL, &p_subdict));
69 TRY(gras_dict_set_ext(&p_elm, key[i], key_len[i], &p_subdict,
76 return gras_dict_set_ext(&p_elm, key[i], key_len[i], data, free_ctn);
80 gras_multidict_set(gras_dictelm_t **pp_head,
84 void_f_pvoid_t *free_ctn) {
85 gras_error_t errcode = no_error;
89 key_len = malloc(keycount * sizeof (int));
93 for (i = 0; i < keycount; i++) {
94 key_len[i] = 1+strlen(key[i]);
97 TRYCLEAN(gras_multidict_set_ext(pp_head, keycount, key, key_len, data, free_ctn),
108 * @head: the head of dict
109 * @keycount: the number of the key
111 * @data: where to put the got data
112 * @Returns: gras_error_t
114 * Search the given @key. data=NULL when not found
119 gras_multidict_get_ext(gras_dictelm_t *p_head,
123 /* OUT */void **data) {
124 gras_error_t errcode = no_error;
125 gras_dictelm_t *p_elm = p_head;
128 CDEBUG2(dict_multi, "fast_multidict_get(%p, %d). Keys:", p_head, keycount);
131 for (i = 0; i < keycount; i++) {
132 CDEBUG1(dict_multi, "\"%s\"", key[i]);
138 while (p_elm && i < keycount-1) {
140 TRY(gras_dict_get_ext(p_elm, key[i], key_len[i], (void**)p_elm));
144 CDEBUG3(dict_multi,"Found level %d for key %s in multitree %", i, key[i], p_head);
146 CDEBUG3(dict_multi,"NOT found level %d for key %s in multitree %p", i, key[i], p_head);
153 if (p_elm) { /* Found all dicts to the data */
155 /* gras_dict_dump(dict,&gras_dict_prints); */
156 return gras_dict_get_ext(p_elm, key[i], key_len[i], data);
168 gras_multidict_get(gras_dictelm_t *p_head,
171 /* OUT */void **data) {
172 gras_error_t errcode = no_error;
176 key_len = malloc(keycount * sizeof (int));
180 for (i = 0; i < keycount; i++) {
181 key_len[i] = 1+strlen(key[i]);
184 TRYCLEAN(gras_multidict_get_ext(p_head, keycount, key, key_len, data),
193 * gras_mutidict_remove:
195 * @head: the head of dict
196 * @keycount: the number of the key
198 * @Returns: gras_error_t
200 * Remove the entry associated with the given @key
201 * Removing a non-existant key is ok.
205 gras_multidict_remove_ext(gras_dictelm_t *p_head,
209 gras_dictelm_t *p_elm = p_head;
212 while (p_elm && i < keycount-1) {
213 if (!gras_dict_get_ext(p_elm, key[i], key_len[i], (void**)&p_elm)) {
219 /* Found all dicts to the data */
220 return gras_dict_remove_ext(p_elm, key[i], key_len[i]);
228 gras_multidict_remove(gras_dictelm_t *p_head,
231 gras_error_t errcode = no_error;
235 key_len = malloc(keycount * sizeof (int));
239 for (i = 0; i < keycount; i++) {
240 key_len[i] = 1+strlen(key[i]);
243 TRYCLEAN(gras_multidict_remove_ext(p_head, keycount, key, key_len),