aboutsummaryrefslogtreecommitdiff
path: root/src/imap.c
blob: b6d2110cfeb1c758d3a6bc304ceee11214f1ab8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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, const prne_imap_val_type_t 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 = 0;

	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 = 0;

	return (const prne_imap_tuple_t*)bsearch(&t, im->tbl, im->size, sizeof(prne_imap_tuple_t), imap_cmp_func);
}