rubysl-sdbm 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/ext/rubysl/sdbm/_sdbm.c +929 -0
- data/ext/rubysl/sdbm/extconf.rb +4 -0
- data/ext/rubysl/sdbm/init.c +713 -0
- data/ext/rubysl/sdbm/sdbm.h +86 -0
- data/lib/rubysl/sdbm.rb +2 -0
- data/lib/rubysl/sdbm/version.rb +5 -0
- data/lib/sdbm.rb +1 -0
- data/rubysl-sdbm.gemspec +23 -0
- metadata +101 -0
@@ -0,0 +1,713 @@
|
|
1
|
+
/************************************************
|
2
|
+
|
3
|
+
sdbminit.c -
|
4
|
+
|
5
|
+
$Author$
|
6
|
+
created at: Fri May 7 08:34:24 JST 1999
|
7
|
+
|
8
|
+
Copyright (C) 1995-2001 Yukihiro Matsumoto
|
9
|
+
|
10
|
+
************************************************/
|
11
|
+
|
12
|
+
#include "ruby.h"
|
13
|
+
|
14
|
+
#include "sdbm.h"
|
15
|
+
#include <fcntl.h>
|
16
|
+
#include <errno.h>
|
17
|
+
|
18
|
+
static VALUE rb_cDBM, rb_eDBMError;
|
19
|
+
|
20
|
+
struct dbmdata {
|
21
|
+
int di_size;
|
22
|
+
DBM *di_dbm;
|
23
|
+
};
|
24
|
+
|
25
|
+
static void
|
26
|
+
closed_sdbm()
|
27
|
+
{
|
28
|
+
rb_raise(rb_eDBMError, "closed SDBM file");
|
29
|
+
}
|
30
|
+
|
31
|
+
#define GetDBM(obj, dbmp) {\
|
32
|
+
Data_Get_Struct((obj), struct dbmdata, (dbmp));\
|
33
|
+
if ((dbmp) == 0) closed_sdbm();\
|
34
|
+
if ((dbmp)->di_dbm == 0) closed_sdbm();\
|
35
|
+
}
|
36
|
+
|
37
|
+
#define GetDBM2(obj, data, dbm) {\
|
38
|
+
GetDBM((obj), (data));\
|
39
|
+
(dbm) = dbmp->di_dbm;\
|
40
|
+
}
|
41
|
+
|
42
|
+
static void
|
43
|
+
free_sdbm(struct dbmdata *dbmp)
|
44
|
+
{
|
45
|
+
|
46
|
+
if (dbmp->di_dbm) sdbm_close(dbmp->di_dbm);
|
47
|
+
ruby_xfree(dbmp);
|
48
|
+
}
|
49
|
+
|
50
|
+
static VALUE
|
51
|
+
fsdbm_close(VALUE obj)
|
52
|
+
{
|
53
|
+
struct dbmdata *dbmp;
|
54
|
+
|
55
|
+
GetDBM(obj, dbmp);
|
56
|
+
sdbm_close(dbmp->di_dbm);
|
57
|
+
dbmp->di_dbm = 0;
|
58
|
+
|
59
|
+
return Qnil;
|
60
|
+
}
|
61
|
+
|
62
|
+
static VALUE
|
63
|
+
fsdbm_closed(VALUE obj)
|
64
|
+
{
|
65
|
+
struct dbmdata *dbmp;
|
66
|
+
|
67
|
+
Data_Get_Struct(obj, struct dbmdata, dbmp);
|
68
|
+
if (dbmp == 0)
|
69
|
+
return Qtrue;
|
70
|
+
if (dbmp->di_dbm == 0)
|
71
|
+
return Qtrue;
|
72
|
+
|
73
|
+
return Qfalse;
|
74
|
+
}
|
75
|
+
|
76
|
+
static VALUE
|
77
|
+
fsdbm_alloc(VALUE klass)
|
78
|
+
{
|
79
|
+
return Data_Wrap_Struct(klass, 0, free_sdbm, 0);
|
80
|
+
}
|
81
|
+
|
82
|
+
static VALUE
|
83
|
+
fsdbm_initialize(int argc, VALUE *argv, VALUE obj)
|
84
|
+
{
|
85
|
+
volatile VALUE file;
|
86
|
+
VALUE vmode;
|
87
|
+
DBM *dbm;
|
88
|
+
struct dbmdata *dbmp;
|
89
|
+
int mode;
|
90
|
+
|
91
|
+
if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
|
92
|
+
mode = 0666; /* default value */
|
93
|
+
}
|
94
|
+
else if (NIL_P(vmode)) {
|
95
|
+
mode = -1; /* return nil if DB not exist */
|
96
|
+
}
|
97
|
+
else {
|
98
|
+
mode = NUM2INT(vmode);
|
99
|
+
}
|
100
|
+
FilePathValue(file);
|
101
|
+
|
102
|
+
dbm = 0;
|
103
|
+
if (mode >= 0)
|
104
|
+
dbm = sdbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT, mode);
|
105
|
+
if (!dbm)
|
106
|
+
dbm = sdbm_open(RSTRING_PTR(file), O_RDWR, 0);
|
107
|
+
if (!dbm)
|
108
|
+
dbm = sdbm_open(RSTRING_PTR(file), O_RDONLY, 0);
|
109
|
+
|
110
|
+
if (!dbm) {
|
111
|
+
if (mode == -1) return Qnil;
|
112
|
+
rb_sys_fail(RSTRING_PTR(file));
|
113
|
+
}
|
114
|
+
|
115
|
+
dbmp = ALLOC(struct dbmdata);
|
116
|
+
DATA_PTR(obj) = dbmp;
|
117
|
+
dbmp->di_dbm = dbm;
|
118
|
+
dbmp->di_size = -1;
|
119
|
+
|
120
|
+
return obj;
|
121
|
+
}
|
122
|
+
|
123
|
+
static VALUE
|
124
|
+
fsdbm_s_open(int argc, VALUE *argv, VALUE klass)
|
125
|
+
{
|
126
|
+
VALUE obj = Data_Wrap_Struct(klass, 0, free_sdbm, 0);
|
127
|
+
|
128
|
+
if (NIL_P(fsdbm_initialize(argc, argv, obj))) {
|
129
|
+
return Qnil;
|
130
|
+
}
|
131
|
+
|
132
|
+
if (rb_block_given_p()) {
|
133
|
+
return rb_ensure(rb_yield, obj, fsdbm_close, obj);
|
134
|
+
}
|
135
|
+
|
136
|
+
return obj;
|
137
|
+
}
|
138
|
+
|
139
|
+
static VALUE
|
140
|
+
fsdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
|
141
|
+
{
|
142
|
+
datum key, value;
|
143
|
+
struct dbmdata *dbmp;
|
144
|
+
DBM *dbm;
|
145
|
+
|
146
|
+
ExportStringValue(keystr);
|
147
|
+
key.dptr = RSTRING_PTR(keystr);
|
148
|
+
key.dsize = RSTRING_LENINT(keystr);
|
149
|
+
|
150
|
+
GetDBM2(obj, dbmp, dbm);
|
151
|
+
value = sdbm_fetch(dbm, key);
|
152
|
+
if (value.dptr == 0) {
|
153
|
+
if (ifnone == Qnil && rb_block_given_p())
|
154
|
+
return rb_yield(rb_external_str_new(key.dptr, key.dsize));
|
155
|
+
return ifnone;
|
156
|
+
}
|
157
|
+
return rb_external_str_new(value.dptr, value.dsize);
|
158
|
+
}
|
159
|
+
|
160
|
+
static VALUE
|
161
|
+
fsdbm_aref(VALUE obj, VALUE keystr)
|
162
|
+
{
|
163
|
+
return fsdbm_fetch(obj, keystr, Qnil);
|
164
|
+
}
|
165
|
+
|
166
|
+
static VALUE
|
167
|
+
fsdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
|
168
|
+
{
|
169
|
+
VALUE keystr, valstr, ifnone;
|
170
|
+
|
171
|
+
rb_scan_args(argc, argv, "11", &keystr, &ifnone);
|
172
|
+
valstr = fsdbm_fetch(obj, keystr, ifnone);
|
173
|
+
if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
|
174
|
+
rb_raise(rb_eIndexError, "key not found");
|
175
|
+
|
176
|
+
return valstr;
|
177
|
+
}
|
178
|
+
|
179
|
+
static VALUE
|
180
|
+
fsdbm_key(VALUE obj, VALUE valstr)
|
181
|
+
{
|
182
|
+
datum key, val;
|
183
|
+
struct dbmdata *dbmp;
|
184
|
+
DBM *dbm;
|
185
|
+
|
186
|
+
ExportStringValue(valstr);
|
187
|
+
val.dptr = RSTRING_PTR(valstr);
|
188
|
+
val.dsize = RSTRING_LENINT(valstr);
|
189
|
+
|
190
|
+
GetDBM2(obj, dbmp, dbm);
|
191
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
192
|
+
val = sdbm_fetch(dbm, key);
|
193
|
+
if (val.dsize == RSTRING_LEN(valstr) &&
|
194
|
+
memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
|
195
|
+
return rb_external_str_new(key.dptr, key.dsize);
|
196
|
+
}
|
197
|
+
return Qnil;
|
198
|
+
}
|
199
|
+
|
200
|
+
static VALUE
|
201
|
+
fsdbm_index(VALUE hash, VALUE value)
|
202
|
+
{
|
203
|
+
rb_warn("SDBM#index is deprecated; use SDBM#key");
|
204
|
+
return fsdbm_key(hash, value);
|
205
|
+
}
|
206
|
+
|
207
|
+
static VALUE
|
208
|
+
fsdbm_select(VALUE obj)
|
209
|
+
{
|
210
|
+
VALUE new = rb_ary_new();
|
211
|
+
datum key, val;
|
212
|
+
DBM *dbm;
|
213
|
+
struct dbmdata *dbmp;
|
214
|
+
|
215
|
+
GetDBM2(obj, dbmp, dbm);
|
216
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
217
|
+
VALUE assoc, v;
|
218
|
+
val = sdbm_fetch(dbm, key);
|
219
|
+
assoc = rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
|
220
|
+
rb_external_str_new(val.dptr, val.dsize));
|
221
|
+
v = rb_yield(assoc);
|
222
|
+
if (RTEST(v)) {
|
223
|
+
rb_ary_push(new, assoc);
|
224
|
+
}
|
225
|
+
GetDBM2(obj, dbmp, dbm);
|
226
|
+
}
|
227
|
+
|
228
|
+
return new;
|
229
|
+
}
|
230
|
+
|
231
|
+
static VALUE
|
232
|
+
fsdbm_values_at(int argc, VALUE *argv, VALUE obj)
|
233
|
+
{
|
234
|
+
VALUE new = rb_ary_new2(argc);
|
235
|
+
int i;
|
236
|
+
|
237
|
+
for (i=0; i<argc; i++) {
|
238
|
+
rb_ary_push(new, fsdbm_fetch(obj, argv[i], Qnil));
|
239
|
+
}
|
240
|
+
|
241
|
+
return new;
|
242
|
+
}
|
243
|
+
|
244
|
+
static void
|
245
|
+
fdbm_modify(VALUE obj)
|
246
|
+
{
|
247
|
+
rb_secure(4);
|
248
|
+
if (OBJ_FROZEN(obj)) rb_error_frozen("SDBM");
|
249
|
+
}
|
250
|
+
|
251
|
+
static VALUE
|
252
|
+
fsdbm_delete(VALUE obj, VALUE keystr)
|
253
|
+
{
|
254
|
+
datum key, value;
|
255
|
+
struct dbmdata *dbmp;
|
256
|
+
DBM *dbm;
|
257
|
+
VALUE valstr;
|
258
|
+
|
259
|
+
fdbm_modify(obj);
|
260
|
+
ExportStringValue(keystr);
|
261
|
+
key.dptr = RSTRING_PTR(keystr);
|
262
|
+
key.dsize = RSTRING_LENINT(keystr);
|
263
|
+
|
264
|
+
GetDBM2(obj, dbmp, dbm);
|
265
|
+
dbmp->di_size = -1;
|
266
|
+
|
267
|
+
value = sdbm_fetch(dbm, key);
|
268
|
+
if (value.dptr == 0) {
|
269
|
+
if (rb_block_given_p()) return rb_yield(keystr);
|
270
|
+
return Qnil;
|
271
|
+
}
|
272
|
+
|
273
|
+
/* need to save value before sdbm_delete() */
|
274
|
+
valstr = rb_external_str_new(value.dptr, value.dsize);
|
275
|
+
|
276
|
+
if (sdbm_delete(dbm, key)) {
|
277
|
+
dbmp->di_size = -1;
|
278
|
+
rb_raise(rb_eDBMError, "dbm_delete failed");
|
279
|
+
}
|
280
|
+
else if (dbmp->di_size >= 0) {
|
281
|
+
dbmp->di_size--;
|
282
|
+
}
|
283
|
+
return valstr;
|
284
|
+
}
|
285
|
+
|
286
|
+
static VALUE
|
287
|
+
fsdbm_shift(VALUE obj)
|
288
|
+
{
|
289
|
+
datum key, val;
|
290
|
+
struct dbmdata *dbmp;
|
291
|
+
DBM *dbm;
|
292
|
+
VALUE keystr, valstr;
|
293
|
+
|
294
|
+
fdbm_modify(obj);
|
295
|
+
GetDBM2(obj, dbmp, dbm);
|
296
|
+
key = sdbm_firstkey(dbm);
|
297
|
+
if (!key.dptr) return Qnil;
|
298
|
+
val = sdbm_fetch(dbm, key);
|
299
|
+
keystr = rb_external_str_new(key.dptr, key.dsize);
|
300
|
+
valstr = rb_external_str_new(val.dptr, val.dsize);
|
301
|
+
sdbm_delete(dbm, key);
|
302
|
+
if (dbmp->di_size >= 0) {
|
303
|
+
dbmp->di_size--;
|
304
|
+
}
|
305
|
+
|
306
|
+
return rb_assoc_new(keystr, valstr);
|
307
|
+
}
|
308
|
+
|
309
|
+
static VALUE
|
310
|
+
fsdbm_delete_if(VALUE obj)
|
311
|
+
{
|
312
|
+
datum key, val;
|
313
|
+
struct dbmdata *dbmp;
|
314
|
+
DBM *dbm;
|
315
|
+
VALUE keystr, valstr;
|
316
|
+
VALUE ret, ary = rb_ary_new();
|
317
|
+
int i, status = 0, n;
|
318
|
+
|
319
|
+
fdbm_modify(obj);
|
320
|
+
GetDBM2(obj, dbmp, dbm);
|
321
|
+
n = dbmp->di_size;
|
322
|
+
dbmp->di_size = -1;
|
323
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
324
|
+
val = sdbm_fetch(dbm, key);
|
325
|
+
keystr = rb_external_str_new(key.dptr, key.dsize);
|
326
|
+
valstr = rb_external_str_new(val.dptr, val.dsize);
|
327
|
+
ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
|
328
|
+
if (status != 0) break;
|
329
|
+
if (RTEST(ret)) rb_ary_push(ary, keystr);
|
330
|
+
GetDBM2(obj, dbmp, dbm);
|
331
|
+
}
|
332
|
+
|
333
|
+
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
334
|
+
keystr = rb_ary_entry(ary, i);
|
335
|
+
ExportStringValue(keystr);
|
336
|
+
key.dptr = RSTRING_PTR(keystr);
|
337
|
+
key.dsize = RSTRING_LENINT(keystr);
|
338
|
+
if (sdbm_delete(dbm, key)) {
|
339
|
+
rb_raise(rb_eDBMError, "sdbm_delete failed");
|
340
|
+
}
|
341
|
+
}
|
342
|
+
if (status) rb_jump_tag(status);
|
343
|
+
if (n > 0) dbmp->di_size = n - RARRAY_LENINT(ary);
|
344
|
+
|
345
|
+
return obj;
|
346
|
+
}
|
347
|
+
|
348
|
+
static VALUE
|
349
|
+
fsdbm_clear(VALUE obj)
|
350
|
+
{
|
351
|
+
datum key;
|
352
|
+
struct dbmdata *dbmp;
|
353
|
+
DBM *dbm;
|
354
|
+
|
355
|
+
fdbm_modify(obj);
|
356
|
+
GetDBM2(obj, dbmp, dbm);
|
357
|
+
dbmp->di_size = -1;
|
358
|
+
while (key = sdbm_firstkey(dbm), key.dptr) {
|
359
|
+
if (sdbm_delete(dbm, key)) {
|
360
|
+
rb_raise(rb_eDBMError, "sdbm_delete failed");
|
361
|
+
}
|
362
|
+
}
|
363
|
+
dbmp->di_size = 0;
|
364
|
+
|
365
|
+
return obj;
|
366
|
+
}
|
367
|
+
|
368
|
+
static VALUE
|
369
|
+
fsdbm_invert(VALUE obj)
|
370
|
+
{
|
371
|
+
datum key, val;
|
372
|
+
struct dbmdata *dbmp;
|
373
|
+
DBM *dbm;
|
374
|
+
VALUE keystr, valstr;
|
375
|
+
VALUE hash = rb_hash_new();
|
376
|
+
|
377
|
+
GetDBM2(obj, dbmp, dbm);
|
378
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
379
|
+
val = sdbm_fetch(dbm, key);
|
380
|
+
keystr = rb_external_str_new(key.dptr, key.dsize);
|
381
|
+
valstr = rb_external_str_new(val.dptr, val.dsize);
|
382
|
+
rb_hash_aset(hash, valstr, keystr);
|
383
|
+
}
|
384
|
+
return hash;
|
385
|
+
}
|
386
|
+
|
387
|
+
static VALUE
|
388
|
+
fsdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
|
389
|
+
{
|
390
|
+
datum key, val;
|
391
|
+
struct dbmdata *dbmp;
|
392
|
+
DBM *dbm;
|
393
|
+
|
394
|
+
if (valstr == Qnil) {
|
395
|
+
fsdbm_delete(obj, keystr);
|
396
|
+
return Qnil;
|
397
|
+
}
|
398
|
+
|
399
|
+
fdbm_modify(obj);
|
400
|
+
ExportStringValue(keystr);
|
401
|
+
ExportStringValue(valstr);
|
402
|
+
|
403
|
+
key.dptr = RSTRING_PTR(keystr);
|
404
|
+
key.dsize = RSTRING_LENINT(keystr);
|
405
|
+
|
406
|
+
val.dptr = RSTRING_PTR(valstr);
|
407
|
+
val.dsize = RSTRING_LENINT(valstr);
|
408
|
+
|
409
|
+
GetDBM2(obj, dbmp, dbm);
|
410
|
+
dbmp->di_size = -1;
|
411
|
+
if (sdbm_store(dbm, key, val, DBM_REPLACE)) {
|
412
|
+
#ifdef HAVE_DBM_CLAERERR
|
413
|
+
sdbm_clearerr(dbm);
|
414
|
+
#endif
|
415
|
+
if (errno == EPERM) rb_sys_fail(0);
|
416
|
+
rb_raise(rb_eDBMError, "sdbm_store failed");
|
417
|
+
}
|
418
|
+
|
419
|
+
return valstr;
|
420
|
+
}
|
421
|
+
|
422
|
+
static VALUE
|
423
|
+
update_i(VALUE pair, VALUE dbm)
|
424
|
+
{
|
425
|
+
Check_Type(pair, T_ARRAY);
|
426
|
+
if (RARRAY_LEN(pair) < 2) {
|
427
|
+
rb_raise(rb_eArgError, "pair must be [key, value]");
|
428
|
+
}
|
429
|
+
fsdbm_store(dbm, rb_ary_entry(pair, 0), rb_ary_entry(pair, 1));
|
430
|
+
return Qnil;
|
431
|
+
}
|
432
|
+
|
433
|
+
static VALUE
|
434
|
+
fsdbm_update(VALUE obj, VALUE other)
|
435
|
+
{
|
436
|
+
rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
|
437
|
+
return obj;
|
438
|
+
}
|
439
|
+
|
440
|
+
static VALUE
|
441
|
+
fsdbm_replace(VALUE obj, VALUE other)
|
442
|
+
{
|
443
|
+
fsdbm_clear(obj);
|
444
|
+
rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
|
445
|
+
return obj;
|
446
|
+
}
|
447
|
+
|
448
|
+
static VALUE
|
449
|
+
fsdbm_length(VALUE obj)
|
450
|
+
{
|
451
|
+
datum key;
|
452
|
+
struct dbmdata *dbmp;
|
453
|
+
DBM *dbm;
|
454
|
+
int i = 0;
|
455
|
+
|
456
|
+
GetDBM2(obj, dbmp, dbm);
|
457
|
+
if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
|
458
|
+
|
459
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
460
|
+
i++;
|
461
|
+
}
|
462
|
+
dbmp->di_size = i;
|
463
|
+
|
464
|
+
return INT2FIX(i);
|
465
|
+
}
|
466
|
+
|
467
|
+
static VALUE
|
468
|
+
fsdbm_empty_p(VALUE obj)
|
469
|
+
{
|
470
|
+
datum key;
|
471
|
+
struct dbmdata *dbmp;
|
472
|
+
DBM *dbm;
|
473
|
+
int i = 0;
|
474
|
+
|
475
|
+
GetDBM(obj, dbmp);
|
476
|
+
if (dbmp->di_size < 0) {
|
477
|
+
dbm = dbmp->di_dbm;
|
478
|
+
|
479
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
480
|
+
i++;
|
481
|
+
}
|
482
|
+
}
|
483
|
+
else {
|
484
|
+
i = dbmp->di_size;
|
485
|
+
}
|
486
|
+
if (i == 0) return Qtrue;
|
487
|
+
return Qfalse;
|
488
|
+
}
|
489
|
+
|
490
|
+
static VALUE
|
491
|
+
fsdbm_each_value(VALUE obj)
|
492
|
+
{
|
493
|
+
datum key, val;
|
494
|
+
struct dbmdata *dbmp;
|
495
|
+
DBM *dbm;
|
496
|
+
|
497
|
+
RETURN_ENUMERATOR(obj, 0, 0);
|
498
|
+
|
499
|
+
GetDBM2(obj, dbmp, dbm);
|
500
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
501
|
+
val = sdbm_fetch(dbm, key);
|
502
|
+
rb_yield(rb_external_str_new(val.dptr, val.dsize));
|
503
|
+
GetDBM2(obj, dbmp, dbm);
|
504
|
+
}
|
505
|
+
return obj;
|
506
|
+
}
|
507
|
+
|
508
|
+
static VALUE
|
509
|
+
fsdbm_each_key(VALUE obj)
|
510
|
+
{
|
511
|
+
datum key;
|
512
|
+
struct dbmdata *dbmp;
|
513
|
+
DBM *dbm;
|
514
|
+
|
515
|
+
RETURN_ENUMERATOR(obj, 0, 0);
|
516
|
+
|
517
|
+
GetDBM2(obj, dbmp, dbm);
|
518
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
519
|
+
rb_yield(rb_external_str_new(key.dptr, key.dsize));
|
520
|
+
GetDBM2(obj, dbmp, dbm);
|
521
|
+
}
|
522
|
+
return obj;
|
523
|
+
}
|
524
|
+
|
525
|
+
static VALUE
|
526
|
+
fsdbm_each_pair(VALUE obj)
|
527
|
+
{
|
528
|
+
datum key, val;
|
529
|
+
DBM *dbm;
|
530
|
+
struct dbmdata *dbmp;
|
531
|
+
VALUE keystr, valstr;
|
532
|
+
|
533
|
+
RETURN_ENUMERATOR(obj, 0, 0);
|
534
|
+
|
535
|
+
GetDBM2(obj, dbmp, dbm);
|
536
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
537
|
+
val = sdbm_fetch(dbm, key);
|
538
|
+
keystr = rb_external_str_new(key.dptr, key.dsize);
|
539
|
+
valstr = rb_external_str_new(val.dptr, val.dsize);
|
540
|
+
rb_yield(rb_assoc_new(keystr, valstr));
|
541
|
+
GetDBM2(obj, dbmp, dbm);
|
542
|
+
}
|
543
|
+
|
544
|
+
return obj;
|
545
|
+
}
|
546
|
+
|
547
|
+
static VALUE
|
548
|
+
fsdbm_keys(VALUE obj)
|
549
|
+
{
|
550
|
+
datum key;
|
551
|
+
struct dbmdata *dbmp;
|
552
|
+
DBM *dbm;
|
553
|
+
VALUE ary;
|
554
|
+
|
555
|
+
GetDBM2(obj, dbmp, dbm);
|
556
|
+
ary = rb_ary_new();
|
557
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
558
|
+
rb_ary_push(ary, rb_external_str_new(key.dptr, key.dsize));
|
559
|
+
}
|
560
|
+
|
561
|
+
return ary;
|
562
|
+
}
|
563
|
+
|
564
|
+
static VALUE
|
565
|
+
fsdbm_values(VALUE obj)
|
566
|
+
{
|
567
|
+
datum key, val;
|
568
|
+
struct dbmdata *dbmp;
|
569
|
+
DBM *dbm;
|
570
|
+
VALUE ary;
|
571
|
+
|
572
|
+
GetDBM2(obj, dbmp, dbm);
|
573
|
+
ary = rb_ary_new();
|
574
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
575
|
+
val = sdbm_fetch(dbm, key);
|
576
|
+
rb_ary_push(ary, rb_external_str_new(val.dptr, val.dsize));
|
577
|
+
}
|
578
|
+
|
579
|
+
return ary;
|
580
|
+
}
|
581
|
+
|
582
|
+
static VALUE
|
583
|
+
fsdbm_has_key(VALUE obj, VALUE keystr)
|
584
|
+
{
|
585
|
+
datum key, val;
|
586
|
+
struct dbmdata *dbmp;
|
587
|
+
DBM *dbm;
|
588
|
+
|
589
|
+
ExportStringValue(keystr);
|
590
|
+
key.dptr = RSTRING_PTR(keystr);
|
591
|
+
key.dsize = RSTRING_LENINT(keystr);
|
592
|
+
|
593
|
+
GetDBM2(obj, dbmp, dbm);
|
594
|
+
val = sdbm_fetch(dbm, key);
|
595
|
+
if (val.dptr) return Qtrue;
|
596
|
+
return Qfalse;
|
597
|
+
}
|
598
|
+
|
599
|
+
static VALUE
|
600
|
+
fsdbm_has_value(VALUE obj, VALUE valstr)
|
601
|
+
{
|
602
|
+
datum key, val;
|
603
|
+
struct dbmdata *dbmp;
|
604
|
+
DBM *dbm;
|
605
|
+
|
606
|
+
ExportStringValue(valstr);
|
607
|
+
val.dptr = RSTRING_PTR(valstr);
|
608
|
+
val.dsize = RSTRING_LENINT(valstr);
|
609
|
+
|
610
|
+
GetDBM2(obj, dbmp, dbm);
|
611
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
612
|
+
val = sdbm_fetch(dbm, key);
|
613
|
+
if (val.dsize == RSTRING_LENINT(valstr) &&
|
614
|
+
memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
|
615
|
+
return Qtrue;
|
616
|
+
}
|
617
|
+
return Qfalse;
|
618
|
+
}
|
619
|
+
|
620
|
+
static VALUE
|
621
|
+
fsdbm_to_a(VALUE obj)
|
622
|
+
{
|
623
|
+
datum key, val;
|
624
|
+
struct dbmdata *dbmp;
|
625
|
+
DBM *dbm;
|
626
|
+
VALUE ary;
|
627
|
+
|
628
|
+
GetDBM2(obj, dbmp, dbm);
|
629
|
+
ary = rb_ary_new();
|
630
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
631
|
+
val = sdbm_fetch(dbm, key);
|
632
|
+
rb_ary_push(ary, rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
|
633
|
+
rb_external_str_new(val.dptr, val.dsize)));
|
634
|
+
}
|
635
|
+
|
636
|
+
return ary;
|
637
|
+
}
|
638
|
+
|
639
|
+
static VALUE
|
640
|
+
fsdbm_to_hash(VALUE obj)
|
641
|
+
{
|
642
|
+
datum key, val;
|
643
|
+
struct dbmdata *dbmp;
|
644
|
+
DBM *dbm;
|
645
|
+
VALUE hash;
|
646
|
+
|
647
|
+
GetDBM2(obj, dbmp, dbm);
|
648
|
+
hash = rb_hash_new();
|
649
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
650
|
+
val = sdbm_fetch(dbm, key);
|
651
|
+
rb_hash_aset(hash, rb_external_str_new(key.dptr, key.dsize),
|
652
|
+
rb_external_str_new(val.dptr, val.dsize));
|
653
|
+
}
|
654
|
+
|
655
|
+
return hash;
|
656
|
+
}
|
657
|
+
|
658
|
+
static VALUE
|
659
|
+
fsdbm_reject(VALUE obj)
|
660
|
+
{
|
661
|
+
return rb_hash_delete_if(fsdbm_to_hash(obj));
|
662
|
+
}
|
663
|
+
|
664
|
+
void
|
665
|
+
Init_sdbm()
|
666
|
+
{
|
667
|
+
rb_cDBM = rb_define_class("SDBM", rb_cObject);
|
668
|
+
rb_eDBMError = rb_define_class("SDBMError", rb_eStandardError);
|
669
|
+
rb_include_module(rb_cDBM, rb_mEnumerable);
|
670
|
+
|
671
|
+
rb_define_alloc_func(rb_cDBM, fsdbm_alloc);
|
672
|
+
rb_define_singleton_method(rb_cDBM, "open", fsdbm_s_open, -1);
|
673
|
+
|
674
|
+
rb_define_method(rb_cDBM, "initialize", fsdbm_initialize, -1);
|
675
|
+
rb_define_method(rb_cDBM, "close", fsdbm_close, 0);
|
676
|
+
rb_define_method(rb_cDBM, "closed?", fsdbm_closed, 0);
|
677
|
+
rb_define_method(rb_cDBM, "[]", fsdbm_aref, 1);
|
678
|
+
rb_define_method(rb_cDBM, "fetch", fsdbm_fetch_m, -1);
|
679
|
+
rb_define_method(rb_cDBM, "[]=", fsdbm_store, 2);
|
680
|
+
rb_define_method(rb_cDBM, "store", fsdbm_store, 2);
|
681
|
+
rb_define_method(rb_cDBM, "index", fsdbm_index, 1);
|
682
|
+
rb_define_method(rb_cDBM, "key", fsdbm_key, 1);
|
683
|
+
rb_define_method(rb_cDBM, "select", fsdbm_select, 0);
|
684
|
+
rb_define_method(rb_cDBM, "values_at", fsdbm_values_at, -1);
|
685
|
+
rb_define_method(rb_cDBM, "length", fsdbm_length, 0);
|
686
|
+
rb_define_method(rb_cDBM, "size", fsdbm_length, 0);
|
687
|
+
rb_define_method(rb_cDBM, "empty?", fsdbm_empty_p, 0);
|
688
|
+
rb_define_method(rb_cDBM, "each", fsdbm_each_pair, 0);
|
689
|
+
rb_define_method(rb_cDBM, "each_value", fsdbm_each_value, 0);
|
690
|
+
rb_define_method(rb_cDBM, "each_key", fsdbm_each_key, 0);
|
691
|
+
rb_define_method(rb_cDBM, "each_pair", fsdbm_each_pair, 0);
|
692
|
+
rb_define_method(rb_cDBM, "keys", fsdbm_keys, 0);
|
693
|
+
rb_define_method(rb_cDBM, "values", fsdbm_values, 0);
|
694
|
+
rb_define_method(rb_cDBM, "shift", fsdbm_shift, 0);
|
695
|
+
rb_define_method(rb_cDBM, "delete", fsdbm_delete, 1);
|
696
|
+
rb_define_method(rb_cDBM, "delete_if", fsdbm_delete_if, 0);
|
697
|
+
rb_define_method(rb_cDBM, "reject!", fsdbm_delete_if, 0);
|
698
|
+
rb_define_method(rb_cDBM, "reject", fsdbm_reject, 0);
|
699
|
+
rb_define_method(rb_cDBM, "clear", fsdbm_clear, 0);
|
700
|
+
rb_define_method(rb_cDBM,"invert", fsdbm_invert, 0);
|
701
|
+
rb_define_method(rb_cDBM,"update", fsdbm_update, 1);
|
702
|
+
rb_define_method(rb_cDBM,"replace", fsdbm_replace, 1);
|
703
|
+
|
704
|
+
rb_define_method(rb_cDBM, "include?", fsdbm_has_key, 1);
|
705
|
+
rb_define_method(rb_cDBM, "has_key?", fsdbm_has_key, 1);
|
706
|
+
rb_define_method(rb_cDBM, "member?", fsdbm_has_key, 1);
|
707
|
+
rb_define_method(rb_cDBM, "has_value?", fsdbm_has_value, 1);
|
708
|
+
rb_define_method(rb_cDBM, "key?", fsdbm_has_key, 1);
|
709
|
+
rb_define_method(rb_cDBM, "value?", fsdbm_has_value, 1);
|
710
|
+
|
711
|
+
rb_define_method(rb_cDBM, "to_a", fsdbm_to_a, 0);
|
712
|
+
rb_define_method(rb_cDBM, "to_hash", fsdbm_to_hash, 0);
|
713
|
+
}
|