Annotation of embedaddon/php/ext/dba/libcdb/cdb.c, revision 1.1.1.1
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1997-2010 The PHP Group |
6: +----------------------------------------------------------------------+
7: | This source file is subject to version 3.01 of the PHP license, |
8: | that is bundled with this package in the file LICENSE, and is |
9: | available through the world-wide-web at the following url: |
10: | http://www.php.net/license/3_01.txt |
11: | If you did not receive a copy of the PHP license and are unable to |
12: | obtain it through the world-wide-web, please send a note to |
13: | license@php.net so we can mail you a copy immediately. |
14: +----------------------------------------------------------------------+
15: | Author: Marcus Boerger <helly@php.net> |
16: +----------------------------------------------------------------------+
17: */
18:
19: /* $Id: cdb.c 293036 2010-01-03 09:23:27Z sebastian $ */
20:
21: /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/
22:
23: #ifdef HAVE_CONFIG_H
24: #include "config.h"
25: #endif
26:
27: #include "php.h"
28:
29: #include <sys/types.h>
30: #include <sys/stat.h>
31: #ifndef PHP_WIN32
32: #include <sys/mman.h>
33: #endif
34: #ifdef HAVE_UNISTD_H
35: #include <unistd.h>
36: #endif
37: #include <string.h>
38: #include <errno.h>
39: #include "cdb.h"
40:
41: #ifndef EPROTO
42: # define EPROTO -15 /* cdb 0.75's default for PROTOless systems */
43: #endif
44:
45: /* {{{ cdb_match */
46: static int cdb_match(struct cdb *c, char *key, unsigned int len, uint32 pos TSRMLS_DC)
47: {
48: char buf[32];
49: unsigned int n;
50:
51: while (len > 0) {
52: n = sizeof(buf);
53: if (n > len)
54: n = len;
55: if (cdb_read(c, buf, n, pos TSRMLS_CC) == -1)
56: return -1;
57: if (memcmp(buf, key, n))
58: return 0;
59: pos += n;
60: key += n;
61: len -= n;
62: }
63: return 1;
64: }
65: /* }}} */
66:
67: /* {{{ cdb_hash */
68: uint32 cdb_hash(char *buf, unsigned int len)
69: {
70: uint32 h;
71: const unsigned char * b = (unsigned char *)buf;
72:
73: h = CDB_HASHSTART;
74: while (len--) {
75: h = ( h + (h << 5)) ^ (*b++);
76: }
77: return h;
78: }
79: /* }}} */
80:
81: /* {{{ cdb_free */
82: void cdb_free(struct cdb *c TSRMLS_DC)
83: {
84: }
85: /* }}} */
86:
87: /* {{{ cdb_findstart */
88: void cdb_findstart(struct cdb *c TSRMLS_DC)
89: {
90: c->loop = 0;
91: }
92: /* }}} */
93:
94: /* {{{ cdb_init */
95: void cdb_init(struct cdb *c, php_stream *fp TSRMLS_DC)
96: {
97: cdb_free(c TSRMLS_CC);
98: cdb_findstart(c TSRMLS_CC);
99: c->fp = fp;
100: }
101: /* }}} */
102:
103: /* {{{ cdb_read */
104: int cdb_read(struct cdb *c, char *buf, unsigned int len, uint32 pos TSRMLS_DC)
105: {
106: if (php_stream_seek(c->fp, pos, SEEK_SET) == -1) {
107: errno = EPROTO;
108: return -1;
109: }
110: while (len > 0) {
111: int r;
112: do {
113: r = php_stream_read(c->fp, buf, len);
114: } while ((r == -1) && (errno == EINTR));
115: if (r == -1)
116: return -1;
117: if (r == 0) {
118: errno = EPROTO;
119: return -1;
120: }
121: buf += r;
122: len -= r;
123: }
124: return 0;
125: }
126: /* }}} */
127:
128: /* {{{ cdb_findnext */
129: int cdb_findnext(struct cdb *c, char *key, unsigned int len TSRMLS_DC)
130: {
131: char buf[8];
132: uint32 pos;
133: uint32 u;
134:
135: if (!c->loop) {
136: u = cdb_hash(key, len);
137: if (cdb_read(c, buf, 8, (u << 3) & 2047 TSRMLS_CC) == -1)
138: return -1;
139: uint32_unpack(buf + 4,&c->hslots);
140: if (!c->hslots)
141: return 0;
142: uint32_unpack(buf, &c->hpos);
143: c->khash = u;
144: u >>= 8;
145: u %= c->hslots;
146: u <<= 3;
147: c->kpos = c->hpos + u;
148: }
149:
150: while (c->loop < c->hslots) {
151: if (cdb_read(c, buf, 8, c->kpos TSRMLS_CC) == -1)
152: return -1;
153: uint32_unpack(buf + 4, &pos);
154: if (!pos)
155: return 0;
156: c->loop += 1;
157: c->kpos += 8;
158: if (c->kpos == c->hpos + (c->hslots << 3))
159: c->kpos = c->hpos;
160: uint32_unpack(buf, &u);
161: if (u == c->khash) {
162: if (cdb_read(c, buf, 8, pos TSRMLS_CC) == -1)
163: return -1;
164: uint32_unpack(buf, &u);
165: if (u == len)
166: switch(cdb_match(c, key, len, pos + 8 TSRMLS_CC)) {
167: case -1:
168: return -1;
169: case 1:
170: uint32_unpack(buf + 4, &c->dlen);
171: c->dpos = pos + 8 + len;
172: return 1;
173: }
174: }
175: }
176:
177: return 0;
178: }
179: /* }}} */
180:
181: /* {{{ cdb_find */
182: int cdb_find(struct cdb *c, char *key, unsigned int len TSRMLS_DC)
183: {
184: cdb_findstart(c TSRMLS_CC);
185: return cdb_findnext(c, key, len TSRMLS_CC);
186: }
187: /* }}} */
188:
189: /* {{{ cdb_version */
190: char *cdb_version()
191: {
192: return "0.75, $Revision: 293036 $";
193: }
194: /* }}} */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>