diff options
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/strmap.c | 131 | ||||
-rw-r--r-- | src/strmap.h | 31 |
3 files changed, 164 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index f2e68d6..6d037d1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -66,7 +66,8 @@ libproone_a_SOURCES =\ rnd.c\ rnd_well512.c\ recon.c\ - inet.c + inet.c\ + strmap.c proone: proone.bin dvault.bin cp -fa proone.bin proone diff --git a/src/strmap.c b/src/strmap.c new file mode 100644 index 0000000..81d19b5 --- /dev/null +++ b/src/strmap.c @@ -0,0 +1,131 @@ +#include "strmap.h" +#include "util_rt.h" + +#include <string.h> +#include <errno.h> + + +static int strmap_cmp_f (const void *a, const void *b) { + return strcmp( + ((const prne_strmap_tuple_t *)a)->key, + ((const prne_strmap_tuple_t *)b)->key); +} + +void prne_init_strmap (prne_strmap_t *map) { + prne_memzero(map, sizeof(prne_strmap_t)); +} + +void prne_free_strmap (prne_strmap_t *map) { + if (map == NULL) { + return; + } + prne_strmap_clear(map); +} + +void prne_strmap_clear (prne_strmap_t *map) { + for (size_t i = 0; i < map->size; i += 1) { + prne_free((void*)map->tbl[i].key); + } + prne_free(map->tbl); + + prne_memzero(map, sizeof(prne_strmap_t)); +} + +const prne_strmap_tuple_t *prne_strmap_insert ( + prne_strmap_t *map, + const char* key, + void *val) +{ + prne_strmap_tuple_t *ret; + prne_strmap_tuple_t t; + + t.key = key; + t.val = val; + ret = (prne_strmap_tuple_t*)bsearch( + &t, + map->tbl, + map->size, + sizeof(prne_strmap_tuple_t), + strmap_cmp_f); + if (ret == NULL) { + const size_t sl = strlen(key); + void *ny_tbl; + + t.key = prne_alloc_str(sl); + if (t.key == NULL) { + return NULL; + } + memcpy((void*)t.key, key, sl + 1); + ny_tbl = (prne_strmap_tuple_t*)prne_realloc( + map->tbl, + sizeof(prne_strmap_tuple_t), + map->size + 1); + if (ny_tbl == NULL) { + prne_free((void*)t.key); + return NULL; + } + map->tbl = (prne_strmap_tuple_t*)ny_tbl; + map->tbl[map->size] = t; + map->size += 1; + + qsort(map->tbl, map->size, sizeof(prne_strmap_tuple_t), strmap_cmp_f); + ret = (prne_strmap_tuple_t*)prne_strmap_lookup(map, key); + prne_dbgtrap(ret != NULL); + } + else { + ret->val = t.val; + } + + return ret; +} + +void prne_strmap_erase (prne_strmap_t *map, const char* key) { + prne_strmap_tuple_t t, *e; + + t.key = key; + t.val = NULL; + e = (prne_strmap_tuple_t*)bsearch( + &t, + map->tbl, + map->size, + sizeof(prne_strmap_tuple_t), + strmap_cmp_f); + if (e == NULL) { + return; + } + prne_free((void*)e->key); + e->key = NULL; + if (map->size == 1) { + prne_strmap_clear(map); + } + else { + void *ny; + + memmove( + e, + e + 1, + sizeof(prne_strmap_tuple_t) * (map->size - 1 - (e - map->tbl))); + map->size -= 1; + ny = prne_realloc(map->tbl, sizeof(prne_strmap_tuple_t), map->size); + if (ny != NULL) { + map->tbl = (prne_strmap_tuple_t*)ny; + } + } +} + +const prne_strmap_tuple_t *prne_strmap_lookup ( + prne_strmap_t *map, + const char* key) +{ + prne_strmap_tuple_t t; + + t.key = key; + t.val = NULL; + + return (const prne_strmap_tuple_t*)bsearch( + &t, + map->tbl, + map->size, + sizeof(prne_strmap_tuple_t), + strmap_cmp_f); +} diff --git a/src/strmap.h b/src/strmap.h new file mode 100644 index 0000000..126ebbc --- /dev/null +++ b/src/strmap.h @@ -0,0 +1,31 @@ +#pragma once +#include <stddef.h> +#include <stdbool.h> +#include <stdint.h> + + +typedef struct prne_strmap prne_strmap_t; +typedef struct prne_strmap_tuple prne_strmap_tuple_t; + +struct prne_strmap { + prne_strmap_tuple_t *tbl; + size_t size; +}; + +struct prne_strmap_tuple { + const char *key; + void *val; +}; + +void prne_init_strmap (prne_strmap_t *map); +void prne_free_strmap (prne_strmap_t *map); + +void prne_strmap_clear (prne_strmap_t *map); +const prne_strmap_tuple_t *prne_strmap_insert ( + prne_strmap_t *map, + const char* key, + void *val); +void prne_strmap_erase (prne_strmap_t *map, const char* key); +const prne_strmap_tuple_t *prne_strmap_lookup ( + prne_strmap_t *map, + const char* key); |