xref: /PHP-5.3/ext/dba/libflatfile/flatfile.c (revision a2045ff3)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 5                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2013 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: Marcus Boerger <helly@php.net>                              |
16    | based on ext/db/db.c by:                                             |
17    |          Rasmus Lerdorf <rasmus@php.net>                             |
18    |          Jim Winstead <jimw@php.net>                                 |
19    +----------------------------------------------------------------------+
20  */
21 
22 /* $Id: e33fd9ea7039be4aec7f2b7ec0f0e24da46e4c55 $ */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #include "php.h"
29 #include "php_globals.h"
30 #include "safe_mode.h"
31 
32 #include <stdlib.h>
33 #include <string.h>
34 #include <errno.h>
35 #if HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38 
39 #include "flatfile.h"
40 
41 #define FLATFILE_BLOCK_SIZE 1024
42 
43 /*
44  * ret = -1 means that database was opened for read-only
45  * ret = 0  success
46  * ret = 1  key already exists - nothing done
47  */
48 
49 /* {{{ flatfile_store
50  */
flatfile_store(flatfile * dba,datum key_datum,datum value_datum,int mode TSRMLS_DC)51 int flatfile_store(flatfile *dba, datum key_datum, datum value_datum, int mode TSRMLS_DC) {
52 	if (mode == FLATFILE_INSERT) {
53 		if (flatfile_findkey(dba, key_datum TSRMLS_CC)) {
54 			return 1;
55 		}
56 		php_stream_seek(dba->fp, 0L, SEEK_END);
57 		php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", key_datum.dsize);
58 		php_stream_flush(dba->fp);
59 		if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) {
60 			return -1;
61 		}
62 		php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", value_datum.dsize);
63 		php_stream_flush(dba->fp);
64 		if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) {
65 			return -1;
66 		}
67 	} else { /* FLATFILE_REPLACE */
68 		flatfile_delete(dba, key_datum TSRMLS_CC);
69 		php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", key_datum.dsize);
70 		php_stream_flush(dba->fp);
71 		if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) {
72 			return -1;
73 		}
74 		php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", value_datum.dsize);
75 		if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) {
76 			return -1;
77 		}
78 	}
79 
80 	php_stream_flush(dba->fp);
81 	return 0;
82 }
83 /* }}} */
84 
85 /* {{{ flatfile_fetch
86  */
flatfile_fetch(flatfile * dba,datum key_datum TSRMLS_DC)87 datum flatfile_fetch(flatfile *dba, datum key_datum TSRMLS_DC) {
88 	datum value_datum = {NULL, 0};
89 	char buf[16];
90 
91 	if (flatfile_findkey(dba, key_datum TSRMLS_CC)) {
92 		if (php_stream_gets(dba->fp, buf, sizeof(buf))) {
93 			value_datum.dsize = atoi(buf);
94 			value_datum.dptr = safe_emalloc(value_datum.dsize, 1, 1);
95 			value_datum.dsize = php_stream_read(dba->fp, value_datum.dptr, value_datum.dsize);
96 		} else {
97 			value_datum.dptr = NULL;
98 			value_datum.dsize = 0;
99 		}
100 	}
101 	return value_datum;
102 }
103 /* }}} */
104 
105 /* {{{ flatfile_delete
106  */
flatfile_delete(flatfile * dba,datum key_datum TSRMLS_DC)107 int flatfile_delete(flatfile *dba, datum key_datum TSRMLS_DC) {
108 	char *key = key_datum.dptr;
109 	size_t size = key_datum.dsize;
110 	size_t buf_size = FLATFILE_BLOCK_SIZE;
111 	char *buf = emalloc(buf_size);
112 	size_t num;
113 	size_t pos;
114 
115 	php_stream_rewind(dba->fp);
116 	while(!php_stream_eof(dba->fp)) {
117 		/* read in the length of the key name */
118 		if (!php_stream_gets(dba->fp, buf, 15)) {
119 			break;
120 		}
121 		num = atoi(buf);
122 		if (num >= buf_size) {
123 			buf_size = num + FLATFILE_BLOCK_SIZE;
124 			buf = erealloc(buf, buf_size);
125 		}
126 		pos = php_stream_tell(dba->fp);
127 
128 		/* read in the key name */
129 		num = php_stream_read(dba->fp, buf, num);
130 		if (num < 0)  {
131 			break;
132 		}
133 
134 		if (size == num && !memcmp(buf, key, size)) {
135 			php_stream_seek(dba->fp, pos, SEEK_SET);
136 			php_stream_putc(dba->fp, 0);
137 			php_stream_flush(dba->fp);
138 			php_stream_seek(dba->fp, 0L, SEEK_END);
139 			efree(buf);
140 			return SUCCESS;
141 		}
142 
143 		/* read in the length of the value */
144 		if (!php_stream_gets(dba->fp, buf, 15)) {
145 			break;
146 		}
147 		num = atoi(buf);
148 		if (num >= buf_size) {
149 			buf_size = num + FLATFILE_BLOCK_SIZE;
150 			buf = erealloc(buf, buf_size);
151 		}
152 		/* read in the value */
153 		num = php_stream_read(dba->fp, buf, num);
154 		if (num < 0) {
155 			break;
156 		}
157 	}
158 	efree(buf);
159 	return FAILURE;
160 }
161 /* }}} */
162 
163 /* {{{ flatfile_findkey
164  */
flatfile_findkey(flatfile * dba,datum key_datum TSRMLS_DC)165 int flatfile_findkey(flatfile *dba, datum key_datum TSRMLS_DC) {
166 	size_t buf_size = FLATFILE_BLOCK_SIZE;
167 	char *buf = emalloc(buf_size);
168 	size_t num;
169 	int ret=0;
170 	void *key = key_datum.dptr;
171 	size_t size = key_datum.dsize;
172 
173 	php_stream_rewind(dba->fp);
174 	while (!php_stream_eof(dba->fp)) {
175 		if (!php_stream_gets(dba->fp, buf, 15)) {
176 			break;
177 		}
178 		num = atoi(buf);
179 		if (num >= buf_size) {
180 			buf_size = num + FLATFILE_BLOCK_SIZE;
181 			buf = erealloc(buf, buf_size);
182 		}
183 		num = php_stream_read(dba->fp, buf, num);
184 		if (num < 0) {
185 			break;
186 		}
187 		if (size == num) {
188 			if (!memcmp(buf, key, size)) {
189 				ret = 1;
190 				break;
191 			}
192 		}
193 		if (!php_stream_gets(dba->fp, buf, 15)) {
194 			break;
195 		}
196 		num = atoi(buf);
197 		if (num >= buf_size) {
198 			buf_size = num + FLATFILE_BLOCK_SIZE;
199 			buf = erealloc(buf, buf_size);
200 		}
201 		num = php_stream_read(dba->fp, buf, num);
202 		if (num < 0) {
203 			break;
204 		}
205 	}
206 	efree(buf);
207 	return ret;
208 }
209 /* }}} */
210 
211 /* {{{ flatfile_firstkey
212  */
flatfile_firstkey(flatfile * dba TSRMLS_DC)213 datum flatfile_firstkey(flatfile *dba TSRMLS_DC) {
214 	datum res;
215 	size_t num;
216 	size_t buf_size = FLATFILE_BLOCK_SIZE;
217 	char *buf = emalloc(buf_size);
218 
219 	php_stream_rewind(dba->fp);
220 	while(!php_stream_eof(dba->fp)) {
221 		if (!php_stream_gets(dba->fp, buf, 15)) {
222 			break;
223 		}
224 		num = atoi(buf);
225 		if (num >= buf_size) {
226 			buf_size = num + FLATFILE_BLOCK_SIZE;
227 			buf = erealloc(buf, buf_size);
228 		}
229 		num = php_stream_read(dba->fp, buf, num);
230 		if (num < 0) {
231 			break;
232 		}
233 		if (*(buf) != 0) {
234 			dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
235 			res.dptr = buf;
236 			res.dsize = num;
237 			return res;
238 		}
239 		if (!php_stream_gets(dba->fp, buf, 15)) {
240 			break;
241 		}
242 		num = atoi(buf);
243 		if (num >= buf_size) {
244 			buf_size = num + FLATFILE_BLOCK_SIZE;
245 			buf = erealloc(buf, buf_size);
246 		}
247 		num = php_stream_read(dba->fp, buf, num);
248 		if (num < 0) {
249 			break;
250 		}
251 	}
252 	efree(buf);
253 	res.dptr = NULL;
254 	res.dsize = 0;
255 	return res;
256 }
257 /* }}} */
258 
259 /* {{{ flatfile_nextkey
260  */
flatfile_nextkey(flatfile * dba TSRMLS_DC)261 datum flatfile_nextkey(flatfile *dba TSRMLS_DC) {
262 	datum res;
263 	size_t num;
264 	size_t buf_size = FLATFILE_BLOCK_SIZE;
265 	char *buf = emalloc(buf_size);
266 
267 	php_stream_seek(dba->fp, dba->CurrentFlatFilePos, SEEK_SET);
268 	while(!php_stream_eof(dba->fp)) {
269 		if (!php_stream_gets(dba->fp, buf, 15)) {
270 			break;
271 		}
272 		num = atoi(buf);
273 		if (num >= buf_size) {
274 			buf_size = num + FLATFILE_BLOCK_SIZE;
275 			buf = erealloc(buf, buf_size);
276 		}
277 		num = php_stream_read(dba->fp, buf, num);
278 		if (num < 0)  {
279 			break;
280 		}
281 		if (!php_stream_gets(dba->fp, buf, 15)) {
282 			break;
283 		}
284 		num = atoi(buf);
285 		if (num >= buf_size) {
286 			buf_size = num + FLATFILE_BLOCK_SIZE;
287 			buf = erealloc(buf, buf_size);
288 		}
289 		num = php_stream_read(dba->fp, buf, num);
290 		if (num < 0) {
291 			break;
292 		}
293 		if (*(buf)!=0) {
294 			dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
295 			res.dptr = buf;
296 			res.dsize = num;
297 			return res;
298 		}
299 	}
300 	efree(buf);
301 	res.dptr = NULL;
302 	res.dsize = 0;
303 	return res;
304 }
305 /* }}} */
306 
307 /* {{{ flatfile_version */
flatfile_version()308 char *flatfile_version()
309 {
310 	return "1.0, $Id: e33fd9ea7039be4aec7f2b7ec0f0e24da46e4c55 $";
311 }
312 /* }}} */
313 
314 /*
315  * Local variables:
316  * tab-width: 4
317  * c-basic-offset: 4
318  * End:
319  * vim600: sw=4 ts=4 fdm=marker
320  * vim<600: sw=4 ts=4
321  */
322