aboutsummaryrefslogtreecommitdiff
path: root/src/imap.c
blob: d1ed619585a1284b1975aef636f80e1a95cb2cf7 (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "imap.h"
#include "util_rt.h"

#include <stdlib.h>
#include <string.h>


static int imap_cmp_func (const void *in_a, const void *in_b) {
	const prne_imap_tuple_t *a = (const prne_imap_tuple_t*)in_a;
	const prne_imap_tuple_t *b = (const prne_imap_tuple_t*)in_b;

	return
		a->key < b->key ? -1 :
		a->key > 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) {
		return;
	}

	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);
}