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

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.3 ! misho       5:    | Copyright (c) 1997-2013 The PHP Group                                |
1.1       misho       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: 
1.1.1.2   misho      20: /* $Id$ */
1.1       misho      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>