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