1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
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 272374 2008-12-31 11:17:49Z sebastian $ */
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 : */
51 58 : int flatfile_store(flatfile *dba, datum key_datum, datum value_datum, int mode TSRMLS_DC) {
52 58 : if (mode == FLATFILE_INSERT) {
53 48 : if (flatfile_findkey(dba, key_datum TSRMLS_CC)) {
54 4 : return 1;
55 : }
56 44 : php_stream_seek(dba->fp, 0L, SEEK_END);
57 44 : php_stream_printf(dba->fp TSRMLS_CC, "%d\n", key_datum.dsize);
58 44 : php_stream_flush(dba->fp);
59 44 : if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) {
60 0 : return -1;
61 : }
62 44 : php_stream_printf(dba->fp TSRMLS_CC, "%d\n", value_datum.dsize);
63 44 : php_stream_flush(dba->fp);
64 44 : if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) {
65 0 : return -1;
66 : }
67 : } else { /* FLATFILE_REPLACE */
68 10 : flatfile_delete(dba, key_datum TSRMLS_CC);
69 10 : php_stream_printf(dba->fp TSRMLS_CC, "%d\n", key_datum.dsize);
70 10 : php_stream_flush(dba->fp);
71 10 : if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) {
72 0 : return -1;
73 : }
74 10 : php_stream_printf(dba->fp TSRMLS_CC, "%d\n", value_datum.dsize);
75 10 : if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) {
76 0 : return -1;
77 : }
78 : }
79 :
80 54 : php_stream_flush(dba->fp);
81 54 : return 0;
82 : }
83 : /* }}} */
84 :
85 : /* {{{ flatfile_fetch
86 : */
87 68 : datum flatfile_fetch(flatfile *dba, datum key_datum TSRMLS_DC) {
88 68 : datum value_datum = {NULL, 0};
89 : char buf[16];
90 :
91 68 : if (flatfile_findkey(dba, key_datum TSRMLS_CC)) {
92 58 : if (php_stream_gets(dba->fp, buf, sizeof(buf))) {
93 58 : value_datum.dsize = atoi(buf);
94 58 : value_datum.dptr = safe_emalloc(value_datum.dsize, 1, 1);
95 58 : value_datum.dsize = php_stream_read(dba->fp, value_datum.dptr, value_datum.dsize);
96 : } else {
97 0 : value_datum.dptr = NULL;
98 0 : value_datum.dsize = 0;
99 : }
100 : }
101 68 : return value_datum;
102 : }
103 : /* }}} */
104 :
105 : /* {{{ flatfile_delete
106 : */
107 24 : int flatfile_delete(flatfile *dba, datum key_datum TSRMLS_DC) {
108 24 : char *key = key_datum.dptr;
109 24 : size_t size = key_datum.dsize;
110 24 : size_t buf_size = FLATFILE_BLOCK_SIZE;
111 24 : char *buf = emalloc(buf_size);
112 : size_t num;
113 : size_t pos;
114 :
115 24 : php_stream_rewind(dba->fp);
116 94 : while(!php_stream_eof(dba->fp)) {
117 : /* read in the length of the key name */
118 70 : if (!php_stream_gets(dba->fp, buf, 15)) {
119 0 : break;
120 : }
121 70 : num = atoi(buf);
122 70 : if (num >= buf_size) {
123 0 : buf_size = num + FLATFILE_BLOCK_SIZE;
124 0 : buf = erealloc(buf, buf_size);
125 : }
126 70 : pos = php_stream_tell(dba->fp);
127 :
128 : /* read in the key name */
129 70 : num = php_stream_read(dba->fp, buf, num);
130 : if (num < 0) {
131 : break;
132 : }
133 :
134 70 : if (size == num && !memcmp(buf, key, size)) {
135 24 : php_stream_seek(dba->fp, pos, SEEK_SET);
136 24 : php_stream_putc(dba->fp, 0);
137 24 : php_stream_flush(dba->fp);
138 24 : php_stream_seek(dba->fp, 0L, SEEK_END);
139 24 : efree(buf);
140 24 : return SUCCESS;
141 : }
142 :
143 : /* read in the length of the value */
144 46 : if (!php_stream_gets(dba->fp, buf, 15)) {
145 0 : break;
146 : }
147 46 : num = atoi(buf);
148 46 : if (num >= buf_size) {
149 0 : buf_size = num + FLATFILE_BLOCK_SIZE;
150 0 : buf = erealloc(buf, buf_size);
151 : }
152 : /* read in the value */
153 46 : num = php_stream_read(dba->fp, buf, num);
154 : if (num < 0) {
155 : break;
156 : }
157 : }
158 0 : efree(buf);
159 0 : return FAILURE;
160 : }
161 : /* }}} */
162 :
163 : /* {{{ flatfile_findkey
164 : */
165 116 : int flatfile_findkey(flatfile *dba, datum key_datum TSRMLS_DC) {
166 116 : size_t buf_size = FLATFILE_BLOCK_SIZE;
167 116 : char *buf = emalloc(buf_size);
168 : size_t num;
169 116 : int ret=0;
170 116 : void *key = key_datum.dptr;
171 116 : size_t size = key_datum.dsize;
172 :
173 116 : php_stream_rewind(dba->fp);
174 601 : while (!php_stream_eof(dba->fp)) {
175 485 : if (!php_stream_gets(dba->fp, buf, 15)) {
176 54 : break;
177 : }
178 431 : num = atoi(buf);
179 431 : if (num >= buf_size) {
180 0 : buf_size = num + FLATFILE_BLOCK_SIZE;
181 0 : buf = erealloc(buf, buf_size);
182 : }
183 431 : num = php_stream_read(dba->fp, buf, num);
184 : if (num < 0) {
185 : break;
186 : }
187 431 : if (size == num) {
188 327 : if (!memcmp(buf, key, size)) {
189 62 : ret = 1;
190 62 : break;
191 : }
192 : }
193 369 : if (!php_stream_gets(dba->fp, buf, 15)) {
194 0 : break;
195 : }
196 369 : num = atoi(buf);
197 369 : if (num >= buf_size) {
198 0 : buf_size = num + FLATFILE_BLOCK_SIZE;
199 0 : buf = erealloc(buf, buf_size);
200 : }
201 369 : num = php_stream_read(dba->fp, buf, num);
202 : if (num < 0) {
203 : break;
204 : }
205 : }
206 116 : efree(buf);
207 116 : return ret;
208 : }
209 : /* }}} */
210 :
211 : /* {{{ flatfile_firstkey
212 : */
213 10 : datum flatfile_firstkey(flatfile *dba TSRMLS_DC) {
214 : datum res;
215 : size_t num;
216 10 : size_t buf_size = FLATFILE_BLOCK_SIZE;
217 10 : char *buf = emalloc(buf_size);
218 :
219 10 : php_stream_rewind(dba->fp);
220 41 : while(!php_stream_eof(dba->fp)) {
221 31 : if (!php_stream_gets(dba->fp, buf, 15)) {
222 0 : break;
223 : }
224 31 : num = atoi(buf);
225 31 : if (num >= buf_size) {
226 0 : buf_size = num + FLATFILE_BLOCK_SIZE;
227 0 : buf = erealloc(buf, buf_size);
228 : }
229 31 : num = php_stream_read(dba->fp, buf, num);
230 : if (num < 0) {
231 : break;
232 : }
233 31 : if (*(buf) != 0) {
234 10 : dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
235 10 : res.dptr = buf;
236 10 : res.dsize = num;
237 10 : return res;
238 : }
239 21 : if (!php_stream_gets(dba->fp, buf, 15)) {
240 0 : break;
241 : }
242 21 : num = atoi(buf);
243 21 : if (num >= buf_size) {
244 0 : buf_size = num + FLATFILE_BLOCK_SIZE;
245 0 : buf = erealloc(buf, buf_size);
246 : }
247 21 : num = php_stream_read(dba->fp, buf, num);
248 : if (num < 0) {
249 : break;
250 : }
251 : }
252 0 : efree(buf);
253 0 : res.dptr = NULL;
254 0 : res.dsize = 0;
255 0 : return res;
256 : }
257 : /* }}} */
258 :
259 : /* {{{ flatfile_nextkey
260 : */
261 32 : datum flatfile_nextkey(flatfile *dba TSRMLS_DC) {
262 : datum res;
263 : size_t num;
264 32 : size_t buf_size = FLATFILE_BLOCK_SIZE;
265 32 : char *buf = emalloc(buf_size);
266 :
267 32 : php_stream_seek(dba->fp, dba->CurrentFlatFilePos, SEEK_SET);
268 32 : while(!php_stream_eof(dba->fp)) {
269 41 : if (!php_stream_gets(dba->fp, buf, 15)) {
270 0 : break;
271 : }
272 41 : num = atoi(buf);
273 41 : if (num >= buf_size) {
274 0 : buf_size = num + FLATFILE_BLOCK_SIZE;
275 0 : buf = erealloc(buf, buf_size);
276 : }
277 41 : num = php_stream_read(dba->fp, buf, num);
278 : if (num < 0) {
279 : break;
280 : }
281 41 : if (!php_stream_gets(dba->fp, buf, 15)) {
282 10 : break;
283 : }
284 31 : num = atoi(buf);
285 31 : if (num >= buf_size) {
286 0 : buf_size = num + FLATFILE_BLOCK_SIZE;
287 0 : buf = erealloc(buf, buf_size);
288 : }
289 31 : num = php_stream_read(dba->fp, buf, num);
290 : if (num < 0) {
291 : break;
292 : }
293 31 : if (*(buf)!=0) {
294 22 : dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
295 22 : res.dptr = buf;
296 22 : res.dsize = num;
297 22 : return res;
298 : }
299 : }
300 10 : efree(buf);
301 10 : res.dptr = NULL;
302 10 : res.dsize = 0;
303 10 : return res;
304 : }
305 : /* }}} */
306 :
307 : /* {{{ flatfile_version */
308 : char *flatfile_version()
309 0 : {
310 0 : return "1.0, $Revision: 272374 $";
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 : */
|