Annotation of embedaddon/php/ext/dba/libcdb/cdb.c, revision 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>