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>