File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / dba / dba_cdb.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:34:37 2012 UTC (12 years, 1 month ago) by misho
Branches: php, MAIN
CVS tags: v5_4_3elwix, v5_4_17p0, HEAD
php 5.4.3+patches

    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,v 1.1.1.2 2012/05/29 12:34:37 misho Exp $ */
   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>