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