123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /*
- +----------------------------------------------------------------------+
- | Copyright (c) The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | https://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Author: Marcus Boerger <helly@php.net> |
- +----------------------------------------------------------------------+
- */
- /* $Id$ */
- /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "php.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifndef PHP_WIN32
- #include <sys/mman.h>
- #endif
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include <string.h>
- #include <errno.h>
- #include "cdb.h"
- #ifndef EPROTO
- # define EPROTO -15 /* cdb 0.75's default for PROTOless systems */
- #endif
- /* {{{ cdb_match */
- static int cdb_match(struct cdb *c, char *key, unsigned int len, uint32 pos)
- {
- char buf[32];
- unsigned int n;
- while (len > 0) {
- n = sizeof(buf);
- if (n > len)
- n = len;
- if (cdb_read(c, buf, n, pos) == -1)
- return -1;
- if (memcmp(buf, key, n))
- return 0;
- pos += n;
- key += n;
- len -= n;
- }
- return 1;
- }
- /* }}} */
- /* {{{ cdb_hash */
- uint32 cdb_hash(char *buf, unsigned int len)
- {
- uint32 h;
- const unsigned char * b = (unsigned char *)buf;
- h = CDB_HASHSTART;
- while (len--) {
- h = ( h + (h << 5)) ^ (*b++);
- }
- return h;
- }
- /* }}} */
- /* {{{ cdb_free */
- void cdb_free(struct cdb *c)
- {
- }
- /* }}} */
- /* {{{ cdb_findstart */
- void cdb_findstart(struct cdb *c)
- {
- c->loop = 0;
- }
- /* }}} */
- /* {{{ cdb_init */
- void cdb_init(struct cdb *c, php_stream *fp)
- {
- cdb_free(c);
- cdb_findstart(c);
- c->fp = fp;
- }
- /* }}} */
- /* {{{ cdb_read */
- int cdb_read(struct cdb *c, char *buf, unsigned int len, uint32 pos)
- {
- if (php_stream_seek(c->fp, pos, SEEK_SET) == -1) {
- errno = EPROTO;
- return -1;
- }
- while (len > 0) {
- int r;
- do {
- r = php_stream_read(c->fp, buf, len);
- } while ((r == -1) && (errno == EINTR));
- if (r == -1)
- return -1;
- if (r == 0) {
- errno = EPROTO;
- return -1;
- }
- buf += r;
- len -= r;
- }
- return 0;
- }
- /* }}} */
- /* {{{ cdb_findnext */
- int cdb_findnext(struct cdb *c, char *key, unsigned int len)
- {
- char buf[8];
- uint32 pos;
- uint32 u;
- if (!c->loop) {
- u = cdb_hash(key, len);
- if (cdb_read(c, buf, 8, (u << 3) & 2047) == -1)
- return -1;
- uint32_unpack(buf + 4,&c->hslots);
- if (!c->hslots)
- return 0;
- uint32_unpack(buf, &c->hpos);
- c->khash = u;
- u >>= 8;
- u %= c->hslots;
- u <<= 3;
- c->kpos = c->hpos + u;
- }
- while (c->loop < c->hslots) {
- if (cdb_read(c, buf, 8, c->kpos) == -1)
- return -1;
- uint32_unpack(buf + 4, &pos);
- if (!pos)
- return 0;
- c->loop += 1;
- c->kpos += 8;
- if (c->kpos == c->hpos + (c->hslots << 3))
- c->kpos = c->hpos;
- uint32_unpack(buf, &u);
- if (u == c->khash) {
- if (cdb_read(c, buf, 8, pos) == -1)
- return -1;
- uint32_unpack(buf, &u);
- if (u == len)
- switch(cdb_match(c, key, len, pos + 8)) {
- case -1:
- return -1;
- case 1:
- uint32_unpack(buf + 4, &c->dlen);
- c->dpos = pos + 8 + len;
- return 1;
- }
- }
- }
- return 0;
- }
- /* }}} */
- /* {{{ cdb_find */
- int cdb_find(struct cdb *c, char *key, unsigned int len)
- {
- cdb_findstart(c);
- return cdb_findnext(c, key, len);
- }
- /* }}} */
- /* {{{ cdb_version */
- char *cdb_version()
- {
- return "0.75, $Id$";
- }
- /* }}} */
|