/[LeafOK_CVS]/pvpgn-1.7.4/src/tinycdb/cdb_seek.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/tinycdb/cdb_seek.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
no message

1 /* old interface for reading cdb file
2 *
3 * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
4 * Public domain.
5 */
6
7 #include "common/setup_before.h"
8 #include <stdio.h>
9 #include "cdb_int.h"
10 #include "common/setup_after.h"
11
12 #ifndef SEEK_SET
13 # define SEEK_SET 0
14 #endif
15
16 /* read a chunk from file, ignoring interrupts (EINTR) */
17
18 int
19 cdb_bread(FILE *fd, void *buf, int len)
20 {
21 int l;
22 while(len > 0) {
23 do l = fread(buf, 1, len, fd);
24 while(l < 0 && errno == EINTR);
25 if (l <= 0) {
26 if (!l)
27 errno = EIO;
28 return -1;
29 }
30 buf = (char*)buf + l;
31 len -= l;
32 }
33 return 0;
34 }
35
36 /* find a given key in cdb file, seek a file pointer to it's value and
37 place data length to *dlenp. */
38
39 int
40 cdb_seek(FILE *fd, const void *key, unsigned klen, unsigned *dlenp)
41 {
42 unsigned htstart; /* hash table start position */
43 unsigned htsize; /* number of elements in a hash table */
44 unsigned httodo; /* hash table elements left to look */
45 unsigned hti; /* hash table index */
46 unsigned pos; /* position in a file */
47 unsigned hval; /* key's hash value */
48 unsigned char rbuf[64]; /* read buffer */
49 int needseek = 1; /* if we should seek to a hash slot */
50
51 hval = cdb_hash(key, klen);
52 pos = (hval & 0xff) << 3; /* position in TOC */
53 /* read the hash table parameters */
54 if (fseek(fd, pos, SEEK_SET) || cdb_bread(fd, rbuf, 8) < 0)
55 return -1;
56 if ((htsize = cdb_unpack(rbuf + 4)) == 0)
57 return 0;
58 hti = (hval >> 8) % htsize; /* start position in hash table */
59 httodo = htsize;
60 htstart = cdb_unpack(rbuf);
61
62 for(;;) {
63 if (needseek && fseek(fd, htstart + (hti << 3), SEEK_SET))
64 return -1;
65 if (cdb_bread(fd, rbuf, 8) < 0)
66 return -1;
67 if ((pos = cdb_unpack(rbuf + 4)) == 0) /* not found */
68 return 0;
69
70 if (cdb_unpack(rbuf) != hval) /* hash value not matched */
71 needseek = 0;
72 else { /* hash value matched */
73 if (fseek(fd, pos, SEEK_SET) || cdb_bread(fd, rbuf, 8) < 0)
74 return -1;
75 if (cdb_unpack(rbuf) == klen) { /* key length matches */
76 /* read the key from file and compare with wanted */
77 unsigned l = klen, c;
78 const char *k = (const char*)key;
79 if (*dlenp)
80 *dlenp = cdb_unpack(rbuf + 4); /* save value length */
81 for(;;) {
82 if (!l) /* the whole key read and matches, return */
83 return 1;
84 c = l > sizeof(rbuf) ? sizeof(rbuf) : l;
85 if (cdb_bread(fd, rbuf, c) < 0)
86 return -1;
87 if (memcmp(rbuf, k, c) != 0) /* no, it differs, stop here */
88 break;
89 k += c; l -= c;
90 }
91 }
92 needseek = 1; /* we're looked to other place, should seek back */
93 }
94 if (!--httodo)
95 return 0;
96 if (++hti == htsize) {
97 hti = 0;
98 needseek = 1;
99 }
100 }
101 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1