Return to dba_cdb.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / dba |
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: */