php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
dba_cdb.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Sascha Schumann <sascha@schumann.cx> |
14 | Marcus Boerger <helly@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18#ifdef HAVE_CONFIG_H
19#include <config.h>
20#endif
21
22#include "php.h"
23
24#ifdef DBA_CDB
25#include "php_cdb.h"
26
27#include <sys/types.h>
28#ifdef HAVE_UNISTD_H
29#include <unistd.h>
30#endif
31#include <fcntl.h>
32
33#ifdef DBA_CDB_BUILTIN
34# include "libcdb/cdb.h"
35# include "libcdb/cdb_make.h"
36# include "libcdb/uint32.h"
37#else
38# ifdef CDB_INCLUDE_FILE
39# include CDB_INCLUDE_FILE
40# endif
41#endif
42
43#define CDB_INFO \
44 dba_cdb *cdb = (dba_cdb *) info->dbf
45
46typedef struct {
47 struct cdb c;
48#ifdef DBA_CDB_BUILTIN
49 struct cdb_make m;
51 int make;
52#else
53 int file;
54#endif
55 uint32 eod; /* size of constant database */
56 uint32 pos; /* current position for traversing */
57} dba_cdb;
58
59DBA_OPEN_FUNC(cdb)
60{
61#ifdef DBA_CDB_BUILTIN
62 php_stream* file = 0;
63 int make;
64#else
65 int file = 0;
66#endif
67 dba_cdb *cdb;
68 dba_info *pinfo = (dba_info *) info;
69
70 switch (info->mode) {
71 case DBA_READER:
72#ifdef DBA_CDB_BUILTIN
73 make = 0;
74 file = info->fp;
75#else
76 file = VCWD_OPEN(ZSTR_VAL(info->path), O_RDONLY);
77 if (file < 0) {
78 *error = "Unable to open file";
79 return FAILURE;
80 }
81#endif
82 break;
83#ifdef DBA_CDB_BUILTIN
84 case DBA_TRUNC:
85 make = 1;
86 file = info->fp;
87 break;
88 case DBA_CREAT:
89 case DBA_WRITER:
90 *error = "Update operations are not supported";
91 return FAILURE; /* not supported */
92#endif
93 default:
94 *error = "Currently not supported";
95 return FAILURE;
96 }
97
98 cdb = pemalloc(sizeof(dba_cdb), info->flags&DBA_PERSISTENT);
99 memset(cdb, 0, sizeof(dba_cdb));
100
101#ifdef DBA_CDB_BUILTIN
102 if (make) {
103 cdb_make_start(&cdb->m, file);
104 } else {
105 cdb_init(&cdb->c, file);
106 }
107 cdb->make = make;
108#else
109 cdb_init(&cdb->c, file);
110#endif
111 cdb->file = file;
112
113 pinfo->dbf = cdb;
114 return SUCCESS;
115}
116
117DBA_CLOSE_FUNC(cdb)
118{
119 CDB_INFO;
120
121 /* cdb_free does not close associated file */
122#ifdef DBA_CDB_BUILTIN
123 if (cdb->make) {
124 cdb_make_finish(&cdb->m);
125 } else {
126 cdb_free(&cdb->c);
127 }
128#else
129 cdb_free(&cdb->c);
130 close(cdb->file);
131#endif
132 pefree(cdb, info->flags&DBA_PERSISTENT);
133}
134
135#ifdef DBA_CDB_BUILTIN
136# define php_cdb_read(cdb, buf, len, pos) cdb_read(cdb, buf, len, pos)
137# define php_cdb_findnext(cdb, key, len) cdb_findnext(cdb, key, len)
138# define php_cdb_find(cdb, key, len) cdb_find(cdb, key, len)
139#else
140# define php_cdb_read(cdb, buf, len, pos) cdb_read(cdb, buf, len, pos)
141# define php_cdb_findnext(cdb, key, len) cdb_findnext(cdb, key, len)
142# define php_cdb_find(cdb, key, len) cdb_find(cdb, key, len)
143#endif
144
145DBA_FETCH_FUNC(cdb)
146{
147 CDB_INFO;
148 zend_string *fetched_val = NULL;
149 unsigned int len;
150
151#ifdef DBA_CDB_BUILTIN
152 if (cdb->make)
153 return NULL; /* database was opened writeonly */
154#endif
155 if (php_cdb_find(&cdb->c, ZSTR_VAL(key), ZSTR_LEN(key)) == 1) {
156 while(skip--) {
157 if (php_cdb_findnext(&cdb->c, ZSTR_VAL(key), ZSTR_LEN(key)) != 1) {
158 return NULL;
159 }
160 }
161 len = cdb_datalen(&cdb->c);
162 fetched_val = zend_string_alloc(len, /* persistent */ false);
163
164 if (php_cdb_read(&cdb->c, ZSTR_VAL(fetched_val), len, cdb_datapos(&cdb->c)) == -1) {
165 zend_string_release_ex(fetched_val, /* persistent */ false);
166 return NULL;
167 }
168 ZSTR_VAL(fetched_val)[len] = 0;
169 }
170
171 return fetched_val;
172}
173
174DBA_UPDATE_FUNC(cdb)
175{
176#ifdef DBA_CDB_BUILTIN
177 CDB_INFO;
178
179 if (!cdb->make)
180 return FAILURE; /* database was opened readonly */
181 if (!mode)
182 return FAILURE; /* cdb_make doesn't know replace */
184 return SUCCESS;
185#endif
186 return FAILURE;
187}
188
189DBA_EXISTS_FUNC(cdb)
190{
191 CDB_INFO;
192
193#ifdef DBA_CDB_BUILTIN
194 if (cdb->make)
195 return FAILURE; /* database was opened writeonly */
196#endif
197 if (php_cdb_find(&cdb->c, ZSTR_VAL(key), ZSTR_LEN(key)) == 1)
198 return SUCCESS;
199 return FAILURE;
200}
201
202DBA_DELETE_FUNC(cdb)
203{
204 return FAILURE; /* cdb doesn't support delete */
205}
206
207/* {{{ cdb_file_read */
208#ifdef DBA_CDB_BUILTIN
209# define cdb_file_read(fildes, buf, size) php_stream_read(fildes, buf, size)
210#else
211# define cdb_file_read(fildes, buf, size) read(fildes, buf, size)
212#endif
213/* }}} */
214
215#define CREAD(n) do { \
216 if (cdb_file_read(cdb->file, buf, n) < n) return NULL; \
217} while (0)
218
219/* {{{ cdb_file_lseek
220 php_stream_seek does not return actual position */
221#ifdef DBA_CDB_BUILTIN
222zend_off_t cdb_file_lseek(php_stream *fp, zend_off_t offset, int whence) {
223 php_stream_seek(fp, offset, whence);
224 return php_stream_tell(fp);
225}
226#else
227zend_off_t cdb_file_lseek(int fd, zend_off_t offset, int whence) {
228 return lseek(fd, offset, whence);
229}
230#endif
231/* }}} */
232
233#define CSEEK(n) do { \
234 if (n >= cdb->eod) return NULL; \
235 if (cdb_file_lseek(cdb->file, (zend_off_t)n, SEEK_SET) != (zend_off_t) n) return NULL; \
236} while (0)
237
238
239DBA_FIRSTKEY_FUNC(cdb)
240{
241 CDB_INFO;
242 uint32 klen, dlen;
243 char buf[8];
245
246#ifdef DBA_CDB_BUILTIN
247 if (cdb->make)
248 return NULL; /* database was opened writeonly */
249#endif
250
251 cdb->eod = -1;
252 CSEEK(0);
253 CREAD(4);
254
255 /* Total length of file in bytes */
256 uint32_unpack(buf, &cdb->eod);
257
258 CSEEK(2048);
259 CREAD(8);
260
261 /* The first four bytes contain the length of the key */
262 uint32_unpack(buf, &klen);
263 uint32_unpack(buf + 4, &dlen);
264
265 key = zend_string_alloc(klen, /* persistent */ false);
266 if (cdb_file_read(cdb->file, ZSTR_VAL(key), klen) < klen) {
267 zend_string_release_ex(key, /* persistent */ false);
268 key = NULL;
269 } else {
270 ZSTR_VAL(key)[klen] = 0;
271 }
272
273 /* header + klenlen + dlenlen + klen + dlen */
274 cdb->pos = 2048 + 4 + 4 + klen + dlen;
275
276 return key;
277}
278
279DBA_NEXTKEY_FUNC(cdb)
280{
281 CDB_INFO;
282 uint32 klen, dlen;
283 char buf[8];
285
286#ifdef DBA_CDB_BUILTIN
287 if (cdb->make)
288 return NULL; /* database was opened writeonly */
289#endif
290
291 CSEEK(cdb->pos);
292 CREAD(8);
293 uint32_unpack(buf, &klen);
294 uint32_unpack(buf + 4, &dlen);
295
296 key = zend_string_alloc(klen, /* persistent */ false);
297 if (cdb_file_read(cdb->file, ZSTR_VAL(key), klen) < klen) {
298 zend_string_release_ex(key, /* persistent */ false);
299 key = NULL;
300 } else {
301 ZSTR_VAL(key)[klen] = 0;
302 }
303
304 cdb->pos += 8 + klen + dlen;
305
306 return key;
307}
308
309DBA_OPTIMIZE_FUNC(cdb)
310{
311 return SUCCESS;
312}
313
314DBA_SYNC_FUNC(cdb)
315{
316 /* this is read-only */
317 return SUCCESS;
318}
319
320DBA_INFO_FUNC(cdb)
321{
322#ifdef DBA_CDB_BUILTIN
323 if (!strcmp(hnd->name, "cdb")) {
324 return estrdup(cdb_version());
325 } else {
326 return estrdup(cdb_make_version());
327 }
328#else
329 return estrdup("External");
330#endif
331}
332
333#endif
size_t len
Definition apprentice.c:174
file(string $filename, int $flags=0, $context=null)
void cdb_init(struct cdb *c, php_stream *fp)
Definition cdb.c:93
void cdb_free(struct cdb *c)
Definition cdb.c:80
const char * cdb_version(void)
Definition cdb.c:188
#define cdb_datalen(c)
Definition cdb.h:49
#define cdb_datapos(c)
Definition cdb.h:48
const char * cdb_make_version(void)
Definition cdb_make.c:239
int cdb_make_finish(struct cdb_make *c)
Definition cdb_make.c:136
int cdb_make_start(struct cdb_make *c, php_stream *f)
Definition cdb_make.c:57
int cdb_make_add(struct cdb_make *c, char *key, unsigned int keylen, char *data, unsigned int datalen)
Definition cdb_make.c:123
error($message)
Definition ext_skel.php:22
memset(ptr, 0, type->size)
zval * val
Definition ffi.c:4262
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
zend_long offset
char * mode
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
#define uint32
Definition lsapilib.c:92
unsigned const char * pos
Definition php_ffi.h:52
unsigned char key[REFLECTION_KEY_LEN]
struct _php_stream php_stream
Definition php_streams.h:96
#define php_stream_seek(stream, offset, whence)
#define php_stream_tell(stream)
int fd
Definition phpdbg.h:282
php_stream * fp
Definition cdb_make.h:50
Definition cdb.h:26
void uint32_unpack(const char *in, uint32 *out)
Definition uint32.c:38
#define close(a)
#define estrdup(s)
Definition zend_alloc.h:164
#define pefree(ptr, persistent)
Definition zend_alloc.h:191
#define pemalloc(size, persistent)
Definition zend_alloc.h:189
strcmp(string $string1, string $string2)
zend_string_release_ex(func->internal_function.function_name, 0)
int32_t zend_off_t
Definition zend_long.h:44
struct _zend_string zend_string
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
@ FAILURE
Definition zend_types.h:61
#define VCWD_OPEN(path, flags)