You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
3.3 KiB
C
164 lines
3.3 KiB
C
#ifndef INCLUDED_LOOKUP_LIST_H
|
|
#define INCLUDED_LOOKUP_LIST_H
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
|
|
// Both key and value will be string
|
|
typedef struct LookupList{
|
|
char *key;
|
|
char *value;
|
|
struct LookupList *next;
|
|
} LookupList;
|
|
|
|
// return -1 on failure
|
|
int LookupList_add(LookupList **list ,char *key, char *value){
|
|
// Search in list for key and change value
|
|
LookupList *i = *list;
|
|
while(i != NULL){
|
|
if(strcmp(i->key, key) == 0 ){
|
|
i->value = value;
|
|
return 0;
|
|
}
|
|
i = i->next;
|
|
}
|
|
|
|
// Create new node if key not in list
|
|
LookupList *node = (LookupList *) malloc(sizeof(LookupList));
|
|
if(node == NULL) return -1;
|
|
|
|
node->key = key;
|
|
node->value = value;
|
|
node->next = *list;
|
|
*list = node;
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Does not try to free key and value strings
|
|
void LookupList_remove(LookupList **list, char *key){
|
|
LookupList *a = *list;
|
|
if(a == NULL) return;
|
|
if(strcmp(key, a->key) == 0){
|
|
*list = (*list)->next;
|
|
free(a);
|
|
return;
|
|
}
|
|
|
|
LookupList *b = a->next;
|
|
while(b != NULL){
|
|
if(strcmp(key, b->key) == 0){
|
|
a->next = b->next;
|
|
free(b);
|
|
return;
|
|
}
|
|
|
|
a = b;
|
|
b = b->next;
|
|
}
|
|
}
|
|
|
|
char *LookupList_get(LookupList *list, char *key, char *r){
|
|
while(list != NULL){
|
|
if(strcmp(list->key, key) == 0 )
|
|
return list->value;
|
|
list = list->next;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
void LookupList_print(LookupList *list){
|
|
printf("{ ");
|
|
while(list != NULL){
|
|
printf("\"%s\" : \"%s\" ,", list->key, list->value);
|
|
list = list->next;
|
|
}
|
|
printf("}\n");
|
|
}
|
|
|
|
// The binary will first have a uint32_t equal to the number of (key,value) pairs.
|
|
// Then we kill have char[] that are seperated using \0 in key1, value1, key2, value2, key3, value3 .... for all pairs.
|
|
void LookupList_store(LookupList *list, char *filename){
|
|
uint32_t n = 0;
|
|
LookupList *t = list;
|
|
while(t != NULL){
|
|
n += 1;
|
|
t = t->next;
|
|
}
|
|
|
|
t = list;
|
|
FILE *f = fopen(filename, "wb");
|
|
fwrite(&n, sizeof(uint32_t), 1, f);
|
|
for(int i = 0; i < n; i++){
|
|
size_t len_key = 0;
|
|
size_t len_value = 0;
|
|
|
|
while(t->key[len_key++] != '\0');
|
|
while(t->value[len_value++] != '\0');
|
|
|
|
fwrite(t->key, sizeof(char), len_key, f);
|
|
fwrite(t->value, sizeof(char), len_value, f);
|
|
t = t->next;
|
|
}
|
|
fclose(f);
|
|
}
|
|
|
|
void LookupList_load(LookupList **l, char *filename){
|
|
FILE *f = fopen(filename, "rb");
|
|
assert(f != NULL);
|
|
|
|
uint32_t n = 0;
|
|
fread(&n, sizeof(uint32_t), 1, f);
|
|
|
|
for(int i = 0; i < n; i++){
|
|
|
|
size_t key_capacity = 10;
|
|
char *key = (char *) malloc(sizeof(char) * key_capacity);
|
|
assert(key != NULL);
|
|
int j = 0;
|
|
|
|
|
|
while(1){
|
|
|
|
if((j+1) == key_capacity){
|
|
key_capacity *= 2;
|
|
key = (char *) realloc(key, sizeof(char) * key_capacity);
|
|
assert(key != NULL);
|
|
}
|
|
|
|
fread((key + j), sizeof(char), 1, f);
|
|
if (key[j] == '\0')
|
|
break;
|
|
|
|
j++;
|
|
}
|
|
|
|
size_t value_capacity = 10;
|
|
char *value = (char *) malloc(sizeof(char) * value_capacity);
|
|
assert(value != NULL);
|
|
j = 0;
|
|
|
|
while(1){
|
|
if((j+1) == value_capacity){
|
|
value_capacity *= 2;
|
|
value = (char *) realloc(value, sizeof(char) * value_capacity);
|
|
assert(value != NULL);
|
|
}
|
|
|
|
fread((value + j), sizeof(char), 1, f);
|
|
if (value[j] == '\0')
|
|
break;
|
|
j++;
|
|
}
|
|
|
|
LookupList_add(l, key, value);
|
|
}
|
|
|
|
fclose(f);
|
|
}
|
|
|
|
#endif
|