6static void free_hash_table(WORD * hash_table);
7static int cto_lower(
int c);
8static WORD * init_hash_table(
void);
9static void shuffle(WORD * table,
unsigned int);
10static unsigned int hashme(
cdict_ctx*,
char *);
11static int cstr_ccmp(
const char * str1,
const char * str2);
15static int cto_lower(
int c){
16 return c >=
'A' && c <=
'Z'? c +
'a' -
'A':c;
19static int cstr_ccmp(
const char * str1,
const char * str2){
20 char * s1 = (
char *) str1;
21 char * s2 = (
char *) str2;
22 while (*s1 !=
'\0' && *s2 !=
'\0' && cto_lower(*s1) == cto_lower(*s2)){
26 return cto_lower(*s1) - cto_lower(*s2);
41static WORD * init_hash_table(
void){
42 WORD * hash_table = (WORD *) malloc(TABLE_SIZE *
sizeof(WORD));
43 if (NULL == hash_table){
46 for (
unsigned long int i=0;i<TABLE_SIZE -1; i++)
48 shuffle(hash_table, TABLE_SIZE - 1);
59static void free_hash_table(WORD * hash_table){
60 if (NULL == hash_table)
71static void shuffle(WORD * table,
unsigned int n){
74 unsigned int i,j, tmp;
75 for (i = n-1; i> 0; i--){
110 if (copy_func == NULL){
113 WORD * hash_table = init_hash_table();
114 if (NULL == hash_table)
122 if (ctx->
table == NULL){
128 for (
unsigned long int i=0; i< TABLE_SIZE; i++){
134 ctx->
errmsg = (
char *) malloc(
sizeof(
char) * 0xFF);
146static unsigned int hashme(
cdict_ctx * ctx,
char * key){
148 ctx->
err = ERROR_NULL_VALUE_FOR_KEY;
149 strcpy(ctx->
errmsg,
"Key can not be NULL for a dictionary!");
152 unsigned long long int j;
154 unsigned int key_len = strlen(key);
155 for (
unsigned int i=0; i< key_len; ++i){
157 j = (j % (TABLE_SIZE)) & 0xFFFF;
174 ctx->
err = ERROR_NULL_VALUE_FOR_KEY;
175 strcpy(ctx->
errmsg,
"The key can not be null for a dictionary!");
178 WORD index = hashme(ctx, key);
179 if (ctx->
err != ERROR_OK)
188 if (tmp->
key == NULL)
190 if (strcmp(tmp->
key, key) == 0){
191 return (
void*)tmp->
value;
213 ctx->
err = ERROR_NULL_VALUE_FOR_KEY;
214 strcpy(ctx->
errmsg,
"The key can not be null for a dictionary!");
218 char * clone_key = strdup(key);
219 for (
int i=0; clone_key[i]; i++)
220 clone_key[i] = cto_lower(clone_key[i]);
222 WORD index = hashme(ctx, clone_key);
223 if (ctx->
err != ERROR_OK){
237 if (tmp->
key == NULL){
241 if (cstr_ccmp(tmp->
key, clone_key) == 0){
243 return (
void*)tmp->
value;
265 return ERROR_DICT_POINTER_IS_NULL;
267 ctx->
err = ERROR_NULL_VALUE_FOR_KEY;
268 strcpy(ctx->
errmsg,
"Key can not be NULL!");
269 return ERROR_NULL_VALUE_FOR_KEY;
272 char * clone_key = strdup(key);
275 for (
int i=0; clone_key[i]; i++)
276 clone_key[i] = cto_lower(clone_key[i]);
278 WORD hash_val = hashme(ctx, clone_key);
280 void * clone_val = ctx->
copy_func(value);
282 if (NULL == ctx->
table[hash_val].
key){
284 ctx->
table[hash_val].
key = clone_key;
291 while(tmp->
next != NULL){
292 if (strcmp(tmp->
key, clone_key) != 0){
299 if (strcmp(tmp->
key, clone_key) == 0){
300 if (tmp->
value != NULL)
304 tmp->
value = clone_val;
308 if (NULL == tmp->
next){
309 ctx->
err = CDICT_ERROR_CAN_NOT_ALLOCATE_MEMORY;
312 strcpy(ctx->
errmsg,
"Can not allocate memory for the new key-value pair!");
313 return CDICT_ERROR_CAN_NOT_ALLOCATE_MEMORY;
316 tmp->
key = clone_key;
317 tmp->
value = clone_val;
341 return ERROR_DICT_POINTER_IS_NULL;
343 ctx->
err = ERROR_NULL_VALUE_FOR_KEY;
344 strcpy(ctx->
errmsg,
"Key can not be NULL!");
345 return ERROR_NULL_VALUE_FOR_KEY;
348 WORD hash_val = hashme(ctx, key);
350 char * clone_key = strdup(key);
351 void * clone_val = ctx->
copy_func(value);
353 if (NULL == ctx->
table[hash_val].
key){
355 ctx->
table[hash_val].
key = clone_key;
362 while(tmp->
next != NULL){
363 if (strcmp(tmp->
key, clone_key) != 0){
370 if (strcmp(tmp->
key, clone_key) == 0){
371 if (tmp->
value != NULL)
375 tmp->
value = clone_val;
379 if (NULL == tmp->
next){
380 ctx->
err = CDICT_ERROR_CAN_NOT_ALLOCATE_MEMORY;
383 strcpy(ctx->
errmsg,
"Can not allocate memory for the new key-value pair!");
384 return CDICT_ERROR_CAN_NOT_ALLOCATE_MEMORY;
387 tmp->
key = clone_key;
388 tmp->
value = clone_val;
411 if (ctx->
table != NULL){
412 for (
unsigned int i=0; i< TABLE_SIZE; i++){
443 ctx->
err = ERROR_NULL_VALUE_FOR_KEY;
444 strcpy(ctx->
errmsg,
"The key can not be null for a dictionary");
447 WORD index = hashme(ctx, key);
448 if (ctx->
err != ERROR_OK)
454 if (tmp->
key == NULL)
456 if (strcmp(tmp->
key, key) == 0){
477 ctx->
err = ERROR_NULL_VALUE_FOR_KEY;
478 strcpy(ctx->
errmsg,
"The key can not be null for a dictionary");
481 WORD index = hashme(ctx, key);
482 if (ctx->
err != ERROR_OK)
488 if (tmp->
key == NULL)
490 if (cstr_ccmp(tmp->
key, key) == 0){
511 for (
unsigned int i=0; i< klst->len; ++i)
534 unsigned long int cnt = 0;
536 for (
unsigned long int i=0; i< TABLE_SIZE; i++){
540 while(tmp && tmp->
key){
548 ctx->
err = CDICT_ERROR_CAN_NOT_ALLOCATE_MEMORY;
549 strcpy(ctx->
errmsg,
"Can not allocate memory for keys");
556 klst->lst = (
char**) malloc (cnt *
sizeof(
char*));
557 if (NULL == klst->lst){
558 ctx->
err = CDICT_ERROR_CAN_NOT_ALLOCATE_MEMORY;
559 strcpy(ctx->
errmsg,
"Can not allocate memory for keys");
566 for (
unsigned long int i=0; i< TABLE_SIZE; ++i){
571 while (tmp && tmp->
key){
572 klst->lst[cnt] = clone_keys?strdup(tmp->
key):tmp->
key;
594 WORD index = hashme(ctx, key);
599 tmp = &(ctx->
table[index]);
600 if (strcmp(key, tmp->
key) == 0){
602 if (tmp->
next == NULL){
627 if (strcmp(tmp->
key, key) == 0){
634 if (tmp->
next == NULL){
void * cdict_get_nocase(cdict_ctx *ctx, char *key)
get a value from the dictionary by providing the key (case-insensitive key)
int cdict_has_key_nocase(cdict_ctx *ctx, char *key)
Checks if the key exists in the dictionary (case-insensitive comparison)
void cdict_free_keylist(cdict_keylist *klst, int clone_keys)
This function free the keylist structure returned by cdict_keys()
void cdict_free(cdict_ctx *ctx)
Frees the memory allocated for the dictionary.
int cdict_has_key(cdict_ctx *ctx, char *key)
Checks if the key exists in the dictionary.
int cdict_set_nocase(cdict_ctx *ctx, char *key, void *value)
Sets the new value for a given key (make key lower case first).
cdict_ctx * cdict_init(void(*free_func)(void *), void *(*copy_func)(void *))
Initializes the Dictionary in the memory.
void cdict_remove(cdict_ctx *ctx, char *key)
Removes a key-value pair from the dictionary.
int cdict_set(cdict_ctx *ctx, char *key, void *value)
Sets the new value for a given key.
void * cdict_get(cdict_ctx *ctx, char *key)
cdict_keylist * cdict_keys(cdict_ctx *ctx, int clone_keys)
Get the list of keys from the dictionary.
PNODE table
Pointer to an array of NODE structure.
int err
Possible Error code.
WORD * hash_table
Pointer to the hash table for hashing.
char * errmsg
Description of the possible error.
void *(* copy_func)(void *)
a pointer to the copy function provided by user
void(* free_func)(void *)
a pointer to the free function provided by user
char * key
key for finding matches. Key is a null-terminated string
void * value
Value to store. value is a pointer to void so it can be any type.
struct _NODE * next
A pointer points to the next node in case of collision.