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>