fehQlibs 26
Qlibs
Loading...
Searching...
No Matches
cdbread.c
Go to the documentation of this file.
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <sys/mman.h>
4#include <unistd.h>
5#include "error.h"
6#include "seek.h"
7#include "byte.h"
8#include "cdbread.h"
9
17uint32 cdb_unpack(unsigned char *buf)
18{
19 uint32 num;
20 num = buf[3]; num <<= 8;
21 num += buf[2]; num <<= 8;
22 num += buf[1]; num <<= 8;
23 num += buf[0];
24 return num;
25}
26
27void cdb_free(struct cdb *c)
28{
29 if (c->map) {
30 munmap(c->map,c->size);
31 c->map = 0;
32 }
33}
34
35void cdb_findstart(struct cdb *c)
36{
37 c->loop = 0;
38}
39
40void cdb_init(struct cdb *c,int fd)
41{
42 struct stat st;
43 char *x;
44
45 cdb_free(c);
47 c->fd = fd;
48
49 if (fstat(fd,&st) == 0)
50 if (st.st_size <= 0xffffffff) {
51 x = mmap(0,st.st_size,PROT_READ,MAP_SHARED,fd,0);
52 if (x + 1) { // FIXME x + 1 means outside legal memory area; don't do it this way
53 c->size = st.st_size;
54 c->map = x;
55 }
56 }
57}
58
59int cdb_read(struct cdb *c,char *buf,unsigned int len,uint32 pos)
60{
61 if (c->map) {
62 if ((pos > c->size) || (c->size - pos < len)) goto FORMAT;
63 byte_copy(buf,len,c->map + pos);
64 }
65 else {
66 if (seek_set(c->fd,pos) == -1) return -1;
67 while (len > 0) {
68 int r;
69 do
70 r = read(c->fd,buf,len);
71 while ((r == -1) && (errno == EINTR));
72 if (r == -1) return -1;
73 if (r == 0) goto FORMAT;
74 buf += r;
75 len -= r;
76 }
77 }
78 return 0;
79
80 FORMAT:
81 errno = EPROTO;
82 return -1;
83}
84
85static int match(struct cdb *c,char *key,unsigned int len,uint32 pos)
86{
87 char buf[32];
88 int n;
89
90 while (len > 0) {
91 n = sizeof(buf);
92 if (n > len) n = len;
93 if (cdb_read(c,buf,n,pos) == -1) return -1;
94 if (byte_diff(buf,n,key)) return 0;
95 pos += n;
96 key += n;
97 len -= n;
98 }
99 return 1;
100}
101
102int cdb_findnext(struct cdb *c,char *key,unsigned int len)
103{
104 char buf[8];
105 uint32 pos;
106 uint32 u;
107
108 if (!c->loop) {
109 u = cdb_hash(key,len);
110 if (cdb_read(c,buf,8,(u << 3) & 2047) == -1) return -1;
111 uint32_unpack(buf + 4,&c->hslots);
112 if (!c->hslots) return 0;
113 uint32_unpack(buf,&c->hpos);
114 c->khash = u;
115 u >>= 8;
116 u %= c->hslots;
117 u <<= 3;
118 c->kpos = c->hpos + u;
119 }
120
121 while (c->loop < c->hslots) {
122 if (cdb_read(c,buf,8,c->kpos) == -1) return -1;
123 uint32_unpack(buf + 4,&pos);
124 if (!pos) return 0;
125 c->loop += 1;
126 c->kpos += 8;
127 if (c->kpos == c->hpos + (c->hslots << 3)) c->kpos = c->hpos;
128 uint32_unpack(buf,&u);
129 if (u == c->khash) {
130 if (cdb_read(c,buf,8,pos) == -1) return -1;
131 uint32_unpack(buf,&u);
132 if (u == len)
133 switch(match(c,key,len,pos + 8)) {
134 case -1:
135 return -1;
136 case 1:
137 uint32_unpack(buf + 4,&c->dlen);
138 c->dpos = pos + 8 + len;
139 return 1;
140 }
141 }
142 }
143
144 return 0;
145}
146
147int cdb_find(struct cdb *c,char *key,unsigned int len)
148{
149 cdb_findstart(c);
150 return cdb_findnext(c,key,len);
151}
152
153uint32 cdb_hashadd(uint32 h,unsigned char c)
154{
155 h += (h << 5);
156 return h ^ c;
157}
158
159uint32 cdb_hash(char *buf,unsigned int len)
160{
161 uint32 h;
162
163 h = CDB_HASHSTART;
164 while (len) {
165 h = cdb_hashadd(h,*buf++);
166 --len;
167 }
168 return h;
169}
int read(int _str, void *_buf, int _b)
void cdb_init(struct cdb *c, int fd)
Definition: cdbread.c:40
uint32 cdb_unpack(unsigned char *buf)
Definition: cdbread.c:17
int cdb_findnext(struct cdb *c, char *key, unsigned int len)
Definition: cdbread.c:102
void cdb_free(struct cdb *c)
Definition: cdbread.c:27
uint32 cdb_hashadd(uint32 h, unsigned char c)
Definition: cdbread.c:153
int cdb_read(struct cdb *c, char *buf, unsigned int len, uint32 pos)
Definition: cdbread.c:59
int cdb_find(struct cdb *c, char *key, unsigned int len)
Definition: cdbread.c:147
void cdb_findstart(struct cdb *c)
Definition: cdbread.c:35
uint32 cdb_hash(char *buf, unsigned int len)
Definition: cdbread.c:159
#define EPROTO
Definition: error.h:7
#define CDB_HASHSTART
Definition: cdbread.h:8
void uint32_unpack(char *, uint32 *)
uint32_t uint32
Definition: uint_t.h:40
int seek_set(int, seek_pos)
Definition: seek.c:31
int byte_diff(const void *, unsigned int, const void *)
Definition: byte.c:40
void byte_copy(void *, unsigned int, const void *)
Definition: byte.c:20
Definition: cdbread.h:13
uint32 size
Definition: cdbread.h:16
uint32 hslots
Definition: cdbread.h:21
uint32 hpos
Definition: cdbread.h:20
uint32 khash
Definition: cdbread.h:18
int fd
Definition: cdbread.h:15
char * map
Definition: cdbread.h:14
uint32 dpos
Definition: cdbread.h:22
uint32 loop
Definition: cdbread.h:17
uint32 dlen
Definition: cdbread.h:23
uint32 kpos
Definition: cdbread.h:19