00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "ruby.h"
00013
00014 #include "sdbm.h"
00015 #include <fcntl.h>
00016 #include <errno.h>
00017
00018 static VALUE rb_cDBM, rb_eDBMError;
00019
00020 struct dbmdata {
00021 int di_size;
00022 DBM *di_dbm;
00023 };
00024
00025 static void
00026 closed_sdbm()
00027 {
00028 rb_raise(rb_eDBMError, "closed SDBM file");
00029 }
00030
00031 #define GetDBM(obj, dbmp) {\
00032 Data_Get_Struct(obj, struct dbmdata, dbmp);\
00033 if (dbmp == 0) closed_sdbm();\
00034 if (dbmp->di_dbm == 0) closed_sdbm();\
00035 }
00036
00037 #define GetDBM2(obj, data, dbm) {\
00038 GetDBM(obj, data);\
00039 (dbm) = dbmp->di_dbm;\
00040 }
00041
00042 static void
00043 free_sdbm(struct dbmdata *dbmp)
00044 {
00045
00046 if (dbmp->di_dbm) sdbm_close(dbmp->di_dbm);
00047 ruby_xfree(dbmp);
00048 }
00049
00050 static VALUE
00051 fsdbm_close(VALUE obj)
00052 {
00053 struct dbmdata *dbmp;
00054
00055 GetDBM(obj, dbmp);
00056 sdbm_close(dbmp->di_dbm);
00057 dbmp->di_dbm = 0;
00058
00059 return Qnil;
00060 }
00061
00062 static VALUE
00063 fsdbm_closed(VALUE obj)
00064 {
00065 struct dbmdata *dbmp;
00066
00067 Data_Get_Struct(obj, struct dbmdata, dbmp);
00068 if (dbmp == 0)
00069 return Qtrue;
00070 if (dbmp->di_dbm == 0)
00071 return Qtrue;
00072
00073 return Qfalse;
00074 }
00075
00076 static VALUE
00077 fsdbm_alloc(VALUE klass)
00078 {
00079 return Data_Wrap_Struct(klass, 0, free_sdbm, 0);
00080 }
00081
00082 static VALUE
00083 fsdbm_initialize(int argc, VALUE *argv, VALUE obj)
00084 {
00085 volatile VALUE file;
00086 VALUE vmode;
00087 DBM *dbm;
00088 struct dbmdata *dbmp;
00089 int mode;
00090
00091 if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
00092 mode = 0666;
00093 }
00094 else if (NIL_P(vmode)) {
00095 mode = -1;
00096 }
00097 else {
00098 mode = NUM2INT(vmode);
00099 }
00100 FilePathValue(file);
00101
00102 dbm = 0;
00103 if (mode >= 0)
00104 dbm = sdbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT, mode);
00105 if (!dbm)
00106 dbm = sdbm_open(RSTRING_PTR(file), O_RDWR, 0);
00107 if (!dbm)
00108 dbm = sdbm_open(RSTRING_PTR(file), O_RDONLY, 0);
00109
00110 if (!dbm) {
00111 if (mode == -1) return Qnil;
00112 rb_sys_fail(RSTRING_PTR(file));
00113 }
00114
00115 dbmp = ALLOC(struct dbmdata);
00116 DATA_PTR(obj) = dbmp;
00117 dbmp->di_dbm = dbm;
00118 dbmp->di_size = -1;
00119
00120 return obj;
00121 }
00122
00123 static VALUE
00124 fsdbm_s_open(int argc, VALUE *argv, VALUE klass)
00125 {
00126 VALUE obj = Data_Wrap_Struct(klass, 0, free_sdbm, 0);
00127
00128 if (NIL_P(fsdbm_initialize(argc, argv, obj))) {
00129 return Qnil;
00130 }
00131
00132 if (rb_block_given_p()) {
00133 return rb_ensure(rb_yield, obj, fsdbm_close, obj);
00134 }
00135
00136 return obj;
00137 }
00138
00139 static VALUE
00140 fsdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
00141 {
00142 datum key, value;
00143 struct dbmdata *dbmp;
00144 DBM *dbm;
00145
00146 ExportStringValue(keystr);
00147 key.dptr = RSTRING_PTR(keystr);
00148 key.dsize = RSTRING_LEN(keystr);
00149
00150 GetDBM2(obj, dbmp, dbm);
00151 value = sdbm_fetch(dbm, key);
00152 if (value.dptr == 0) {
00153 if (ifnone == Qnil && rb_block_given_p())
00154 return rb_yield(rb_external_str_new(key.dptr, key.dsize));
00155 return ifnone;
00156 }
00157 return rb_external_str_new(value.dptr, value.dsize);
00158 }
00159
00160 static VALUE
00161 fsdbm_aref(VALUE obj, VALUE keystr)
00162 {
00163 return fsdbm_fetch(obj, keystr, Qnil);
00164 }
00165
00166 static VALUE
00167 fsdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
00168 {
00169 VALUE keystr, valstr, ifnone;
00170
00171 rb_scan_args(argc, argv, "11", &keystr, &ifnone);
00172 valstr = fsdbm_fetch(obj, keystr, ifnone);
00173 if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
00174 rb_raise(rb_eIndexError, "key not found");
00175
00176 return valstr;
00177 }
00178
00179 static VALUE
00180 fsdbm_key(VALUE obj, VALUE valstr)
00181 {
00182 datum key, val;
00183 struct dbmdata *dbmp;
00184 DBM *dbm;
00185
00186 ExportStringValue(valstr);
00187 val.dptr = RSTRING_PTR(valstr);
00188 val.dsize = RSTRING_LEN(valstr);
00189
00190 GetDBM2(obj, dbmp, dbm);
00191 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00192 val = sdbm_fetch(dbm, key);
00193 if (val.dsize == RSTRING_LEN(valstr) &&
00194 memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
00195 return rb_external_str_new(key.dptr, key.dsize);
00196 }
00197 return Qnil;
00198 }
00199
00200 static VALUE
00201 fsdbm_index(VALUE hash, VALUE value)
00202 {
00203 rb_warn("SDBM#index is deprecated; use SDBM#key");
00204 return fsdbm_key(hash, value);
00205 }
00206
00207 static VALUE
00208 fsdbm_select(VALUE obj)
00209 {
00210 VALUE new = rb_ary_new();
00211 datum key, val;
00212 DBM *dbm;
00213 struct dbmdata *dbmp;
00214
00215 GetDBM2(obj, dbmp, dbm);
00216 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00217 VALUE assoc, v;
00218 val = sdbm_fetch(dbm, key);
00219 assoc = rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
00220 rb_external_str_new(val.dptr, val.dsize));
00221 v = rb_yield(assoc);
00222 if (RTEST(v)) {
00223 rb_ary_push(new, assoc);
00224 }
00225 GetDBM2(obj, dbmp, dbm);
00226 }
00227
00228 return new;
00229 }
00230
00231 static VALUE
00232 fsdbm_values_at(int argc, VALUE *argv, VALUE obj)
00233 {
00234 VALUE new = rb_ary_new2(argc);
00235 int i;
00236
00237 for (i=0; i<argc; i++) {
00238 rb_ary_push(new, fsdbm_fetch(obj, argv[i], Qnil));
00239 }
00240
00241 return new;
00242 }
00243
00244 static void
00245 fdbm_modify(VALUE obj)
00246 {
00247 rb_secure(4);
00248 if (OBJ_FROZEN(obj)) rb_error_frozen("SDBM");
00249 }
00250
00251 static VALUE
00252 fsdbm_delete(VALUE obj, VALUE keystr)
00253 {
00254 datum key, value;
00255 struct dbmdata *dbmp;
00256 DBM *dbm;
00257 VALUE valstr;
00258
00259 fdbm_modify(obj);
00260 ExportStringValue(keystr);
00261 key.dptr = RSTRING_PTR(keystr);
00262 key.dsize = RSTRING_LEN(keystr);
00263
00264 GetDBM2(obj, dbmp, dbm);
00265 dbmp->di_size = -1;
00266
00267 value = sdbm_fetch(dbm, key);
00268 if (value.dptr == 0) {
00269 if (rb_block_given_p()) return rb_yield(keystr);
00270 return Qnil;
00271 }
00272
00273
00274 valstr = rb_external_str_new(value.dptr, value.dsize);
00275
00276 if (sdbm_delete(dbm, key)) {
00277 dbmp->di_size = -1;
00278 rb_raise(rb_eDBMError, "dbm_delete failed");
00279 }
00280 else if (dbmp->di_size >= 0) {
00281 dbmp->di_size--;
00282 }
00283 return valstr;
00284 }
00285
00286 static VALUE
00287 fsdbm_shift(VALUE obj)
00288 {
00289 datum key, val;
00290 struct dbmdata *dbmp;
00291 DBM *dbm;
00292 VALUE keystr, valstr;
00293
00294 fdbm_modify(obj);
00295 GetDBM2(obj, dbmp, dbm);
00296 key = sdbm_firstkey(dbm);
00297 if (!key.dptr) return Qnil;
00298 val = sdbm_fetch(dbm, key);
00299 keystr = rb_external_str_new(key.dptr, key.dsize);
00300 valstr = rb_external_str_new(val.dptr, val.dsize);
00301 sdbm_delete(dbm, key);
00302 if (dbmp->di_size >= 0) {
00303 dbmp->di_size--;
00304 }
00305
00306 return rb_assoc_new(keystr, valstr);
00307 }
00308
00309 static VALUE
00310 fsdbm_delete_if(VALUE obj)
00311 {
00312 datum key, val;
00313 struct dbmdata *dbmp;
00314 DBM *dbm;
00315 VALUE keystr, valstr;
00316 VALUE ret, ary = rb_ary_new();
00317 int i, status = 0, n;
00318
00319 fdbm_modify(obj);
00320 GetDBM2(obj, dbmp, dbm);
00321 n = dbmp->di_size;
00322 dbmp->di_size = -1;
00323 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00324 val = sdbm_fetch(dbm, key);
00325 keystr = rb_external_str_new(key.dptr, key.dsize);
00326 valstr = rb_external_str_new(val.dptr, val.dsize);
00327 ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
00328 if (status != 0) break;
00329 if (RTEST(ret)) rb_ary_push(ary, keystr);
00330 GetDBM2(obj, dbmp, dbm);
00331 }
00332
00333 for (i = 0; i < RARRAY_LEN(ary); i++) {
00334 keystr = RARRAY_PTR(ary)[i];
00335 ExportStringValue(keystr);
00336 key.dptr = RSTRING_PTR(keystr);
00337 key.dsize = RSTRING_LEN(keystr);
00338 if (sdbm_delete(dbm, key)) {
00339 rb_raise(rb_eDBMError, "sdbm_delete failed");
00340 }
00341 }
00342 if (status) rb_jump_tag(status);
00343 if (n > 0) dbmp->di_size = n - RARRAY_LEN(ary);
00344
00345 return obj;
00346 }
00347
00348 static VALUE
00349 fsdbm_clear(VALUE obj)
00350 {
00351 datum key;
00352 struct dbmdata *dbmp;
00353 DBM *dbm;
00354
00355 fdbm_modify(obj);
00356 GetDBM2(obj, dbmp, dbm);
00357 dbmp->di_size = -1;
00358 while (key = sdbm_firstkey(dbm), key.dptr) {
00359 if (sdbm_delete(dbm, key)) {
00360 rb_raise(rb_eDBMError, "sdbm_delete failed");
00361 }
00362 }
00363 dbmp->di_size = 0;
00364
00365 return obj;
00366 }
00367
00368 static VALUE
00369 fsdbm_invert(VALUE obj)
00370 {
00371 datum key, val;
00372 struct dbmdata *dbmp;
00373 DBM *dbm;
00374 VALUE keystr, valstr;
00375 VALUE hash = rb_hash_new();
00376
00377 GetDBM2(obj, dbmp, dbm);
00378 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00379 val = sdbm_fetch(dbm, key);
00380 keystr = rb_external_str_new(key.dptr, key.dsize);
00381 valstr = rb_external_str_new(val.dptr, val.dsize);
00382 rb_hash_aset(hash, valstr, keystr);
00383 }
00384 return hash;
00385 }
00386
00387 static VALUE
00388 fsdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
00389 {
00390 datum key, val;
00391 struct dbmdata *dbmp;
00392 DBM *dbm;
00393
00394 if (valstr == Qnil) {
00395 fsdbm_delete(obj, keystr);
00396 return Qnil;
00397 }
00398
00399 fdbm_modify(obj);
00400 ExportStringValue(keystr);
00401 ExportStringValue(valstr);
00402
00403 key.dptr = RSTRING_PTR(keystr);
00404 key.dsize = RSTRING_LEN(keystr);
00405
00406 val.dptr = RSTRING_PTR(valstr);
00407 val.dsize = RSTRING_LEN(valstr);
00408
00409 GetDBM2(obj, dbmp, dbm);
00410 dbmp->di_size = -1;
00411 if (sdbm_store(dbm, key, val, DBM_REPLACE)) {
00412 #ifdef HAVE_DBM_CLAERERR
00413 sdbm_clearerr(dbm);
00414 #endif
00415 if (errno == EPERM) rb_sys_fail(0);
00416 rb_raise(rb_eDBMError, "sdbm_store failed");
00417 }
00418
00419 return valstr;
00420 }
00421
00422 static VALUE
00423 update_i(VALUE pair, VALUE dbm)
00424 {
00425 Check_Type(pair, T_ARRAY);
00426 if (RARRAY_LEN(pair) < 2) {
00427 rb_raise(rb_eArgError, "pair must be [key, value]");
00428 }
00429 fsdbm_store(dbm, RARRAY_PTR(pair)[0], RARRAY_PTR(pair)[1]);
00430 return Qnil;
00431 }
00432
00433 static VALUE
00434 fsdbm_update(VALUE obj, VALUE other)
00435 {
00436 rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
00437 return obj;
00438 }
00439
00440 static VALUE
00441 fsdbm_replace(VALUE obj, VALUE other)
00442 {
00443 fsdbm_clear(obj);
00444 rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
00445 return obj;
00446 }
00447
00448 static VALUE
00449 fsdbm_length(VALUE obj)
00450 {
00451 datum key;
00452 struct dbmdata *dbmp;
00453 DBM *dbm;
00454 int i = 0;
00455
00456 GetDBM2(obj, dbmp, dbm);
00457 if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
00458
00459 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00460 i++;
00461 }
00462 dbmp->di_size = i;
00463
00464 return INT2FIX(i);
00465 }
00466
00467 static VALUE
00468 fsdbm_empty_p(VALUE obj)
00469 {
00470 datum key;
00471 struct dbmdata *dbmp;
00472 DBM *dbm;
00473 int i = 0;
00474
00475 GetDBM(obj, dbmp);
00476 if (dbmp->di_size < 0) {
00477 dbm = dbmp->di_dbm;
00478
00479 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00480 i++;
00481 }
00482 }
00483 else {
00484 i = dbmp->di_size;
00485 }
00486 if (i == 0) return Qtrue;
00487 return Qfalse;
00488 }
00489
00490 static VALUE
00491 fsdbm_each_value(VALUE obj)
00492 {
00493 datum key, val;
00494 struct dbmdata *dbmp;
00495 DBM *dbm;
00496
00497 RETURN_ENUMERATOR(obj, 0, 0);
00498
00499 GetDBM2(obj, dbmp, dbm);
00500 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00501 val = sdbm_fetch(dbm, key);
00502 rb_yield(rb_external_str_new(val.dptr, val.dsize));
00503 GetDBM2(obj, dbmp, dbm);
00504 }
00505 return obj;
00506 }
00507
00508 static VALUE
00509 fsdbm_each_key(VALUE obj)
00510 {
00511 datum key;
00512 struct dbmdata *dbmp;
00513 DBM *dbm;
00514
00515 RETURN_ENUMERATOR(obj, 0, 0);
00516
00517 GetDBM2(obj, dbmp, dbm);
00518 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00519 rb_yield(rb_external_str_new(key.dptr, key.dsize));
00520 GetDBM2(obj, dbmp, dbm);
00521 }
00522 return obj;
00523 }
00524
00525 static VALUE
00526 fsdbm_each_pair(VALUE obj)
00527 {
00528 datum key, val;
00529 DBM *dbm;
00530 struct dbmdata *dbmp;
00531 VALUE keystr, valstr;
00532
00533 RETURN_ENUMERATOR(obj, 0, 0);
00534
00535 GetDBM2(obj, dbmp, dbm);
00536 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00537 val = sdbm_fetch(dbm, key);
00538 keystr = rb_external_str_new(key.dptr, key.dsize);
00539 valstr = rb_external_str_new(val.dptr, val.dsize);
00540 rb_yield(rb_assoc_new(keystr, valstr));
00541 GetDBM2(obj, dbmp, dbm);
00542 }
00543
00544 return obj;
00545 }
00546
00547 static VALUE
00548 fsdbm_keys(VALUE obj)
00549 {
00550 datum key;
00551 struct dbmdata *dbmp;
00552 DBM *dbm;
00553 VALUE ary;
00554
00555 GetDBM2(obj, dbmp, dbm);
00556 ary = rb_ary_new();
00557 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00558 rb_ary_push(ary, rb_external_str_new(key.dptr, key.dsize));
00559 }
00560
00561 return ary;
00562 }
00563
00564 static VALUE
00565 fsdbm_values(VALUE obj)
00566 {
00567 datum key, val;
00568 struct dbmdata *dbmp;
00569 DBM *dbm;
00570 VALUE ary;
00571
00572 GetDBM2(obj, dbmp, dbm);
00573 ary = rb_ary_new();
00574 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00575 val = sdbm_fetch(dbm, key);
00576 rb_ary_push(ary, rb_external_str_new(val.dptr, val.dsize));
00577 }
00578
00579 return ary;
00580 }
00581
00582 static VALUE
00583 fsdbm_has_key(VALUE obj, VALUE keystr)
00584 {
00585 datum key, val;
00586 struct dbmdata *dbmp;
00587 DBM *dbm;
00588
00589 ExportStringValue(keystr);
00590 key.dptr = RSTRING_PTR(keystr);
00591 key.dsize = RSTRING_LEN(keystr);
00592
00593 GetDBM2(obj, dbmp, dbm);
00594 val = sdbm_fetch(dbm, key);
00595 if (val.dptr) return Qtrue;
00596 return Qfalse;
00597 }
00598
00599 static VALUE
00600 fsdbm_has_value(VALUE obj, VALUE valstr)
00601 {
00602 datum key, val;
00603 struct dbmdata *dbmp;
00604 DBM *dbm;
00605
00606 ExportStringValue(valstr);
00607 val.dptr = RSTRING_PTR(valstr);
00608 val.dsize = RSTRING_LEN(valstr);
00609
00610 GetDBM2(obj, dbmp, dbm);
00611 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00612 val = sdbm_fetch(dbm, key);
00613 if (val.dsize == RSTRING_LEN(valstr) &&
00614 memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
00615 return Qtrue;
00616 }
00617 return Qfalse;
00618 }
00619
00620 static VALUE
00621 fsdbm_to_a(VALUE obj)
00622 {
00623 datum key, val;
00624 struct dbmdata *dbmp;
00625 DBM *dbm;
00626 VALUE ary;
00627
00628 GetDBM2(obj, dbmp, dbm);
00629 ary = rb_ary_new();
00630 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00631 val = sdbm_fetch(dbm, key);
00632 rb_ary_push(ary, rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
00633 rb_external_str_new(val.dptr, val.dsize)));
00634 }
00635
00636 return ary;
00637 }
00638
00639 static VALUE
00640 fsdbm_to_hash(VALUE obj)
00641 {
00642 datum key, val;
00643 struct dbmdata *dbmp;
00644 DBM *dbm;
00645 VALUE hash;
00646
00647 GetDBM2(obj, dbmp, dbm);
00648 hash = rb_hash_new();
00649 for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
00650 val = sdbm_fetch(dbm, key);
00651 rb_hash_aset(hash, rb_external_str_new(key.dptr, key.dsize),
00652 rb_external_str_new(val.dptr, val.dsize));
00653 }
00654
00655 return hash;
00656 }
00657
00658 static VALUE
00659 fsdbm_reject(VALUE obj)
00660 {
00661 return rb_hash_delete_if(fsdbm_to_hash(obj));
00662 }
00663
00664 void
00665 Init_sdbm()
00666 {
00667 rb_cDBM = rb_define_class("SDBM", rb_cObject);
00668 rb_eDBMError = rb_define_class("SDBMError", rb_eStandardError);
00669 rb_include_module(rb_cDBM, rb_mEnumerable);
00670
00671 rb_define_alloc_func(rb_cDBM, fsdbm_alloc);
00672 rb_define_singleton_method(rb_cDBM, "open", fsdbm_s_open, -1);
00673
00674 rb_define_method(rb_cDBM, "initialize", fsdbm_initialize, -1);
00675 rb_define_method(rb_cDBM, "close", fsdbm_close, 0);
00676 rb_define_method(rb_cDBM, "closed?", fsdbm_closed, 0);
00677 rb_define_method(rb_cDBM, "[]", fsdbm_aref, 1);
00678 rb_define_method(rb_cDBM, "fetch", fsdbm_fetch_m, -1);
00679 rb_define_method(rb_cDBM, "[]=", fsdbm_store, 2);
00680 rb_define_method(rb_cDBM, "store", fsdbm_store, 2);
00681 rb_define_method(rb_cDBM, "index", fsdbm_index, 1);
00682 rb_define_method(rb_cDBM, "key", fsdbm_key, 1);
00683 rb_define_method(rb_cDBM, "select", fsdbm_select, 0);
00684 rb_define_method(rb_cDBM, "values_at", fsdbm_values_at, -1);
00685 rb_define_method(rb_cDBM, "length", fsdbm_length, 0);
00686 rb_define_method(rb_cDBM, "size", fsdbm_length, 0);
00687 rb_define_method(rb_cDBM, "empty?", fsdbm_empty_p, 0);
00688 rb_define_method(rb_cDBM, "each", fsdbm_each_pair, 0);
00689 rb_define_method(rb_cDBM, "each_value", fsdbm_each_value, 0);
00690 rb_define_method(rb_cDBM, "each_key", fsdbm_each_key, 0);
00691 rb_define_method(rb_cDBM, "each_pair", fsdbm_each_pair, 0);
00692 rb_define_method(rb_cDBM, "keys", fsdbm_keys, 0);
00693 rb_define_method(rb_cDBM, "values", fsdbm_values, 0);
00694 rb_define_method(rb_cDBM, "shift", fsdbm_shift, 0);
00695 rb_define_method(rb_cDBM, "delete", fsdbm_delete, 1);
00696 rb_define_method(rb_cDBM, "delete_if", fsdbm_delete_if, 0);
00697 rb_define_method(rb_cDBM, "reject!", fsdbm_delete_if, 0);
00698 rb_define_method(rb_cDBM, "reject", fsdbm_reject, 0);
00699 rb_define_method(rb_cDBM, "clear", fsdbm_clear, 0);
00700 rb_define_method(rb_cDBM,"invert", fsdbm_invert, 0);
00701 rb_define_method(rb_cDBM,"update", fsdbm_update, 1);
00702 rb_define_method(rb_cDBM,"replace", fsdbm_replace, 1);
00703
00704 rb_define_method(rb_cDBM, "include?", fsdbm_has_key, 1);
00705 rb_define_method(rb_cDBM, "has_key?", fsdbm_has_key, 1);
00706 rb_define_method(rb_cDBM, "member?", fsdbm_has_key, 1);
00707 rb_define_method(rb_cDBM, "has_value?", fsdbm_has_value, 1);
00708 rb_define_method(rb_cDBM, "key?", fsdbm_has_key, 1);
00709 rb_define_method(rb_cDBM, "value?", fsdbm_has_value, 1);
00710
00711 rb_define_method(rb_cDBM, "to_a", fsdbm_to_a, 0);
00712 rb_define_method(rb_cDBM, "to_hash", fsdbm_to_hash, 0);
00713 }
00714