Annotation of embedaddon/php/ext/dba/dba_cdb.c, revision 1.1

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2012 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:    | Authors: Sascha Schumann <sascha@schumann.cx>                        |
        !            16:    |          Marcus Boerger <helly@php.net>                              |
        !            17:    +----------------------------------------------------------------------+
        !            18:  */
        !            19: 
        !            20: /* $Id: dba_cdb.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            21: 
        !            22: #ifdef HAVE_CONFIG_H
        !            23: #include "config.h"
        !            24: #endif
        !            25: 
        !            26: #include "php.h"
        !            27: 
        !            28: #if DBA_CDB
        !            29: #include "php_cdb.h"
        !            30: 
        !            31: #include <sys/types.h>
        !            32: #ifdef HAVE_UNISTD_H
        !            33: #include <unistd.h>
        !            34: #endif
        !            35: #include <fcntl.h>
        !            36: 
        !            37: #if DBA_CDB_BUILTIN
        !            38: # include "libcdb/cdb.h"
        !            39: # include "libcdb/cdb_make.h"
        !            40: # include "libcdb/uint32.h"
        !            41: #else
        !            42: # ifdef CDB_INCLUDE_FILE
        !            43: #  include CDB_INCLUDE_FILE
        !            44: # endif
        !            45: #endif
        !            46: 
        !            47: #define CDB_INFO \
        !            48:        dba_cdb *cdb = (dba_cdb *) info->dbf
        !            49: 
        !            50: typedef struct {
        !            51:        struct cdb c;
        !            52: #if DBA_CDB_BUILTIN
        !            53:        struct cdb_make m;
        !            54:        php_stream *file;
        !            55:        int make;
        !            56: #else
        !            57:        int file;
        !            58: #endif
        !            59:        uint32 eod; /* size of constant database */
        !            60:        uint32 pos; /* current position for traversing */
        !            61: } dba_cdb;
        !            62: 
        !            63: DBA_OPEN_FUNC(cdb)
        !            64: {
        !            65: #if DBA_CDB_BUILTIN
        !            66:        php_stream* file = 0;
        !            67:        int make;
        !            68: #else
        !            69:        int file = 0;
        !            70: #endif
        !            71:        dba_cdb *cdb;
        !            72:        dba_info *pinfo = (dba_info *) info;
        !            73: 
        !            74:        switch (info->mode) {
        !            75:                case DBA_READER: 
        !            76: #if DBA_CDB_BUILTIN
        !            77:                        make = 0;
        !            78:                        file = info->fp;
        !            79: #else
        !            80:                        file = VCWD_OPEN(info->path, O_RDONLY);
        !            81:                        if (file < 0) {
        !            82:                                *error = "Unable to open file";
        !            83:                                return FAILURE;
        !            84:                        }
        !            85: #endif
        !            86:                        break;
        !            87: #if DBA_CDB_BUILTIN
        !            88:                case DBA_TRUNC:
        !            89:                        make = 1;
        !            90:                        file = info->fp;
        !            91:                        break;
        !            92:                case DBA_CREAT:
        !            93:                case DBA_WRITER:
        !            94:                        *error = "Update operations are not supported";
        !            95:                        return FAILURE; /* not supported */
        !            96: #endif
        !            97:                default: 
        !            98:                        *error = "Currently not supported";
        !            99:                        return FAILURE;
        !           100:        }
        !           101: 
        !           102:        cdb = pemalloc(sizeof(dba_cdb), info->flags&DBA_PERSISTENT);
        !           103:        memset(cdb, 0, sizeof(dba_cdb));
        !           104: 
        !           105: #if DBA_CDB_BUILTIN
        !           106:        if (make) {
        !           107:                cdb_make_start(&cdb->m, file TSRMLS_CC);
        !           108:        } else {
        !           109:                cdb_init(&cdb->c, file TSRMLS_CC);
        !           110:        }
        !           111:        cdb->make = make;
        !           112: #else
        !           113:        cdb_init(&cdb->c, file);
        !           114: #endif
        !           115:        cdb->file = file;
        !           116:        
        !           117:        pinfo->dbf = cdb;
        !           118:        return SUCCESS;
        !           119: }
        !           120: 
        !           121: DBA_CLOSE_FUNC(cdb)
        !           122: {
        !           123:        CDB_INFO;
        !           124: 
        !           125:        /* cdb_free does not close associated file */
        !           126: #if DBA_CDB_BUILTIN
        !           127:        if (cdb->make) {
        !           128:                cdb_make_finish(&cdb->m TSRMLS_CC);
        !           129:        } else {
        !           130:                cdb_free(&cdb->c TSRMLS_CC);
        !           131:        }
        !           132: #else
        !           133:        cdb_free(&cdb->c);
        !           134:        close(cdb->file);
        !           135: #endif
        !           136:        pefree(cdb, info->flags&DBA_PERSISTENT);
        !           137: }
        !           138: 
        !           139: #if DBA_CDB_BUILTIN
        !           140: # define php_cdb_read(cdb, buf, len, pos) cdb_read(cdb, buf, len, pos TSRMLS_CC)
        !           141: # define php_cdb_findnext(cdb, key, len) cdb_findnext(cdb, key, len TSRMLS_CC)
        !           142: # define php_cdb_find(cdb, key, len) cdb_find(cdb, key, len TSRMLS_CC)
        !           143: #else
        !           144: # define php_cdb_read(cdb, buf, len, pos) cdb_read(cdb, buf, len, pos)
        !           145: # define php_cdb_findnext(cdb, key, len) cdb_findnext(cdb, key, len)
        !           146: # define php_cdb_find(cdb, key, len) cdb_find(cdb, key, len)
        !           147: #endif
        !           148: 
        !           149: DBA_FETCH_FUNC(cdb)
        !           150: {
        !           151:        CDB_INFO;
        !           152:        unsigned int len;
        !           153:        char *new_entry = NULL;
        !           154:        
        !           155: #if DBA_CDB_BUILTIN
        !           156:        if (cdb->make)
        !           157:                return NULL; /* database was opened writeonly */
        !           158: #endif
        !           159:        if (php_cdb_find(&cdb->c, key, keylen) == 1) {
        !           160:                while(skip--) {
        !           161:                        if (php_cdb_findnext(&cdb->c, key, keylen) != 1) {
        !           162:                                return NULL;
        !           163:                        }
        !           164:                }
        !           165:                len = cdb_datalen(&cdb->c);
        !           166:                new_entry = safe_emalloc(len, 1, 1);
        !           167:                
        !           168:                if (php_cdb_read(&cdb->c, new_entry, len, cdb_datapos(&cdb->c)) == -1) {
        !           169:                        efree(new_entry);
        !           170:                        return NULL;
        !           171:                }
        !           172:                new_entry[len] = 0;
        !           173:                if (newlen) 
        !           174:                        *newlen = len;
        !           175:        }
        !           176:        
        !           177:        return new_entry;
        !           178: }
        !           179: 
        !           180: DBA_UPDATE_FUNC(cdb)
        !           181: {
        !           182: #if DBA_CDB_BUILTIN
        !           183:        CDB_INFO;
        !           184: 
        !           185:        if (!cdb->make)
        !           186:                return FAILURE; /* database was opened readonly */
        !           187:        if (!mode)
        !           188:                return FAILURE; /* cdb_make dosn't know replace */
        !           189:        if (cdb_make_add(&cdb->m, key, keylen, val, vallen TSRMLS_CC) != -1)
        !           190:                return SUCCESS;
        !           191: #endif
        !           192:        return FAILURE;
        !           193: }
        !           194: 
        !           195: DBA_EXISTS_FUNC(cdb)
        !           196: {
        !           197:        CDB_INFO;
        !           198: 
        !           199: #if DBA_CDB_BUILTIN
        !           200:        if (cdb->make)
        !           201:                return FAILURE; /* database was opened writeonly */
        !           202: #endif
        !           203:        if (php_cdb_find(&cdb->c, key, keylen) == 1)
        !           204:                return SUCCESS;
        !           205:        return FAILURE;
        !           206: }
        !           207: 
        !           208: DBA_DELETE_FUNC(cdb)
        !           209: {
        !           210:        return FAILURE; /* cdb doesn't support delete */
        !           211: }
        !           212: 
        !           213: /* {{{ cdb_file_read */
        !           214: #if DBA_CDB_BUILTIN
        !           215: # define cdb_file_read(fildes, buf, size) php_stream_read(fildes, buf, size)
        !           216: #else
        !           217: # define cdb_file_read(fildes, buf, size) read(fildes, buf, size)
        !           218: #endif
        !           219: /* }}} */
        !           220: 
        !           221: #define CREAD(n) do { \
        !           222:        if (cdb_file_read(cdb->file, buf, n) < n) return NULL; \
        !           223: } while (0)
        !           224: 
        !           225: /* {{{ cdb_file_lseek 
        !           226:  php_stream_seek does not return actual position */
        !           227: #if DBA_CDB_BUILTIN
        !           228: int cdb_file_lseek(php_stream *fp, off_t offset, int whence TSRMLS_DC) {
        !           229:        php_stream_seek(fp, offset, whence);
        !           230:        return php_stream_tell(fp);
        !           231: }
        !           232: #else
        !           233: int cdb_file_lseek(int fd, off_t offset, int whence TSRMLS_DC) {
        !           234:        return lseek(fd, offset, whence);
        !           235: }
        !           236: #endif
        !           237: /* }}} */
        !           238: 
        !           239: #define CSEEK(n) do { \
        !           240:        if (n >= cdb->eod) return NULL; \
        !           241:        if (cdb_file_lseek(cdb->file, (off_t)n, SEEK_SET TSRMLS_CC) != (off_t) n) return NULL; \
        !           242: } while (0)
        !           243: 
        !           244: 
        !           245: DBA_FIRSTKEY_FUNC(cdb)
        !           246: {
        !           247:        CDB_INFO;
        !           248:        uint32 klen, dlen;
        !           249:        char buf[8];
        !           250:        char *key;
        !           251: 
        !           252: #if DBA_CDB_BUILTIN
        !           253:        if (cdb->make)
        !           254:                return NULL; /* database was opened writeonly */
        !           255: #endif
        !           256: 
        !           257:        cdb->eod = -1;
        !           258:        CSEEK(0);
        !           259:        CREAD(4);
        !           260:        
        !           261:        /* Total length of file in bytes */
        !           262:        uint32_unpack(buf, &cdb->eod);
        !           263:        
        !           264:        CSEEK(2048);
        !           265:        CREAD(8);
        !           266:        
        !           267:        /* The first four bytes contain the length of the key */
        !           268:        uint32_unpack(buf, &klen);
        !           269:        uint32_unpack(buf + 4, &dlen);
        !           270: 
        !           271:        key = safe_emalloc(klen, 1, 1);
        !           272:        if (cdb_file_read(cdb->file, key, klen) < klen) {
        !           273:                efree(key);
        !           274:                key = NULL;
        !           275:        } else {
        !           276:                key[klen] = '\0';
        !           277:                if (newlen) *newlen = klen;
        !           278:        }
        !           279: 
        !           280:        /*       header + klenlen + dlenlen + klen + dlen */
        !           281:        cdb->pos = 2048 + 4       + 4       + klen + dlen;
        !           282:                
        !           283:        return key;
        !           284: }
        !           285: 
        !           286: DBA_NEXTKEY_FUNC(cdb)
        !           287: {
        !           288:        CDB_INFO;
        !           289:        uint32 klen, dlen;
        !           290:        char buf[8];
        !           291:        char *key;
        !           292: 
        !           293: #if DBA_CDB_BUILTIN
        !           294:        if (cdb->make)
        !           295:                return NULL; /* database was opened writeonly */
        !           296: #endif
        !           297: 
        !           298:        CSEEK(cdb->pos);
        !           299:        CREAD(8);
        !           300:        uint32_unpack(buf, &klen);
        !           301:        uint32_unpack(buf + 4, &dlen);
        !           302:        
        !           303:        key = safe_emalloc(klen, 1, 1);
        !           304:        if (cdb_file_read(cdb->file, key, klen) < klen) {
        !           305:                efree(key);
        !           306:                key = NULL;
        !           307:        } else {
        !           308:                key[klen] = '\0';
        !           309:                if (newlen) *newlen = klen;
        !           310:        }
        !           311:        
        !           312:        cdb->pos += 8 + klen + dlen;
        !           313:        
        !           314:        return key;
        !           315: }
        !           316: 
        !           317: DBA_OPTIMIZE_FUNC(cdb)
        !           318: {
        !           319:        return SUCCESS;
        !           320: }
        !           321: 
        !           322: DBA_SYNC_FUNC(cdb)
        !           323: {
        !           324:        /* this is read-only */
        !           325:        return SUCCESS;
        !           326: }
        !           327: 
        !           328: DBA_INFO_FUNC(cdb)
        !           329: {
        !           330: #if DBA_CDB_BUILTIN
        !           331:        if (!strcmp(hnd->name, "cdb")) {
        !           332:                return estrdup(cdb_version());
        !           333:        } else {
        !           334:                return estrdup(cdb_make_version());
        !           335:        }
        !           336: #else
        !           337:        return estrdup("External");
        !           338: #endif
        !           339: }
        !           340: 
        !           341: #endif
        !           342: 
        !           343: /*
        !           344:  * Local variables:
        !           345:  * tab-width: 4
        !           346:  * c-basic-offset: 4
        !           347:  * End:
        !           348:  * vim600: sw=4 ts=4 fdm=marker
        !           349:  * vim<600: sw=4 ts=4
        !           350:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>