-
Notifications
You must be signed in to change notification settings - Fork 2
/
dictionary.c
121 lines (100 loc) · 2.2 KB
/
dictionary.c
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
#include "dictionary.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
dictionary create_dictionary(void *value){
dictionary output = (dictionary) {.value = value};
memset(output.next_chars, 0, sizeof(dictionary *)*8);
return output;
}
static void free_dictionary_recursive(dictionary *dict, void (*free_value)(void *)){
unsigned char i;
for(i = 0; i < 8; i++){
if(dict->next_chars[i]){
free_dictionary_recursive(dict->next_chars[i], free_value);
free(dict->next_chars[i]);
}
}
if(dict->value){
free_value(dict->value);
}
}
void free_dictionary(dictionary dict, void (*free_value)(void *)){
unsigned char i;
for(i = 0; i < 8; i++){
if(dict.next_chars[i]){
free_dictionary_recursive(dict.next_chars[i], free_value);
free(dict.next_chars[i]);
}
}
if(dict.value){
free_value(dict.value);
}
}
void *read_dictionary(dictionary dict, char *string, unsigned char offset){
unsigned char zeros = 0;
unsigned char c;
while(*string){
c = (*string)>>offset | (*(string + 1))<<(8 - offset);
zeros = 0;
if(!(c&15)){
zeros += 4;
c>>=4;
}
if(!(c&3)){
zeros += 2;
c>>=2;
}
if(!(c&1)){
zeros++;
}
offset += zeros + 1;
string += (offset&0x08)>>3;
offset = offset&0x07;
if(dict.next_chars[zeros]){
dict = *(dict.next_chars[zeros]);
} else {
return (void *) 0;
}
}
return dict.value;
}
void write_dictionary(dictionary *dict, char *string, void *value, unsigned char offset){
unsigned char zeros = 0;
unsigned char c;
while(*string){
c = (*string)>>offset | (*(string + 1))<<(8 - offset);
zeros = 0;
if(!(c&15)){
zeros += 4;
c>>=4;
}
if(!(c&3)){
zeros += 2;
c>>=2;
}
if(!(c&1)){
zeros++;
}
offset += zeros + 1;
string += (offset&0x08)>>3;
offset = offset&0x07;
if(!dict->next_chars[zeros]){
dict->next_chars[zeros] = malloc(sizeof(dictionary));
*(dict->next_chars[zeros]) = create_dictionary((void *) 0);
}
dict = dict->next_chars[zeros];
}
dict->value = value;
}
void iterate_dictionary(dictionary dict, void (*func)(void *)){
unsigned char i;
if(dict.value){
func(dict.value);
}
for(i = 0; i < 8; i++){
if(dict.next_chars[i]){
iterate_dictionary(*dict.next_chars[i], func);
}
}
}