path:
/account.c
2.01 KB | 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
#include <account.h>
#include <stdlib.h>
// TODO make this dynamic
size_t tree_depth = 4;
map_tree_t *account_search(map_tree_t *rootp, char *acc, size_t acc_size)
{
assert(rootp != NULL);
// we hit leaf node, return rootp
if (rootp->children == NULL) return rootp;
// return rootp when the 'acc' matches exactly with rootp->value
// acc: this, rootp->value: this
vstr_t *rk = rootp->value;
if (rk != NULL && acc_size == rk->len && (strncmp(acc, rk->str, acc_size) == 0)) {
return rootp;
}
// search the string in it's children
for (size_t i = 0; i < rootp->children_len; i++) {
vstr_t *val = rootp->children[i].value;
if (val != NULL && acc_size == val->len && (strncmp(acc, val->str, acc_size) == 0)) {
return rootp->children + i;
}
}
return NULL;
}
int account_add(map_tree_t **rootp, char *acc, size_t acc_size)
{
size_t records_needed = tree_depth * 4;
if (*rootp == NULL) {
*rootp = malloc(sizeof(map_tree_t));
}
if ((*rootp)->children == NULL) {
(*rootp)->children =
(map_tree_t *) calloc(records_needed, sizeof(map_tree_t));
(*rootp)->children_len = 0;
(*rootp)->children_cap = records_needed;
}
map_tree_t* _rootp = *rootp;
size_t i = 0;
while (i < acc_size) {
if (acc[i] == ':' || i + 1 == acc_size) {
size_t j = i + 1;
map_tree_t *current_node = account_search(_rootp, acc, j);
if (current_node == NULL) {
// return the previously allocated child
current_node = _rootp->children + _rootp->children_len++;
// current_node->value is NULL when the search fails
// we have to set the value now
// TODO maybe save vstrs in a pool and use them, would provide a sane way to free memory
vstr_t *vstr = (vstr_t *) malloc(sizeof(vstr_t));
vstr->str = acc;
vstr->len = j;
current_node->value = vstr;
//printf("%zu : %zu %d %.*s\n", current_node, vstr, j, j, acc);
} else {
//printf("Present already= %d %.*s\n", j, j, acc);
}
if (j != acc_size) {
return account_add(¤t_node, acc + j,
acc_size - j);
}
}
i++;
}
return -1;
}