Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
The change Arnaud wanted so much: Big Star Eradication (plus some more, check the...
[simgrid.git] / src / xbt / dict_multi.c
1 /* $Id$ */
2
3 /* dict_multi - dictionnaries of dictionnaries of ... of data               */
4
5 /* Authors: Martin Quinson                                                  */
6 /* Copyright (C) 2003,2004 Martin Quinson.                                  */
7
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. */
10
11 #include "gras_private.h"
12
13 #include <stdlib.h> /* malloc() */
14 #include <string.h> /* strlen() */
15
16 /*####[ Multi dict functions ]##############################################*/
17 /*###############################"##########################################*/
18 /**
19  * gras_mutidict_set:
20  *
21  * @head: the head of dict
22  * @keycount: the number of the key
23  * @key: the key
24  * @data: the data to set
25  * @Returns: gras_error_t
26  *
27  * set the data in the structure under the @keycount @key.
28  */
29
30 gras_error_t
31 gras_multidict_set_ext(gras_dict_t    **pp_head,
32                           int              keycount,
33                           char           **key,
34                           int             *key_len,
35                           void            *data,
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;
40   int           i         =        0;
41
42   CDEBUG2(dict_multi, "fast_multidict_set(%p,%d). Keys:", *pp_head, keycount);
43
44   /*
45   for (i = 0; i < keycount; i++) {
46     CDEBUG1(dict_multi, "\"%s\"", key[i]);
47   }
48   */
49
50   gras_assert0(keycount >= 1, "Can't set less than one key in a multidict");
51
52   if (keycount == 1)
53     return gras_dict_set_ext(pp_head, key[0], key_len[0], data, free_ctn);
54
55   if (!*pp_head) {
56     TRY(_gras_dict_alloc(NULL, 0, 0, NULL, NULL, pp_head));
57   }
58
59   p_elm = *pp_head;
60
61   for (i = 0; i < keycount-1; i++) {
62
63     /* search the dict of next level */
64     TRYCATCH(gras_dict_get(p_elm, key[i], (void*)&p_subdict), mismatch_error);
65
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,
70                                _free_dict));
71     }
72
73     p_elm = p_subdict;
74   }
75
76   return gras_dict_set_ext(&p_elm, key[i], key_len[i], data, free_ctn);
77 }
78
79 gras_error_t
80 gras_multidict_set(gras_dictelm_t    **pp_head,
81                       int              keycount,
82                       char           **key,
83                       void            *data,
84                       void_f_pvoid_t  *free_ctn) {
85   gras_error_t  errcode = no_error;
86   int          *key_len = NULL;
87   int           i       = 0;
88
89   key_len = malloc(keycount * sizeof (int));
90   if (!key_len)
91     RAISE_MALLOC;
92
93   for (i = 0; i < keycount; i++) {
94     key_len[i] = 1+strlen(key[i]);
95   }
96
97   TRYCLEAN(gras_multidict_set_ext(pp_head, keycount, key, key_len, data, free_ctn),
98            gras_free(key_len));
99
100   gras_free(key_len);
101
102   return errcode;
103 }
104
105 /**
106  * gras_mutidict_get:
107  *
108  * @head: the head of dict
109  * @keycount: the number of the key
110  * @key: the key
111  * @data: where to put the got data
112  * @Returns: gras_error_t
113  *
114  * Search the given @key. data=NULL when not found
115  */
116
117
118 gras_error_t
119 gras_multidict_get_ext(gras_dictelm_t    *p_head,
120                             int             keycount,
121                             const char    **key,
122                             int            *key_len,
123                             /* OUT */void **data) {
124   gras_error_t  errcode = no_error;
125   gras_dictelm_t  *p_elm  =   p_head;
126   int           i       =        0;
127
128   CDEBUG2(dict_multi, "fast_multidict_get(%p, %d). Keys:", p_head, keycount);
129
130   /*
131   for (i = 0; i < keycount; i++) {
132     CDEBUG1(dict_multi, "\"%s\"", key[i]);
133   }
134   */
135
136   i = 0;
137
138   while (p_elm && i < keycount-1) {
139
140     TRY(gras_dict_get_ext(p_elm, key[i], key_len[i], (void**)p_elm));
141
142     /*
143     if (p_elm) {
144       CDEBUG3(dict_multi,"Found level %d for key %s in multitree %", i, key[i], p_head);
145     } else {
146       CDEBUG3(dict_multi,"NOT found level %d for key %s in multitree %p", i, key[i], p_head);
147     }
148     */
149
150     i++;
151   }
152
153   if (p_elm) { /* Found all dicts to the data */
154
155     /*    gras_dict_dump(dict,&gras_dict_prints); */
156     return gras_dict_get_ext(p_elm, key[i], key_len[i], data);
157
158   } else {
159
160     *data = NULL;
161
162     return 1;
163   }
164
165 }
166
167 gras_error_t
168 gras_multidict_get(gras_dictelm_t    *p_head,
169                         int             keycount,
170                         const char    **key,
171                         /* OUT */void **data) {
172   gras_error_t  errcode = no_error;
173   int          *key_len = NULL;
174   int           i       = 0;
175
176   key_len = malloc(keycount * sizeof (int));
177   if (!key_len)
178     RAISE_MALLOC;
179
180   for (i = 0; i < keycount; i++) {
181     key_len[i] = 1+strlen(key[i]);
182   }
183
184   TRYCLEAN(gras_multidict_get_ext(p_head, keycount, key, key_len, data),
185            gras_free(key_len));
186   gras_free(key_len);
187
188   return errcode;
189 }
190
191
192 /**
193  *  gras_mutidict_remove:
194  *
195  *  @head: the head of dict
196  *  @keycount: the number of the key
197  *  @key: the key
198  *  @Returns: gras_error_t
199  *
200  * Remove the entry associated with the given @key
201  * Removing a non-existant key is ok.
202  */
203
204 gras_error_t
205 gras_multidict_remove_ext(gras_dictelm_t  *p_head,
206                           int           keycount,
207                           const char  **key,
208                           int          *key_len) {
209   gras_dictelm_t *p_elm = p_head;
210   int          i      =      0;
211
212   while (p_elm && i < keycount-1) {
213     if (!gras_dict_get_ext(p_elm, key[i], key_len[i], (void**)&p_elm)) {
214       return 0;
215     }
216   }
217
218   if (p_elm) {
219     /* Found all dicts to the data */
220     return gras_dict_remove_ext(p_elm, key[i], key_len[i]);
221   } else {
222     return 1;
223   }
224
225 }
226
227 gras_error_t
228 gras_multidict_remove(gras_dictelm_t  *p_head,
229                       int           keycount,
230                       const char  **key) {
231   gras_error_t  errcode = no_error;
232   int          *key_len = NULL;
233   int           i       = 0;
234
235   key_len = malloc(keycount * sizeof (int));
236   if (!key_len)
237     RAISE_MALLOC;
238
239   for (i = 0; i < keycount; i++) {
240     key_len[i] = 1+strlen(key[i]);
241   }
242
243   TRYCLEAN(gras_multidict_remove_ext(p_head, keycount, key, key_len),
244            gras_free(key_len));
245   gras_free(key_len);
246
247   return errcode;
248 }