helly Sat Feb 22 12:20:06 2003 EDT Added files: /php4/ext/dba/libinifile .cvsignore inifile.c inifile.h /php4/ext/dba dba_inifile.c php_inifile.h /php4/ext/dba/tests dba_inifile.phpt
Modified files: /php4/ext/dba config.m4 dba.c Log: @Added dba handler inifiles to support ini files. (Marcus)
Index: php4/ext/dba/config.m4 diff -u php4/ext/dba/config.m4:1.44 php4/ext/dba/config.m4:1.45 --- php4/ext/dba/config.m4:1.44 Sun Feb 9 14:57:50 2003 +++ php4/ext/dba/config.m4 Sat Feb 22 12:20:05 2003 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.44 2003/02/09 19:57:50 sniper Exp $ +dnl $Id: config.m4,v 1.45 2003/02/22 17:20:05 helly Exp $ dnl dnl Suppose we need FlatFile if no support or only CDB is used. @@ -380,6 +380,25 @@ ]) AC_DBA_STD_RESULT(cdb) +AC_DEFUN(PHP_DBA_BUILTIN_INI,[ + PHP_ADD_BUILD_DIR($ext_builddir/libini) + AC_DEFINE(DBA_INIFILE, 1, [ ]) + ini_sources="libinifile/inifile.c" + THIS_RESULT="builtin" +]) + +AC_ARG_WITH(inifile, +[ --with-inifile DBA: Include INI support],[ + if test "$withval" != "no"; then + PHP_DBA_BUILTIN_INI + fi +],[ + if test "$PHP_DBA" != "no"; then + PHP_DBA_BUILTIN_INI + fi +]) +AC_DBA_STD_RESULT(inifile,INI File) + AC_DEFUN(PHP_DBA_BUILTIN_FLATFILE,[ PHP_ADD_BUILD_DIR($ext_builddir/libflatfile) AC_DEFINE(DBA_FLATFILE, 1, [ ]) @@ -406,7 +425,7 @@ if test "$HAVE_DBA" = "1"; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_DBA, 1, [ ]) - PHP_NEW_EXTENSION(dba, dba.c dba_cdb.c dba_db2.c dba_dbm.c dba_gdbm.c dba_ndbm.c dba_db3.c dba_db4.c dba_flatfile.c $cdb_sources $flat_sources, $ext_shared) + PHP_NEW_EXTENSION(dba, dba.c dba_cdb.c dba_db2.c dba_dbm.c dba_gdbm.c dba_ndbm.c dba_db3.c dba_db4.c dba_flatfile.c dba_inifile.c $cdb_sources $flat_sources $ini_sources, $ext_shared) PHP_SUBST(DBA_SHARED_LIBADD) else AC_MSG_RESULT(no) Index: php4/ext/dba/dba.c diff -u php4/ext/dba/dba.c:1.82 php4/ext/dba/dba.c:1.83 --- php4/ext/dba/dba.c:1.82 Fri Jan 31 14:12:23 2003 +++ php4/ext/dba/dba.c Sat Feb 22 12:20:05 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba.c,v 1.82 2003/01/31 19:12:23 helly Exp $ */ +/* $Id: dba.c,v 1.83 2003/02/22 17:20:05 helly Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -47,6 +47,7 @@ #include "php_db3.h" #include "php_db4.h" #include "php_flatfile.h" +#include "php_inifile.h" /* {{{ dba_functions[] */ @@ -189,6 +190,9 @@ #if DBA_DB4 DBA_HND(db4, DBA_LOCK_ALL) /* No lock in lib */ #endif +#if DBA_INIFILE + DBA_HND(inifile, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */ +#endif #if DBA_FLATFILE DBA_HND(flatfile, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */ #endif @@ -212,6 +216,7 @@ #else #define DBA_DEFAULT "" #endif +/* cdb/cdb_make and ini are no option here */ ZEND_BEGIN_MODULE_GLOBALS(dba) char *default_handler; @@ -729,8 +734,29 @@ int len = 0; DBA_ID_GET2_3; - if (ac==3 && strcmp(info->hnd->name, "cdb")) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Handler %s does not support optional skip parameter", info->hnd->name); + if (ac==3) { + if (!strcmp(info->hnd->name, "cdb")) { + if (skip < 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Handler %s accepts only skip values greater than or equal to zero, using skip=0", info->hnd->name); + skip = 0; + } + } else if (!strcmp(info->hnd->name, "inifile")) { + /* "-1" is compareable to 0 but allows a non restrictive + * access which is fater. For example 'inifile' uses this + * to allow faster access when the key was already found + * using firstkey/nextkey. However explicitly setting the + * value to 0 ensures the first value. + */ + if (skip < -1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Handler %s accepts only skip value -1 and greater, using skip=0", info->hnd->name); + skip = 0; + } + } else { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Handler %s does not support optional skip parameter, the value will be ignored", info->hnd->name); + skip = 0; + } + } else { + skip = 0; } if((val = info->hnd->fetch(info, VALLEN(key), skip, &len TSRMLS_CC)) != NULL) { if (val && PG(magic_quotes_runtime)) { @@ -773,7 +799,8 @@ /* }}} */ /* {{{ proto bool dba_delete(string key, int handle) - Deletes the entry associated with key */ + Deletes the entry associated with key + If inifile: remove all other key lines */ PHP_FUNCTION(dba_delete) { DBA_ID_GET2; @@ -787,7 +814,8 @@ /* }}} */ /* {{{ proto bool dba_insert(string key, string value, int handle) - Inserts value as key, returns false, if key exists already */ + If not inifile: Insert value as key, return false, if key exists already + If inifile: Add vakue as key (next instance of key) */ PHP_FUNCTION(dba_insert) { php_dba_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); @@ -795,7 +823,8 @@ /* }}} */ /* {{{ proto bool dba_replace(string key, string value, int handle) - Inserts value as key, replaces key, if key exists already */ + Inserts value as key, replaces key, if key exists already + If inifile: remove all other key lines */ PHP_FUNCTION(dba_replace) { php_dba_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); Index: php4/ext/dba/libinifile/.cvsignore +++ php4/ext/dba/libinifile/.cvsignore *.lo *.la deps *.plg *.opt *.ncb Release Release_inline Debug Release_TS Release_TSDbg Release_TS_inline Debug_TS Index: php4/ext/dba/libinifile/inifile.c +++ php4/ext/dba/libinifile/inifile.c /* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2003 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | [EMAIL PROTECTED] so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Marcus Boerger <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ /* $Id: inifile.c,v 1.1 2003/02/22 17:20:05 helly Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_globals.h" #include "safe_mode.h" #include "php_network.h" #include <stdlib.h> #include <string.h> #include <errno.h> #if HAVE_UNISTD_H #include <unistd.h> #endif #include "inifile.h" /* ret = -1 means that database was opened for read-only * ret = 0 success * ret = 1 key already exists - nothing done */ /* {{{ inifile_version */ char *inifile_version() { return "1.0, $Revision: 1.1 $"; } /* }}} */ /* {{{ inifile_free_key */ void inifile_key_free(key_type *key) { if (key->group) { efree(key->group); } if (key->name) { efree(key->name); } memset(key, 0, sizeof(key_type)); } /* }}} */ /* {{{ inifile_free_val */ void inifile_val_free(val_type *val) { if (val->value) { efree(val->value); } memset(val, 0, sizeof(val_type)); } /* }}} */ /* {{{ inifile_free_val */ void inifile_line_free(line_type *ln) { inifile_key_free(&ln->key); inifile_val_free(&ln->val); ln->pos = 0; } /* }}} */ /* {{{ inifile_alloc */ inifile * inifile_alloc(php_stream *fp, int readonly, int persistent TSRMLS_DC) { inifile *dba; int fd = 0; if (!readonly) { if (php_stream_is(fp, PHP_STREAM_IS_SOCKET)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't truncate sockets"); return NULL; } if (SUCCESS != php_stream_cast(fp, PHP_STREAM_AS_FD, (void*)&fd, 1)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not cast stream"); return NULL; } } dba = pemalloc(sizeof(inifile), persistent); memset(dba, 0, sizeof(inifile)); dba->fp = fp; dba->fd = fd; dba->readonly = readonly; return dba; } /* }}} */ /* {{{ inifile_free */ void inifile_free(inifile *dba, int persistent) { if (dba) { inifile_line_free(&dba->curr); inifile_line_free(&dba->next); pefree(dba, persistent); } } /* }}} */ /* {{{ inifile_key_split */ key_type inifile_key_split(const char *group_name) { key_type key; char *name; if (group_name[0] == '[' && (name = strchr(group_name, ']')) != NULL) { key.group = estrndup(group_name+1, name - (group_name + 1)); key.name = estrdup(name+1); } else { key.group = estrdup(""); key.name = estrdup(group_name); } return key; } /* }}} */ /* {{{ inifile_key_string */ char * inifile_key_string(const key_type *key) { if (key->group && *key->group) { char *result; spprintf(&result, 0, "[%s]%s", key->group, key->name ? key->name : ""); return result; } else if (key->name) { return estrdup(key->name); } else { return NULL; } } /* }}} */ /* {{{ etrim */ static char *etrim(const char *str) { char *val; size_t l; if (!str) { return NULL; } val = (char*)str; while (strchr(" \t\r\n", *val)) { val++; } l = strlen(val); while (l && (strchr(" \t\r\n", val[l-1]))) { l--; } return estrndup(val, l); } /* }}} */ /* {{{ inifile_findkey */ static int inifile_read(inifile *dba, line_type *ln TSRMLS_DC) { char *fline; char *pos; inifile_val_free(&ln->val); while ((fline = php_stream_gets(dba->fp, NULL, 0)) != NULL) { if (fline) { if (fline[0] == '[') { /* A value name cannot start with '[' * So either we find a ']' or we found an error */ pos = strchr(fline+1, ']'); if (pos) { *pos = '\0'; inifile_key_free(&ln->key); ln->key.group = etrim(fline+1); ln->key.name = estrdup(""); ln->pos = php_stream_tell(dba->fp); efree(fline); return 1; } else { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "The following group was started with '[' but not ended with ']': '%s'", fline+1); efree(fline); continue; } } else { pos = strchr(fline, '='); if (pos) { *pos = '\0'; /* keep group or make empty if not existent */ if (!ln->key.group) { ln->key.group = estrdup(""); } if (ln->key.name) { efree(ln->key.name); } ln->key.name = etrim(fline); ln->val.value = etrim(pos+1); ln->pos = php_stream_tell(dba->fp); efree(fline); return 1; } else { /* simply ignore lines without '=' * those should be comments */ efree(fline); continue; } } } } inifile_line_free(ln); return 0; } /* }}} */ /* {{{ inifile_key_cmp */ /* 0 = EQUAL * 1 = GROUP-EQUAL,NAME-DIFFERENT * 2 = DIFFERENT */ static int inifile_key_cmp(const key_type *k1, const key_type *k2 TSRMLS_DC) { assert(k1->group && k1->name && k2->group && k2->name); if (!strcmp(k1->group, k2->group)) { if (!strcmp(k1->name, k2->name)) { return 0; } else { return 1; } } else { return 2; } } /* }}} */ /* {{{ inifile_fetch */ val_type inifile_fetch(inifile *dba, const key_type *key, int skip TSRMLS_DC) { line_type ln = {{NULL,NULL},{NULL}}; val_type val; int res, grp_eq = 0; if (skip == -1) { if (dba->next.key.group && dba->next.key.name && !inifile_key_cmp(&dba->next.key, key TSRMLS_CC)) { /* we got it already from last fetch */ val.value = estrdup(dba->next.val.value ? dba->next.val.value : ""); /* allow faster access by automatically getting next key */ php_stream_seek(dba->fp, dba->next.pos, SEEK_SET); ln.key.group = estrdup(dba->next.key.group ? dba->next.key.group : ""); inifile_read(dba, &ln TSRMLS_CC); inifile_line_free(&dba->next); dba->next = ln; return val; } else if (dba->curr.key.group && dba->curr.key.name && !inifile_key_cmp(&dba->curr.key, key TSRMLS_CC)) { /* we got it already from firstkey/lastkey */ /* * this optimisation does not work when firstkey/nextkey found * any instance other than the one instance wanted. */ val.value = estrdup(dba->curr.val.value ? dba->curr.val.value : ""); /* allow faster access by automatically getting next key * we must use the line pointer 'next' since we cannot change the * line pointer of firstkey/nextkey */ php_stream_seek(dba->fp, dba->curr.pos, SEEK_SET); ln.key.group = estrdup(dba->curr.key.group ? dba->curr.key.group : ""); inifile_read(dba, &ln TSRMLS_CC); inifile_line_free(&dba->next); dba->next = ln; return val; } } /* the slow way: restart and seacrch */ if (skip != -1 || !dba->next.key.group || !dba->next.key.name || inifile_key_cmp(&dba->next.key, key TSRMLS_CC)) { /* specific instance or not same key -> restart search */ php_stream_rewind(dba->fp); } inifile_line_free(&dba->next); if (skip == -1) { skip = 0; } while(inifile_read(dba, &ln TSRMLS_CC)) { if (!(res=inifile_key_cmp(&ln.key, key TSRMLS_CC))) { if (!skip) { val.value = estrdup(ln.val.value ? ln.val.value : ""); /* allow faster access by automatically getting next key */ inifile_read(dba, &ln TSRMLS_CC); inifile_line_free(&dba->next); dba->next = ln; return val; } skip--; } else if (res == 1) { grp_eq = 1; } else if (grp_eq) { /* we are leaving group now: that means we cannot find the key */ break; } } inifile_line_free(&ln); inifile_line_free(&dba->next); return ln.val; } /* }}} */ /* {{{ inifile_firstkey */ int inifile_firstkey(inifile *dba TSRMLS_DC) { inifile_line_free(&dba->curr); dba->curr.pos = 0; return inifile_nextkey(dba TSRMLS_CC); } /* }}} */ /* {{{ inifile_nextkey */ int inifile_nextkey(inifile *dba TSRMLS_DC) { line_type ln = {{NULL,NULL},{NULL}}; /*inifile_line_free(&dba->next); ??? */ php_stream_seek(dba->fp, dba->curr.pos, SEEK_SET); ln.key.group = estrdup(dba->curr.key.group ? dba->curr.key.group : ""); inifile_read(dba, &ln TSRMLS_CC); inifile_line_free(&dba->curr); dba->curr = ln; return ln.key.group || ln.key.name; } /* }}} */ /* {{{ inifile_truncate */ static int inifile_truncate(inifile *dba, size_t size TSRMLS_DC) { int res; if ((res=ftruncate(dba->fd, size)) != 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error in ftruncate: %d", res); return FAILURE; } php_stream_seek(dba->fp, size, SEEK_SET); return SUCCESS; } /* }}} */ /* {{{ inifile_find_group * if found pos_grp_start points to "[group_name]" */ static int inifile_find_group(inifile *dba, const key_type *key, size_t *pos_grp_start TSRMLS_DC) { int ret = FAILURE; php_stream_flush(dba->fp); php_stream_seek(dba->fp, 0, SEEK_SET); inifile_line_free(&dba->curr); inifile_line_free(&dba->next); if (key->group && strlen(key->group)) { int res; line_type ln = {{NULL,NULL},{NULL}}; res = 1; while(inifile_read(dba, &ln TSRMLS_CC)) { if ((res=inifile_key_cmp(&ln.key, key TSRMLS_CC)) < 2) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Found group: %d", *pos_grp_start); ret = SUCCESS; break; } *pos_grp_start = php_stream_tell(dba->fp); } inifile_line_free(&ln); } else { *pos_grp_start = 0; ret = SUCCESS; } if (ret == FAILURE) { *pos_grp_start = php_stream_tell(dba->fp); } return ret; } /* }}} */ /* {{{ inifile_next_group * only valid after a call to inifile_find_group * if any next group is found pos_grp_start points to "[group_name]" or whitespace before that */ static int inifile_next_group(inifile *dba, const key_type *key, size_t *pos_grp_start TSRMLS_DC) { int ret = FAILURE; line_type ln = {{NULL,NULL},{NULL}}; *pos_grp_start = php_stream_tell(dba->fp); ln.key.group = estrdup(key->group); while(inifile_read(dba, &ln TSRMLS_CC)) { if (inifile_key_cmp(&ln.key, key TSRMLS_CC) == 2) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Found next group: %d", *pos_grp_start); ret = SUCCESS; break; } *pos_grp_start = php_stream_tell(dba->fp); } inifile_line_free(&ln); return ret; } /* }}} */ /* {{{ inifile_copy_to */ static int inifile_copy_to(inifile *dba, size_t pos_start, size_t pos_end, inifile **ini_copy TSRMLS_DC) { php_stream *fp; if (pos_start == pos_end) { *ini_copy = NULL; return SUCCESS; } if ((fp = php_stream_temp_create(0, 64 * 1024)) == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create temporary stream"); *ini_copy = NULL; return FAILURE; } if ((*ini_copy = inifile_alloc(fp, 1, 0 TSRMLS_CC)) == NULL) { /* writes error */ return FAILURE; } php_stream_seek(dba->fp, pos_start, SEEK_SET); if (!php_stream_copy_to_stream(dba->fp, fp, pos_end - pos_start)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy group [%d - %d] to temporary stream", pos_start, pos_end); return FAILURE; } return SUCCESS; } /* }}} */ /* {{{ inifile_filter * copy from to dba while ignoring key name (group must equal) */ static int inifile_filter(inifile *dba, inifile *from, const key_type *key TSRMLS_DC) { size_t pos_start = 0, pos_next = 0, pos_curr; int ret = SUCCESS; line_type ln = {{NULL,NULL},{NULL}}; php_stream_seek(from->fp, 0, SEEK_SET); php_stream_seek(dba->fp, 0, SEEK_END); while(inifile_read(from, &ln TSRMLS_CC)) { switch(inifile_key_cmp(&ln.key, key TSRMLS_CC)) { case 0: pos_curr = php_stream_tell(from->fp); if (pos_start != pos_next) { php_stream_seek(from->fp, pos_start, SEEK_SET); if (!php_stream_copy_to_stream(from->fp, dba->fp, pos_next - pos_start)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy [%d - %d] from temporary stream", pos_next, pos_start); ret = FAILURE; } php_stream_seek(from->fp, pos_curr, SEEK_SET); } pos_next = pos_start = pos_curr; break; case 1: pos_next = php_stream_tell(from->fp); break; case 2: /* the function is meant to process only entries from same group */ assert(0); break; } } if (pos_start != pos_next) { php_stream_seek(from->fp, pos_start, SEEK_SET); if (!php_stream_copy_to_stream(from->fp, dba->fp, pos_next - pos_start)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy [%d - %d] from temporary stream", pos_next, pos_start); ret = FAILURE; } } inifile_line_free(&ln); return SUCCESS; } /* }}} */ /* {{{ inifile_delete_replace_append */ static int inifile_delete_replace_append(inifile *dba, const key_type *key, const val_type *value, int append TSRMLS_DC) { size_t pos_grp_start, pos_grp_next; inifile *ini_tmp = NULL; php_stream *fp_tmp = NULL; int ret; /* 1) Search group start * 2) Search next group * 3) If not append: Copy group to ini_tmp * 4) Open temp_stream and copy remainder * 5) Truncate stream * 6) If not append AND key.name given: Filtered copy back from ini_tmp * to stream. Otherwise the user wanted to delete the group. * 7) Append value if given * 8) Append temporary stream */ assert(!append || (key->name && value)); /* missuse */ /* 1 - 3 */ inifile_find_group(dba, key, &pos_grp_start TSRMLS_CC); inifile_next_group(dba, key, &pos_grp_next TSRMLS_CC); if (append) { ret = SUCCESS; } else { ret = inifile_copy_to(dba, pos_grp_start, pos_grp_next, &ini_tmp TSRMLS_CC); } /* 4 */ if (ret == SUCCESS) { fp_tmp = php_stream_temp_create(0, 64 * 1024); if (!fp_tmp) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create temporary stream"); ret = FAILURE; } else { php_stream_seek(dba->fp, 0, SEEK_END); if (pos_grp_next != php_stream_tell(dba->fp)) { php_stream_seek(dba->fp, pos_grp_next, SEEK_SET); if (!php_stream_copy_to_stream(dba->fp, fp_tmp, PHP_STREAM_COPY_ALL)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy remainder to temporary stream"); ret = FAILURE; } } } } /* 5 */ if (ret == SUCCESS) { ret = inifile_truncate(dba, append ? pos_grp_next : pos_grp_start TSRMLS_CC); /* writes error on fail */ } if (ret == SUCCESS) { if (key->name && strlen(key->name)) { /* 6 */ if (!append && ini_tmp) { ret = inifile_filter(dba, ini_tmp, key TSRMLS_CC); } /* 7 */ /* important: do not query ret==SUCCESS again: inifile_filter might fail but * however next operation must be done. */ if (value) { if (pos_grp_start == pos_grp_next && key->group && strlen(key->group)) { php_stream_printf(dba->fp TSRMLS_CC, "[%s]\n", key->group); } php_stream_printf(dba->fp TSRMLS_CC, "%s=%s\n", key->name, value->value ? value->value : ""); } } /* 8 */ /* important: do not query ret==SUCCESS again: inifile_filter might fail but * however next operation must be done. */ if (fp_tmp && php_stream_tell(fp_tmp)) { php_stream_seek(fp_tmp, 0, SEEK_SET); php_stream_seek(dba->fp, 0, SEEK_END); if (!php_stream_copy_to_stream(fp_tmp, dba->fp, PHP_STREAM_COPY_ALL)) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not copy from temporary stream - ini file truncated"); ret = FAILURE; } } } if (ini_tmp) { php_stream_close(ini_tmp->fp); inifile_free(ini_tmp, 0); } if (fp_tmp) { php_stream_close(fp_tmp); } php_stream_flush(dba->fp); php_stream_seek(dba->fp, 0, SEEK_SET); return ret; } /* }}} */ /* {{{ inifile_delete */ int inifile_delete(inifile *dba, const key_type *key TSRMLS_DC) { return inifile_delete_replace_append(dba, key, NULL, 0 TSRMLS_CC); } /* }}} */ /* {{{ inifile_relace */ int inifile_replace(inifile *dba, const key_type *key, const val_type *value TSRMLS_DC) { return inifile_delete_replace_append(dba, key, value, 0 TSRMLS_CC); } /* }}} */ /* {{{ inifile_append */ int inifile_append(inifile *dba, const key_type *key, const val_type *value TSRMLS_DC) { return inifile_delete_replace_append(dba, key, value, 1 TSRMLS_CC); } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */ Index: php4/ext/dba/libinifile/inifile.h +++ php4/ext/dba/libinifile/inifile.h /* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2003 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | [EMAIL PROTECTED] so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Marcus Boerger <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ /* $Id: inifile.h,v 1.1 2003/02/22 17:20:05 helly Exp $ */ #ifndef PHP_LIB_INIFILE_H #define PHP_LIB_INIFILE_H typedef struct { char *group; char *name; } key_type; typedef struct { char *value; } val_type; typedef struct { key_type key; val_type val; size_t pos; } line_type; typedef struct { char *lockfn; int lockfd; php_stream *fp; int fd; int readonly; line_type curr; line_type next; } inifile; val_type inifile_fetch(inifile *dba, const key_type *key, int skip TSRMLS_DC); int inifile_firstkey(inifile *dba TSRMLS_DC); int inifile_nextkey(inifile *dba TSRMLS_DC); int inifile_delete(inifile *dba, const key_type *key TSRMLS_DC); int inifile_replace(inifile *dba, const key_type *key, const val_type *val TSRMLS_DC); int inifile_append(inifile *dba, const key_type *key, const val_type *val TSRMLS_DC); char *inifile_version(); key_type inifile_key_split(const char *group_name); char * inifile_key_string(const key_type *key); void inifile_key_free(key_type *key); void inifile_val_free(val_type *val); void inifile_line_free(line_type *ln); inifile * inifile_alloc(php_stream *fp, int readonly, int persistent TSRMLS_DC); void inifile_free(inifile *dba, int persistent); #endif Index: php4/ext/dba/dba_inifile.c +++ php4/ext/dba/dba_inifile.c /* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2003 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | [EMAIL PROTECTED] so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Marcus Boerger <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ /* $Id: dba_inifile.c,v 1.1 2003/02/22 17:20:05 helly Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #if DBA_INIFILE #include "php_inifile.h" #include "libinifile/inifile.h" #ifdef HAVE_UNISTD_H #include <unistd.h> #endif #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define INIFILE_DATA \ inifile *dba = info->dbf #define INIFILE_GKEY \ key_type ini_key = inifile_key_split((char*)key) /* keylen not needed here */ #define INIFILE_DONE \ inifile_key_free(&ini_key) DBA_OPEN_FUNC(inifile) { info->dbf = inifile_alloc(info->fp, info->mode == DBA_READER, info->flags&DBA_PERSISTENT TSRMLS_CC); return info->dbf ? SUCCESS : FAILURE; } DBA_CLOSE_FUNC(inifile) { INIFILE_DATA; inifile_free(dba, info->flags&DBA_PERSISTENT); } DBA_FETCH_FUNC(inifile) { val_type ini_val; INIFILE_DATA; INIFILE_GKEY; ini_val = inifile_fetch(dba, &ini_key, skip TSRMLS_CC); *newlen = ini_val.value ? strlen(ini_val.value) : 0; INIFILE_DONE; return ini_val.value; } DBA_UPDATE_FUNC(inifile) { val_type ini_val; int res; INIFILE_DATA; INIFILE_GKEY; ini_val.value = val; if (mode == 1) { res = inifile_append(dba, &ini_key, &ini_val TSRMLS_CC); } else { res = inifile_replace(dba, &ini_key, &ini_val TSRMLS_CC); } INIFILE_DONE; switch(res) { case -1: php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Operation not possible"); return FAILURE; default: case 0: return SUCCESS; case 1: php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Key already exists"); return SUCCESS; } } DBA_EXISTS_FUNC(inifile) { val_type ini_val; INIFILE_DATA; INIFILE_GKEY; ini_val = inifile_fetch(dba, &ini_key, 0 TSRMLS_CC); INIFILE_DONE; if (ini_val.value) { inifile_val_free(&ini_val); return SUCCESS; } return FAILURE; } DBA_DELETE_FUNC(inifile) { INIFILE_DATA; INIFILE_GKEY; int res = inifile_delete(dba, &ini_key TSRMLS_CC); INIFILE_DONE; return (res == -1 ? FAILURE : SUCCESS); } DBA_FIRSTKEY_FUNC(inifile) { INIFILE_DATA; if (inifile_firstkey(dba TSRMLS_CC)) { char *result = inifile_key_string(&dba->curr.key); *newlen = strlen(result); return result; } else { return NULL; } } DBA_NEXTKEY_FUNC(inifile) { INIFILE_DATA; if (!dba->curr.key.group && !dba->curr.key.name) { return NULL; } if (inifile_nextkey(dba TSRMLS_CC)) { char *result = inifile_key_string(&dba->curr.key); *newlen = strlen(result); return result; } else { return NULL; } } DBA_OPTIMIZE_FUNC(inifile) { /* dummy */ return SUCCESS; } DBA_SYNC_FUNC(inifile) { /* dummy */ return SUCCESS; } DBA_INFO_FUNC(inifile) { return estrdup(inifile_version()); } #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */ Index: php4/ext/dba/php_inifile.h +++ php4/ext/dba/php_inifile.h #ifndef PHP_INIFILE_H #define PHP_INIFILE_H #if DBA_INIFILE #include "php_dba.h" DBA_FUNCS(inifile); #endif #endif Index: php4/ext/dba/tests/dba_inifile.phpt +++ php4/ext/dba/tests/dba_inifile.phpt --TEST-- DBA INIFILE handler test --SKIPIF-- <?php require_once('skipif.inc'); if (!in_array('inifile', dba_handlers())) die('skip INIFILE handler not available'); ?> --FILE-- <?php require_once('test.inc'); $handler = 'inifile'; require_once('dba_handler.inc'); ?> --EXPECT-- database handler: inifile 3NYNYY Content String 2 Content 2 replaced Read during write: not allowed Content 2 replaced 2nd time The 6th value array(3) { ["key number 6"]=> string(13) "The 6th value" ["key2"]=> string(27) "Content 2 replaced 2nd time" ["key5"]=> string(23) "The last content string" }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php