Back to index

php5  5.3.10
flatfile.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2010 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Marcus Boerger <helly@php.net>                              |
00016    | based on ext/db/db.c by:                                             |
00017    |          Rasmus Lerdorf <rasmus@php.net>                             |
00018    |          Jim Winstead <jimw@php.net>                                 |
00019    +----------------------------------------------------------------------+
00020  */
00021 
00022 /* $Id: flatfile.c 306527 2010-12-20 23:00:11Z iliaa $ */
00023 
00024 #ifdef HAVE_CONFIG_H
00025 #include "config.h"
00026 #endif
00027 
00028 #include "php.h"
00029 #include "php_globals.h"
00030 #include "safe_mode.h"
00031 
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <errno.h>
00035 #if HAVE_UNISTD_H
00036 #include <unistd.h>
00037 #endif
00038 
00039 #include "flatfile.h"
00040 
00041 #define FLATFILE_BLOCK_SIZE 1024
00042 
00043 /*
00044  * ret = -1 means that database was opened for read-only
00045  * ret = 0  success
00046  * ret = 1  key already exists - nothing done
00047  */
00048 
00049 /* {{{ flatfile_store
00050  */
00051 int flatfile_store(flatfile *dba, datum key_datum, datum value_datum, int mode TSRMLS_DC) {
00052        if (mode == FLATFILE_INSERT) {
00053               if (flatfile_findkey(dba, key_datum TSRMLS_CC)) {
00054                      return 1;
00055               }
00056               php_stream_seek(dba->fp, 0L, SEEK_END);
00057               php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", key_datum.dsize);
00058               php_stream_flush(dba->fp);
00059               if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) {
00060                      return -1;
00061               }
00062               php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", value_datum.dsize);
00063               php_stream_flush(dba->fp);
00064               if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) {
00065                      return -1;
00066               }
00067        } else { /* FLATFILE_REPLACE */
00068               flatfile_delete(dba, key_datum TSRMLS_CC);
00069               php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", key_datum.dsize);
00070               php_stream_flush(dba->fp);
00071               if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) {
00072                      return -1;
00073               }
00074               php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", value_datum.dsize);
00075               if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) {
00076                      return -1;
00077               }
00078        }
00079 
00080        php_stream_flush(dba->fp);
00081        return 0;
00082 }
00083 /* }}} */
00084 
00085 /* {{{ flatfile_fetch
00086  */
00087 datum flatfile_fetch(flatfile *dba, datum key_datum TSRMLS_DC) {
00088        datum value_datum = {NULL, 0};
00089        char buf[16];
00090 
00091        if (flatfile_findkey(dba, key_datum TSRMLS_CC)) {
00092               if (php_stream_gets(dba->fp, buf, sizeof(buf))) {
00093                      value_datum.dsize = atoi(buf);
00094                      value_datum.dptr = safe_emalloc(value_datum.dsize, 1, 1);
00095                      value_datum.dsize = php_stream_read(dba->fp, value_datum.dptr, value_datum.dsize);
00096               } else {
00097                      value_datum.dptr = NULL;
00098                      value_datum.dsize = 0;
00099               }
00100        }
00101        return value_datum;
00102 }
00103 /* }}} */
00104 
00105 /* {{{ flatfile_delete
00106  */
00107 int flatfile_delete(flatfile *dba, datum key_datum TSRMLS_DC) {
00108        char *key = key_datum.dptr;
00109        size_t size = key_datum.dsize;
00110        size_t buf_size = FLATFILE_BLOCK_SIZE;
00111        char *buf = emalloc(buf_size);
00112        size_t num;
00113        size_t pos;
00114 
00115        php_stream_rewind(dba->fp);
00116        while(!php_stream_eof(dba->fp)) {
00117               /* read in the length of the key name */
00118               if (!php_stream_gets(dba->fp, buf, 15)) {
00119                      break;
00120               }
00121               num = atoi(buf);
00122               if (num >= buf_size) {
00123                      buf_size = num + FLATFILE_BLOCK_SIZE;
00124                      buf = erealloc(buf, buf_size);
00125               }
00126               pos = php_stream_tell(dba->fp);
00127 
00128               /* read in the key name */
00129               num = php_stream_read(dba->fp, buf, num);
00130               if (num < 0)  {
00131                      break;
00132               }
00133 
00134               if (size == num && !memcmp(buf, key, size)) {
00135                      php_stream_seek(dba->fp, pos, SEEK_SET);
00136                      php_stream_putc(dba->fp, 0);
00137                      php_stream_flush(dba->fp);
00138                      php_stream_seek(dba->fp, 0L, SEEK_END);
00139                      efree(buf);
00140                      return SUCCESS;
00141               }      
00142 
00143               /* read in the length of the value */
00144               if (!php_stream_gets(dba->fp, buf, 15)) {
00145                      break;
00146               }
00147               num = atoi(buf);
00148               if (num >= buf_size) {
00149                      buf_size = num + FLATFILE_BLOCK_SIZE;
00150                      buf = erealloc(buf, buf_size);
00151               }
00152               /* read in the value */
00153               num = php_stream_read(dba->fp, buf, num);
00154               if (num < 0) {
00155                      break;
00156               }
00157        }
00158        efree(buf);
00159        return FAILURE;
00160 }      
00161 /* }}} */
00162 
00163 /* {{{ flatfile_findkey
00164  */
00165 int flatfile_findkey(flatfile *dba, datum key_datum TSRMLS_DC) {
00166        size_t buf_size = FLATFILE_BLOCK_SIZE;
00167        char *buf = emalloc(buf_size);
00168        size_t num;
00169        int ret=0;
00170        void *key = key_datum.dptr;
00171        size_t size = key_datum.dsize;
00172 
00173        php_stream_rewind(dba->fp);
00174        while (!php_stream_eof(dba->fp)) {
00175               if (!php_stream_gets(dba->fp, buf, 15)) {
00176                      break;
00177               }
00178               num = atoi(buf);
00179               if (num >= buf_size) {
00180                      buf_size = num + FLATFILE_BLOCK_SIZE;
00181                      buf = erealloc(buf, buf_size);
00182               }
00183               num = php_stream_read(dba->fp, buf, num);
00184               if (num < 0) {
00185                      break;
00186               }
00187               if (size == num) {
00188                      if (!memcmp(buf, key, size)) {
00189                             ret = 1;
00190                             break;
00191                      }
00192               }      
00193               if (!php_stream_gets(dba->fp, buf, 15)) {
00194                      break;
00195               }
00196               num = atoi(buf);
00197               if (num >= buf_size) {
00198                      buf_size = num + FLATFILE_BLOCK_SIZE;
00199                      buf = erealloc(buf, buf_size);
00200               }
00201               num = php_stream_read(dba->fp, buf, num);
00202               if (num < 0) {
00203                      break;
00204               }
00205        }
00206        efree(buf);
00207        return ret;
00208 }
00209 /* }}} */
00210 
00211 /* {{{ flatfile_firstkey
00212  */
00213 datum flatfile_firstkey(flatfile *dba TSRMLS_DC) {
00214        datum res;
00215        size_t num;
00216        size_t buf_size = FLATFILE_BLOCK_SIZE;
00217        char *buf = emalloc(buf_size);
00218 
00219        php_stream_rewind(dba->fp);
00220        while(!php_stream_eof(dba->fp)) {
00221               if (!php_stream_gets(dba->fp, buf, 15)) {
00222                      break;
00223               }
00224               num = atoi(buf);
00225               if (num >= buf_size) {
00226                      buf_size = num + FLATFILE_BLOCK_SIZE;
00227                      buf = erealloc(buf, buf_size);
00228               }
00229               num = php_stream_read(dba->fp, buf, num);
00230               if (num < 0) {
00231                      break;
00232               }
00233               if (*(buf) != 0) {
00234                      dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
00235                      res.dptr = buf;
00236                      res.dsize = num;
00237                      return res;
00238               }
00239               if (!php_stream_gets(dba->fp, buf, 15)) {
00240                      break;
00241               }
00242               num = atoi(buf);
00243               if (num >= buf_size) {
00244                      buf_size = num + FLATFILE_BLOCK_SIZE;
00245                      buf = erealloc(buf, buf_size);
00246               }
00247               num = php_stream_read(dba->fp, buf, num);
00248               if (num < 0) {
00249                      break;
00250               }
00251        }
00252        efree(buf);
00253        res.dptr = NULL;
00254        res.dsize = 0;
00255        return res;
00256 }
00257 /* }}} */
00258 
00259 /* {{{ flatfile_nextkey
00260  */
00261 datum flatfile_nextkey(flatfile *dba TSRMLS_DC) {
00262        datum res;
00263        size_t num;
00264        size_t buf_size = FLATFILE_BLOCK_SIZE;
00265        char *buf = emalloc(buf_size);
00266 
00267        php_stream_seek(dba->fp, dba->CurrentFlatFilePos, SEEK_SET);
00268        while(!php_stream_eof(dba->fp)) {
00269               if (!php_stream_gets(dba->fp, buf, 15)) {
00270                      break;
00271               }
00272               num = atoi(buf);
00273               if (num >= buf_size) {
00274                      buf_size = num + FLATFILE_BLOCK_SIZE;
00275                      buf = erealloc(buf, buf_size);
00276               }
00277               num = php_stream_read(dba->fp, buf, num);
00278               if (num < 0)  {
00279                      break;
00280               }
00281               if (!php_stream_gets(dba->fp, buf, 15)) {
00282                      break;
00283               }
00284               num = atoi(buf);
00285               if (num >= buf_size) {
00286                      buf_size = num + FLATFILE_BLOCK_SIZE;
00287                      buf = erealloc(buf, buf_size);
00288               }
00289               num = php_stream_read(dba->fp, buf, num);
00290               if (num < 0) {
00291                      break;
00292               }
00293               if (*(buf)!=0) {
00294                      dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
00295                      res.dptr = buf;
00296                      res.dsize = num;
00297                      return res;
00298               }
00299        }
00300        efree(buf);
00301        res.dptr = NULL;
00302        res.dsize = 0;
00303        return res;
00304 }      
00305 /* }}} */
00306 
00307 /* {{{ flatfile_version */
00308 char *flatfile_version() 
00309 {
00310        return "1.0, $Revision: 306527 $";
00311 }
00312 /* }}} */ 
00313 
00314 /*
00315  * Local variables:
00316  * tab-width: 4
00317  * c-basic-offset: 4
00318  * End:
00319  * vim600: sw=4 ts=4 fdm=marker
00320  * vim<600: sw=4 ts=4
00321  */