00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef lint
00022
00023 #endif
00024
00025
00026 #include "dictionary.h"
00027 #include "libicl.h"
00028 #ifdef _WINDOWS
00029 #include <stdlib.h>
00030 #endif
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034
00035
00036
00037
00038
00043 DICTIONARY *dict_new(int (*_compar)(void *, void *), void (*_keyfree)(void *)) {
00044 DICTIONARY *newdict = (DICTIONARY *)malloc(sizeof(DICTIONARY));
00045
00046 newdict->size = 0;
00047 newdict->capacity = INIT_CAPACITY;
00048 newdict->compar = _compar;
00049 newdict->keyfree = _keyfree;
00050
00051 if(!(newdict->key = (void *)calloc(INIT_CAPACITY, sizeof(void*)))) {
00052 return NULL;
00053 }
00054 if(!(newdict->value = (void *)calloc(INIT_CAPACITY, sizeof(void*)))) {
00055 return NULL;
00056 }
00057 return newdict;
00058 }
00063 int dict_expand_capacity(DICTIONARY *dict) {
00064 void **newkey, **newval;
00065 int newcap, i, n;
00066
00067 if(!dict)
00068 return -1;
00069 newcap = dict->capacity + INIT_CAPACITY;
00070 if(!(newkey = (void *)calloc(newcap, sizeof(void*))))
00071 return dict->capacity;
00072 if(!(newval = (void *)calloc(newcap, sizeof(void*))))
00073 return dict->capacity;
00074 for(i=0, n=dict->size; i<n; i++) {
00075 newkey[i] = dict->key[i];
00076 newval[i] = dict->value[i];
00077 }
00078 free(dict->key);
00079 free(dict->value);
00080 dict->key = newkey;
00081 dict->value = newval;
00082 return(dict->capacity = newcap);
00083 }
00087 void *dict_get(DICTIONARY *d, void *key) {
00088 int i, n;
00089
00090 for(i=0, n=d->size; i<n; i++) {
00091 if(d->compar(key, d->key[i]) == 1) {
00092 return d->value[i];
00093 }
00094 }
00095 return NULL;
00096 }
00097
00102 int dict_get_nth(DICTIONARY *d, void **key, void **value, int n) {
00103 if((n >= 0) && (n < d->size)) {
00104 *key = d->key[n];
00105 *value = d->value[n];
00106 return 1;
00107 }
00108 return 0;
00109 }
00110
00114 int dict_index_for_key(DICTIONARY *d, void *key) {
00115 int i,n;
00116
00117 for(i=0, n=d->size; i<n; i++) {
00118 if(d->compar(key, d->key[i]) == 1) {
00119 return i;
00120 }
00121 }
00122 return -1;
00123 }
00124
00129 void *dict_put(DICTIONARY *d, void *key, void *value) {
00130 int oldsize, index;
00131 void *ret = NULL;
00132
00133 if(!d) return ret;
00134 oldsize = d->size;
00135
00136 if((index = dict_index_for_key(d, key)) < 0) {
00137
00138 if(oldsize >= d->capacity)
00139 if(dict_expand_capacity(d) <= oldsize)
00140 return NULL;
00141
00142 d->key[oldsize] = key;
00143 d->value[oldsize] = value;
00144 d->size++;
00145 } else {
00146 ret = d->value[index];
00147 d->value[index] = value;
00148 }
00149 return ret;
00150 }
00151
00157 void *dict_put_nonunique(DICTIONARY *d, void *key, void *value) {
00158 int oldsize;
00159 void *ret = NULL;
00160
00161 if(!d) return ret;
00162 oldsize = d->size;
00163
00164 if(oldsize >= d->capacity)
00165 if(dict_expand_capacity(d) <= oldsize)
00166 return NULL;
00167
00168 d->key[oldsize] = key;
00169 d->value[oldsize] = value;
00170 d->size++;
00171 return value;
00172 }
00173
00178 void *dict_remove(DICTIONARY *d, void *key) {
00179 void *ret = NULL;
00180 int index, i, n;
00181
00182 if(!d) return ret;
00183 index = dict_index_for_key(d, key);
00184 if(index >= 0) {
00185
00186 ret = d->value[index];
00187
00188 if (d->keyfree)
00189 d->keyfree(d->key[index]);
00190
00191
00192 for(i=index+1, n=d->size; i<n; i++) {
00193 d->key[i-1] = d->key[i];
00194 d->value[i-1] = d->value[i];
00195 }
00196 d->size--;
00197 }
00198 CHECK_LEAKS();
00199 return ret;
00200 }
00201
00210 void *dict_remove_specific(DICTIONARY *d, void *key, void *value) {
00211 void *ret = NULL;
00212 int index = -1, i, n;
00213
00214 if(!d) return ret;
00215 for(i=0, n=d->size; i<n; i++) {
00216 if((d->compar(key, d->key[i]) == 1) &&
00217 (d->compar(value, d->value[i]) == 1)) {
00218
00219
00220 index = i;
00221 ret = d->value[index];
00222
00223
00224 if (d->keyfree)
00225 d->keyfree(d->key[index]);
00226 break;
00227 }
00228 }
00229 if(index >= 0) {
00230
00231 for(i=index+1, n=d->size; i<n; i++) {
00232 d->key[i-1] = d->key[i];
00233 d->value[i-1] = d->value[i];
00234 }
00235 d->size--;
00236 }
00237 return ret;
00238 }
00239
00247 void **dict_remove_all(DICTIONARY *d, void *key, int *num_removed) {
00248 int index, i, n, num_found = 0;
00249 void **_values = NULL;
00250
00251 if(!d) {
00252 if (num_removed) {
00253 *num_removed = num_found;
00254 }
00255 return _values;
00256 }
00257
00258 index = dict_index_for_key(d, key);
00259 while(index >= 0) {
00260 num_found++;
00261
00262
00263 _values = (void *)realloc(_values, sizeof(void*) * num_found);
00264 _values[num_found-1] = d->value[index];
00265
00266
00267 d->keyfree(d->key[index]);
00268
00269
00270 for(i=index+1, n=d->size; i<n; i++) {
00271 d->key[i-1] = d->key[i];
00272 d->value[i-1] = d->value[i];
00273 }
00274 d->size--;
00275 index = dict_index_for_key(d, key);
00276 }
00277 if (num_removed)
00278 *num_removed = num_found;
00279 return _values;
00280 }
00281
00285 void dict_free(DICTIONARY *d) {
00286 if(!d) return;
00287 free(d->key);
00288 free(d->value);
00289 free(d);
00290 }
00291