summaryrefslogtreecommitdiff
path: root/ext/dba/libflatfile
diff options
context:
space:
mode:
Diffstat (limited to 'ext/dba/libflatfile')
-rw-r--r--ext/dba/libflatfile/flatfile.c320
-rw-r--r--ext/dba/libflatfile/flatfile.h48
2 files changed, 368 insertions, 0 deletions
diff --git a/ext/dba/libflatfile/flatfile.c b/ext/dba/libflatfile/flatfile.c
new file mode 100644
index 0000000..194f016
--- /dev/null
+++ b/ext/dba/libflatfile/flatfile.c
@@ -0,0 +1,320 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.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 |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Marcus Boerger <helly@php.net> |
+ | based on ext/db/db.c by: |
+ | Rasmus Lerdorf <rasmus@php.net> |
+ | Jim Winstead <jimw@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id: 6ce2f616c81b8404a2b4143c0be5cadeaa0d4742 $ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_globals.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "flatfile.h"
+
+#define FLATFILE_BLOCK_SIZE 1024
+
+/*
+ * ret = -1 means that database was opened for read-only
+ * ret = 0 success
+ * ret = 1 key already exists - nothing done
+ */
+
+/* {{{ flatfile_store
+ */
+int flatfile_store(flatfile *dba, datum key_datum, datum value_datum, int mode TSRMLS_DC) {
+ if (mode == FLATFILE_INSERT) {
+ if (flatfile_findkey(dba, key_datum TSRMLS_CC)) {
+ return 1;
+ }
+ php_stream_seek(dba->fp, 0L, SEEK_END);
+ php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", key_datum.dsize);
+ php_stream_flush(dba->fp);
+ if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) {
+ return -1;
+ }
+ php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", value_datum.dsize);
+ php_stream_flush(dba->fp);
+ if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) {
+ return -1;
+ }
+ } else { /* FLATFILE_REPLACE */
+ flatfile_delete(dba, key_datum TSRMLS_CC);
+ php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", key_datum.dsize);
+ php_stream_flush(dba->fp);
+ if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) {
+ return -1;
+ }
+ php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", value_datum.dsize);
+ if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) {
+ return -1;
+ }
+ }
+
+ php_stream_flush(dba->fp);
+ return 0;
+}
+/* }}} */
+
+/* {{{ flatfile_fetch
+ */
+datum flatfile_fetch(flatfile *dba, datum key_datum TSRMLS_DC) {
+ datum value_datum = {NULL, 0};
+ char buf[16];
+
+ if (flatfile_findkey(dba, key_datum TSRMLS_CC)) {
+ if (php_stream_gets(dba->fp, buf, sizeof(buf))) {
+ value_datum.dsize = atoi(buf);
+ value_datum.dptr = safe_emalloc(value_datum.dsize, 1, 1);
+ value_datum.dsize = php_stream_read(dba->fp, value_datum.dptr, value_datum.dsize);
+ } else {
+ value_datum.dptr = NULL;
+ value_datum.dsize = 0;
+ }
+ }
+ return value_datum;
+}
+/* }}} */
+
+/* {{{ flatfile_delete
+ */
+int flatfile_delete(flatfile *dba, datum key_datum TSRMLS_DC) {
+ char *key = key_datum.dptr;
+ size_t size = key_datum.dsize;
+ size_t buf_size = FLATFILE_BLOCK_SIZE;
+ char *buf = emalloc(buf_size);
+ size_t num;
+ size_t pos;
+
+ php_stream_rewind(dba->fp);
+ while(!php_stream_eof(dba->fp)) {
+ /* read in the length of the key name */
+ if (!php_stream_gets(dba->fp, buf, 15)) {
+ break;
+ }
+ num = atoi(buf);
+ if (num >= buf_size) {
+ buf_size = num + FLATFILE_BLOCK_SIZE;
+ buf = erealloc(buf, buf_size);
+ }
+ pos = php_stream_tell(dba->fp);
+
+ /* read in the key name */
+ num = php_stream_read(dba->fp, buf, num);
+ if (num < 0) {
+ break;
+ }
+
+ if (size == num && !memcmp(buf, key, size)) {
+ php_stream_seek(dba->fp, pos, SEEK_SET);
+ php_stream_putc(dba->fp, 0);
+ php_stream_flush(dba->fp);
+ php_stream_seek(dba->fp, 0L, SEEK_END);
+ efree(buf);
+ return SUCCESS;
+ }
+
+ /* read in the length of the value */
+ if (!php_stream_gets(dba->fp, buf, 15)) {
+ break;
+ }
+ num = atoi(buf);
+ if (num >= buf_size) {
+ buf_size = num + FLATFILE_BLOCK_SIZE;
+ buf = erealloc(buf, buf_size);
+ }
+ /* read in the value */
+ num = php_stream_read(dba->fp, buf, num);
+ if (num < 0) {
+ break;
+ }
+ }
+ efree(buf);
+ return FAILURE;
+}
+/* }}} */
+
+/* {{{ flatfile_findkey
+ */
+int flatfile_findkey(flatfile *dba, datum key_datum TSRMLS_DC) {
+ size_t buf_size = FLATFILE_BLOCK_SIZE;
+ char *buf = emalloc(buf_size);
+ size_t num;
+ int ret=0;
+ void *key = key_datum.dptr;
+ size_t size = key_datum.dsize;
+
+ php_stream_rewind(dba->fp);
+ while (!php_stream_eof(dba->fp)) {
+ if (!php_stream_gets(dba->fp, buf, 15)) {
+ break;
+ }
+ num = atoi(buf);
+ if (num >= buf_size) {
+ buf_size = num + FLATFILE_BLOCK_SIZE;
+ buf = erealloc(buf, buf_size);
+ }
+ num = php_stream_read(dba->fp, buf, num);
+ if (num < 0) {
+ break;
+ }
+ if (size == num) {
+ if (!memcmp(buf, key, size)) {
+ ret = 1;
+ break;
+ }
+ }
+ if (!php_stream_gets(dba->fp, buf, 15)) {
+ break;
+ }
+ num = atoi(buf);
+ if (num >= buf_size) {
+ buf_size = num + FLATFILE_BLOCK_SIZE;
+ buf = erealloc(buf, buf_size);
+ }
+ num = php_stream_read(dba->fp, buf, num);
+ if (num < 0) {
+ break;
+ }
+ }
+ efree(buf);
+ return ret;
+}
+/* }}} */
+
+/* {{{ flatfile_firstkey
+ */
+datum flatfile_firstkey(flatfile *dba TSRMLS_DC) {
+ datum res;
+ size_t num;
+ size_t buf_size = FLATFILE_BLOCK_SIZE;
+ char *buf = emalloc(buf_size);
+
+ php_stream_rewind(dba->fp);
+ while(!php_stream_eof(dba->fp)) {
+ if (!php_stream_gets(dba->fp, buf, 15)) {
+ break;
+ }
+ num = atoi(buf);
+ if (num >= buf_size) {
+ buf_size = num + FLATFILE_BLOCK_SIZE;
+ buf = erealloc(buf, buf_size);
+ }
+ num = php_stream_read(dba->fp, buf, num);
+ if (num < 0) {
+ break;
+ }
+ if (*(buf) != 0) {
+ dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
+ res.dptr = buf;
+ res.dsize = num;
+ return res;
+ }
+ if (!php_stream_gets(dba->fp, buf, 15)) {
+ break;
+ }
+ num = atoi(buf);
+ if (num >= buf_size) {
+ buf_size = num + FLATFILE_BLOCK_SIZE;
+ buf = erealloc(buf, buf_size);
+ }
+ num = php_stream_read(dba->fp, buf, num);
+ if (num < 0) {
+ break;
+ }
+ }
+ efree(buf);
+ res.dptr = NULL;
+ res.dsize = 0;
+ return res;
+}
+/* }}} */
+
+/* {{{ flatfile_nextkey
+ */
+datum flatfile_nextkey(flatfile *dba TSRMLS_DC) {
+ datum res;
+ size_t num;
+ size_t buf_size = FLATFILE_BLOCK_SIZE;
+ char *buf = emalloc(buf_size);
+
+ php_stream_seek(dba->fp, dba->CurrentFlatFilePos, SEEK_SET);
+ while(!php_stream_eof(dba->fp)) {
+ if (!php_stream_gets(dba->fp, buf, 15)) {
+ break;
+ }
+ num = atoi(buf);
+ if (num >= buf_size) {
+ buf_size = num + FLATFILE_BLOCK_SIZE;
+ buf = erealloc(buf, buf_size);
+ }
+ num = php_stream_read(dba->fp, buf, num);
+ if (num < 0) {
+ break;
+ }
+ if (!php_stream_gets(dba->fp, buf, 15)) {
+ break;
+ }
+ num = atoi(buf);
+ if (num >= buf_size) {
+ buf_size = num + FLATFILE_BLOCK_SIZE;
+ buf = erealloc(buf, buf_size);
+ }
+ num = php_stream_read(dba->fp, buf, num);
+ if (num < 0) {
+ break;
+ }
+ if (*(buf)!=0) {
+ dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
+ res.dptr = buf;
+ res.dsize = num;
+ return res;
+ }
+ }
+ efree(buf);
+ res.dptr = NULL;
+ res.dsize = 0;
+ return res;
+}
+/* }}} */
+
+/* {{{ flatfile_version */
+char *flatfile_version()
+{
+ return "1.0, $Id: 6ce2f616c81b8404a2b4143c0be5cadeaa0d4742 $";
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */
diff --git a/ext/dba/libflatfile/flatfile.h b/ext/dba/libflatfile/flatfile.h
new file mode 100644
index 0000000..b8fbedd
--- /dev/null
+++ b/ext/dba/libflatfile/flatfile.h
@@ -0,0 +1,48 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.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 |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Marcus Boerger <helly@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifndef PHP_LIB_FLATFILE_H
+#define PHP_LIB_FLATFILE_H
+
+typedef struct {
+ char *dptr;
+ size_t dsize;
+} datum;
+
+typedef struct {
+ char *lockfn;
+ int lockfd;
+ php_stream *fp;
+ size_t CurrentFlatFilePos;
+ datum nextkey;
+} flatfile;
+
+#define FLATFILE_INSERT 1
+#define FLATFILE_REPLACE 0
+
+int flatfile_store(flatfile *dba, datum key_datum, datum value_datum, int mode TSRMLS_DC);
+datum flatfile_fetch(flatfile *dba, datum key_datum TSRMLS_DC);
+int flatfile_delete(flatfile *dba, datum key_datum TSRMLS_DC);
+int flatfile_findkey(flatfile *dba, datum key_datum TSRMLS_DC);
+datum flatfile_firstkey(flatfile *dba TSRMLS_DC);
+datum flatfile_nextkey(flatfile *dba TSRMLS_DC);
+char *flatfile_version();
+
+#endif