aboutsummaryrefslogtreecommitdiff
path: root/src/imap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/imap.c')
-rw-r--r--src/imap.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/imap.c b/src/imap.c
new file mode 100644
index 0000000..88e24e9
--- /dev/null
+++ b/src/imap.c
@@ -0,0 +1,96 @@
+#include "imap.h"
+#include "util_rt.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+static int imap_cmp_func (const void *a, const void *b) {
+ return
+ ((const prne_imap_tuple_t*)a)->key < ((const prne_imap_tuple_t*)b)->key ? -1 :
+ ((const prne_imap_tuple_t*)a)->key > ((const prne_imap_tuple_t*)b)->key ? 1 :
+ 0;
+}
+
+
+void prne_init_imap (prne_imap_t *im) {
+ im->tbl = NULL;
+ im->size = 0;
+}
+
+void prne_free_imap (prne_imap_t *im) {
+ prne_free(im->tbl);
+ im->tbl = NULL;
+ im->size = 0;
+}
+
+void prne_imap_clear (prne_imap_t *im) {
+ prne_free(im->tbl);
+ im->tbl = NULL;
+ im->size = 0;
+}
+
+const prne_imap_tuple_t *prne_imap_insert (prne_imap_t *im, const prne_imap_key_type_t key, void *val) {
+ prne_imap_tuple_t *ret;
+ prne_imap_tuple_t t;
+
+ t.key = key;
+ t.val = val;
+
+ ret = (prne_imap_tuple_t*)bsearch(&t, im->tbl, im->size, sizeof(prne_imap_tuple_t), imap_cmp_func);
+ if (ret == NULL) {
+ void *ny_mem;
+
+ ny_mem = prne_realloc(im->tbl, sizeof(prne_imap_tuple_t), im->size + 1);
+ if (ny_mem == NULL) {
+ return NULL;
+ }
+ im->tbl = (prne_imap_tuple_t*)ny_mem;
+ im->tbl[im->size] = t;
+ im->size += 1;
+
+ qsort(im->tbl, im->size, sizeof(prne_imap_tuple_t), imap_cmp_func);
+ ret = (prne_imap_tuple_t*)prne_imap_lookup(im, key);
+ }
+ else {
+ ret->val = t.val;
+ }
+
+ return ret;
+}
+
+void prne_imap_erase (prne_imap_t *im, const prne_imap_key_type_t key) {
+ prne_imap_tuple_t *ext;
+ prne_imap_tuple_t t;
+
+ t.key = key;
+ t.val = NULL;
+
+ ext = bsearch(&t, im->tbl, im->size, sizeof(prne_imap_tuple_t), imap_cmp_func);
+ if (ext != NULL) {
+ if (im->size - 1 == 0) {
+ prne_free(im->tbl);
+ im->tbl = NULL;
+ im->size = 0;
+ }
+ else {
+ void *ny_mem;
+
+ memmove(ext, ext + 1, sizeof(prne_imap_tuple_t) * (im->size - 1 - (ext - im->tbl)));
+ im->size -= 1;
+ ny_mem = prne_realloc(im->tbl, sizeof(prne_imap_tuple_t), im->size);
+ if (ny_mem != NULL) {
+ im->tbl = (prne_imap_tuple_t*)ny_mem;
+ }
+ }
+ }
+}
+
+const prne_imap_tuple_t *prne_imap_lookup (prne_imap_t *im, const prne_imap_key_type_t key) {
+ prne_imap_tuple_t t;
+
+ t.key = key;
+ t.val = NULL;
+
+ return (const prne_imap_tuple_t*)bsearch(&t, im->tbl, im->size, sizeof(prne_imap_tuple_t), imap_cmp_func);
+}