forked from letsencrypt/go-safe-browsing-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhattrie.go
121 lines (100 loc) · 2.16 KB
/
hattrie.go
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
package safebrowsing
/*
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hat-trie.h"
hattrie_t* start() {
hattrie_t* trie;
trie = hattrie_create();
return trie;
}
void set(hattrie_t* h, char* key, size_t len) {
value_t* val;
val = hattrie_get(h, key, len);
*val = 1;
}
int get(hattrie_t* h, char* key, size_t len) {
value_t* val;
val = hattrie_tryget(h, key, len);
if (val != 0) {
return *val;
}
return 0;
}
void delete(hattrie_t* h, char* key, size_t len) {
value_t* val;
val = hattrie_tryget(h, key, len);
if (val != 0) {
*val = 0;
}
}
char* hattrie_iter_key_string(hattrie_iter_t* i, size_t* len) {
const char* in_key;
char* out_key;
in_key = hattrie_iter_key(i, len);
out_key = malloc((*len) * sizeof(char));
memcpy(out_key, in_key, *len);
return out_key;
}
*/
import "C"
import (
"runtime"
"unsafe"
)
type HatTrie struct {
trie *C.hattrie_t
}
func finalizeHatTrie(c *HatTrie) {
C.hattrie_free(c.trie)
}
func NewTrie() *HatTrie {
trie := C.start()
out := &HatTrie{
trie: trie,
}
runtime.SetFinalizer(out, finalizeHatTrie)
return out
}
func (h *HatTrie) Delete(key string) {
ckey := C.CString(key)
defer C.free(unsafe.Pointer(ckey))
C.delete(h.trie, ckey, C.size_t(len(key)))
}
func (h *HatTrie) Set(key string) {
ckey := C.CString(key)
defer C.free(unsafe.Pointer(ckey))
C.set(h.trie, ckey, C.size_t(len(key)))
}
func (h *HatTrie) Get(key string) bool {
ckey := C.CString(key)
defer C.free(unsafe.Pointer(ckey))
val := C.get(h.trie, ckey, C.size_t(len(key)))
return val == 1
}
type HatTrieIterator struct {
iterator *C.hattrie_iter_t
}
func finalizeHatTrieIterator(i *HatTrieIterator) {
C.hattrie_iter_free(i.iterator)
}
func (h *HatTrie) Iterator() *HatTrieIterator {
out := C.hattrie_iter_begin(h.trie, true)
hi := &HatTrieIterator{
iterator: out,
}
runtime.SetFinalizer(hi, finalizeHatTrieIterator)
return hi
}
func (i *HatTrieIterator) Next() string {
if C.hattrie_iter_finished(i.iterator) {
return ""
}
keylen := C.size_t(0)
ckey := C.hattrie_iter_key_string(i.iterator, &keylen)
defer C.free(unsafe.Pointer(ckey))
key := C.GoStringN(ckey, C.int(keylen))
C.hattrie_iter_next(i.iterator)
return key
}