|
1 #include "readwrite.h" |
|
2 #include "seek.h" |
|
3 #include "alloc.h" |
|
4 #include "cdbmss.h" |
|
5 |
|
6 int cdbmss_start(c,fd) |
|
7 struct cdbmss *c; |
|
8 int fd; |
|
9 { |
|
10 cdbmake_init(&c->cdbm); |
|
11 c->fd = fd; |
|
12 c->pos = sizeof(c->cdbm.final); |
|
13 substdio_fdbuf(&c->ss,write,fd,c->ssbuf,sizeof(c->ssbuf)); |
|
14 return seek_set(fd,(seek_pos) c->pos); |
|
15 } |
|
16 |
|
17 int cdbmss_add(c,key,keylen,data,datalen) |
|
18 struct cdbmss *c; |
|
19 unsigned char *key; |
|
20 unsigned int keylen; |
|
21 unsigned char *data; |
|
22 unsigned int datalen; |
|
23 { |
|
24 uint32 h; |
|
25 int i; |
|
26 |
|
27 cdbmake_pack(c->packbuf,(uint32) keylen); |
|
28 cdbmake_pack(c->packbuf + 4,(uint32) datalen); |
|
29 if (substdio_put(&c->ss,c->packbuf,8) == -1) return -1; |
|
30 if (substdio_put(&c->ss,key,keylen) == -1) return -1; |
|
31 if (substdio_put(&c->ss,data,datalen) == -1) return -1; |
|
32 |
|
33 h = CDBMAKE_HASHSTART; |
|
34 for (i = 0;i < keylen;++i) |
|
35 h = cdbmake_hashadd(h,(unsigned int) key[i]); |
|
36 |
|
37 if (!cdbmake_add(&c->cdbm,h,c->pos,alloc)) return -1; |
|
38 |
|
39 c->pos += 8 + keylen + datalen; /* XXX: overflow? */ |
|
40 return 0; |
|
41 } |
|
42 |
|
43 int cdbmss_finish(c) |
|
44 struct cdbmss *c; |
|
45 { |
|
46 int i; |
|
47 uint32 len; |
|
48 uint32 u; |
|
49 |
|
50 if (!cdbmake_split(&c->cdbm,alloc)) return -1; |
|
51 |
|
52 for (i = 0;i < 256;++i) { |
|
53 len = cdbmake_throw(&c->cdbm,c->pos,i); |
|
54 for (u = 0;u < len;++u) { |
|
55 cdbmake_pack(c->packbuf,c->cdbm.hash[u].h); |
|
56 cdbmake_pack(c->packbuf + 4,c->cdbm.hash[u].p); |
|
57 if (substdio_put(&c->ss,c->packbuf,8) == -1) return -1; |
|
58 c->pos += 8; /* XXX: overflow? */ |
|
59 } |
|
60 } |
|
61 |
|
62 if (substdio_flush(&c->ss) == -1) return -1; |
|
63 if (seek_begin(c->fd) == -1) return -1; |
|
64 return substdio_putflush(&c->ss,c->cdbm.final,sizeof(c->cdbm.final)); |
|
65 } |