00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "ruby.h"
00013
00014 #ifdef HAVE_CDEFS_H
00015 # include <cdefs.h>
00016 #endif
00017 #ifdef HAVE_SYS_CDEFS_H
00018 # include <sys/cdefs.h>
00019 #endif
00020 #include DBM_HDR
00021 #include <fcntl.h>
00022 #include <errno.h>
00023
00024 static VALUE rb_cDBM, rb_eDBMError;
00025
00026 #define RUBY_DBM_RW_BIT 0x20000000
00027
00028 struct dbmdata {
00029 long di_size;
00030 DBM *di_dbm;
00031 };
00032
00033 static void
00034 closed_dbm(void)
00035 {
00036 rb_raise(rb_eDBMError, "closed DBM file");
00037 }
00038
00039 #define GetDBM(obj, dbmp) {\
00040 Data_Get_Struct((obj), struct dbmdata, (dbmp));\
00041 if ((dbmp) == 0) closed_dbm();\
00042 if ((dbmp)->di_dbm == 0) closed_dbm();\
00043 }
00044
00045 #define GetDBM2(obj, data, dbm) {\
00046 GetDBM((obj), (data));\
00047 (dbm) = dbmp->di_dbm;\
00048 }
00049
00050 static void
00051 free_dbm(struct dbmdata *dbmp)
00052 {
00053 if (dbmp) {
00054 if (dbmp->di_dbm) dbm_close(dbmp->di_dbm);
00055 xfree(dbmp);
00056 }
00057 }
00058
00059
00060
00061
00062
00063
00064
00065 static VALUE
00066 fdbm_close(VALUE obj)
00067 {
00068 struct dbmdata *dbmp;
00069
00070 GetDBM(obj, dbmp);
00071 dbm_close(dbmp->di_dbm);
00072 dbmp->di_dbm = 0;
00073
00074 return Qnil;
00075 }
00076
00077
00078
00079
00080
00081
00082
00083 static VALUE
00084 fdbm_closed(VALUE obj)
00085 {
00086 struct dbmdata *dbmp;
00087
00088 Data_Get_Struct(obj, struct dbmdata, dbmp);
00089 if (dbmp == 0)
00090 return Qtrue;
00091 if (dbmp->di_dbm == 0)
00092 return Qtrue;
00093
00094 return Qfalse;
00095 }
00096
00097 static VALUE
00098 fdbm_alloc(VALUE klass)
00099 {
00100 return Data_Wrap_Struct(klass, 0, free_dbm, 0);
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 static VALUE
00117 fdbm_initialize(int argc, VALUE *argv, VALUE obj)
00118 {
00119 volatile VALUE file;
00120 VALUE vmode, vflags;
00121 DBM *dbm;
00122 struct dbmdata *dbmp;
00123 int mode, flags = 0;
00124
00125 if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
00126 mode = 0666;
00127 }
00128 else if (NIL_P(vmode)) {
00129 mode = -1;
00130 }
00131 else {
00132 mode = NUM2INT(vmode);
00133 }
00134
00135 if (!NIL_P(vflags))
00136 flags = NUM2INT(vflags);
00137
00138 FilePathValue(file);
00139
00140 if (flags & RUBY_DBM_RW_BIT) {
00141 flags &= ~RUBY_DBM_RW_BIT;
00142 dbm = dbm_open(RSTRING_PTR(file), flags, mode);
00143 }
00144 else {
00145 dbm = 0;
00146 if (mode >= 0) {
00147 dbm = dbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT, mode);
00148 }
00149 if (!dbm) {
00150 dbm = dbm_open(RSTRING_PTR(file), O_RDWR, 0);
00151 }
00152 if (!dbm) {
00153 dbm = dbm_open(RSTRING_PTR(file), O_RDONLY, 0);
00154 }
00155 }
00156
00157 if (!dbm) {
00158 if (mode == -1) return Qnil;
00159 rb_sys_fail(RSTRING_PTR(file));
00160 }
00161
00162 dbmp = ALLOC(struct dbmdata);
00163 DATA_PTR(obj) = dbmp;
00164 dbmp->di_dbm = dbm;
00165 dbmp->di_size = -1;
00166
00167 return obj;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 static VALUE
00179 fdbm_s_open(int argc, VALUE *argv, VALUE klass)
00180 {
00181 VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);
00182
00183 if (NIL_P(fdbm_initialize(argc, argv, obj))) {
00184 return Qnil;
00185 }
00186
00187 if (rb_block_given_p()) {
00188 return rb_ensure(rb_yield, obj, fdbm_close, obj);
00189 }
00190
00191 return obj;
00192 }
00193
00194 static VALUE
00195 fdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
00196 {
00197 datum key, value;
00198 struct dbmdata *dbmp;
00199 DBM *dbm;
00200
00201 ExportStringValue(keystr);
00202 key.dptr = RSTRING_PTR(keystr);
00203 key.dsize = (int)RSTRING_LEN(keystr);
00204
00205 GetDBM2(obj, dbmp, dbm);
00206 value = dbm_fetch(dbm, key);
00207 if (value.dptr == 0) {
00208 if (ifnone == Qnil && rb_block_given_p())
00209 return rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
00210 return ifnone;
00211 }
00212 return rb_tainted_str_new(value.dptr, value.dsize);
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222 static VALUE
00223 fdbm_aref(VALUE obj, VALUE keystr)
00224 {
00225 return fdbm_fetch(obj, keystr, Qnil);
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 static VALUE
00237 fdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
00238 {
00239 VALUE keystr, valstr, ifnone;
00240
00241 rb_scan_args(argc, argv, "11", &keystr, &ifnone);
00242 valstr = fdbm_fetch(obj, keystr, ifnone);
00243 if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
00244 rb_raise(rb_eIndexError, "key not found");
00245
00246 return valstr;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255 static VALUE
00256 fdbm_key(VALUE obj, VALUE valstr)
00257 {
00258 datum key, val;
00259 struct dbmdata *dbmp;
00260 DBM *dbm;
00261
00262 ExportStringValue(valstr);
00263 val.dptr = RSTRING_PTR(valstr);
00264 val.dsize = (int)RSTRING_LEN(valstr);
00265
00266 GetDBM2(obj, dbmp, dbm);
00267 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00268 val = dbm_fetch(dbm, key);
00269 if ((long)val.dsize == (int)RSTRING_LEN(valstr) &&
00270 memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0) {
00271 return rb_tainted_str_new(key.dptr, key.dsize);
00272 }
00273 }
00274 return Qnil;
00275 }
00276
00277
00278 static VALUE
00279 fdbm_index(VALUE hash, VALUE value)
00280 {
00281 rb_warn("DBM#index is deprecated; use DBM#key");
00282 return fdbm_key(hash, value);
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292 static VALUE
00293 fdbm_select(VALUE obj)
00294 {
00295 VALUE new = rb_ary_new();
00296 datum key, val;
00297 DBM *dbm;
00298 struct dbmdata *dbmp;
00299
00300 GetDBM2(obj, dbmp, dbm);
00301 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00302 VALUE assoc, v;
00303 val = dbm_fetch(dbm, key);
00304 assoc = rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
00305 rb_tainted_str_new(val.dptr, val.dsize));
00306 v = rb_yield(assoc);
00307 if (RTEST(v)) {
00308 rb_ary_push(new, assoc);
00309 }
00310 GetDBM2(obj, dbmp, dbm);
00311 }
00312
00313 return new;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322 static VALUE
00323 fdbm_values_at(int argc, VALUE *argv, VALUE obj)
00324 {
00325 VALUE new = rb_ary_new2(argc);
00326 int i;
00327
00328 for (i=0; i<argc; i++) {
00329 rb_ary_push(new, fdbm_fetch(obj, argv[i], Qnil));
00330 }
00331
00332 return new;
00333 }
00334
00335 static void
00336 fdbm_modify(VALUE obj)
00337 {
00338 rb_secure(4);
00339 if (OBJ_FROZEN(obj)) rb_error_frozen("DBM");
00340 }
00341
00342
00343
00344
00345
00346
00347
00348 static VALUE
00349 fdbm_delete(VALUE obj, VALUE keystr)
00350 {
00351 datum key, value;
00352 struct dbmdata *dbmp;
00353 DBM *dbm;
00354 VALUE valstr;
00355
00356 fdbm_modify(obj);
00357 ExportStringValue(keystr);
00358 key.dptr = RSTRING_PTR(keystr);
00359 key.dsize = (int)RSTRING_LEN(keystr);
00360
00361 GetDBM2(obj, dbmp, dbm);
00362
00363 value = dbm_fetch(dbm, key);
00364 if (value.dptr == 0) {
00365 if (rb_block_given_p()) return rb_yield(keystr);
00366 return Qnil;
00367 }
00368
00369
00370 valstr = rb_tainted_str_new(value.dptr, value.dsize);
00371
00372 if (dbm_delete(dbm, key)) {
00373 dbmp->di_size = -1;
00374 rb_raise(rb_eDBMError, "dbm_delete failed");
00375 }
00376 else if (dbmp->di_size >= 0) {
00377 dbmp->di_size--;
00378 }
00379 return valstr;
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 static VALUE
00391 fdbm_shift(VALUE obj)
00392 {
00393 datum key, val;
00394 struct dbmdata *dbmp;
00395 DBM *dbm;
00396 VALUE keystr, valstr;
00397
00398 fdbm_modify(obj);
00399 GetDBM2(obj, dbmp, dbm);
00400 dbmp->di_size = -1;
00401
00402 key = dbm_firstkey(dbm);
00403 if (!key.dptr) return Qnil;
00404 val = dbm_fetch(dbm, key);
00405 keystr = rb_tainted_str_new(key.dptr, key.dsize);
00406 valstr = rb_tainted_str_new(val.dptr, val.dsize);
00407 dbm_delete(dbm, key);
00408
00409 return rb_assoc_new(keystr, valstr);
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 static VALUE
00421 fdbm_delete_if(VALUE obj)
00422 {
00423 datum key, val;
00424 struct dbmdata *dbmp;
00425 DBM *dbm;
00426 VALUE keystr, valstr;
00427 VALUE ret, ary = rb_ary_new();
00428 int i, status = 0;
00429 long n;
00430
00431 fdbm_modify(obj);
00432 GetDBM2(obj, dbmp, dbm);
00433 n = dbmp->di_size;
00434 dbmp->di_size = -1;
00435
00436 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00437 val = dbm_fetch(dbm, key);
00438 keystr = rb_tainted_str_new(key.dptr, key.dsize);
00439 valstr = rb_tainted_str_new(val.dptr, val.dsize);
00440 ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
00441 if (status != 0) break;
00442 if (RTEST(ret)) rb_ary_push(ary, keystr);
00443 GetDBM2(obj, dbmp, dbm);
00444 }
00445
00446 for (i = 0; i < RARRAY_LEN(ary); i++) {
00447 keystr = RARRAY_PTR(ary)[i];
00448 ExportStringValue(keystr);
00449 key.dptr = RSTRING_PTR(keystr);
00450 key.dsize = (int)RSTRING_LEN(keystr);
00451 if (dbm_delete(dbm, key)) {
00452 rb_raise(rb_eDBMError, "dbm_delete failed");
00453 }
00454 }
00455 if (status) rb_jump_tag(status);
00456 if (n > 0) dbmp->di_size = n - RARRAY_LEN(ary);
00457
00458 return obj;
00459 }
00460
00461
00462
00463
00464
00465
00466
00467 static VALUE
00468 fdbm_clear(VALUE obj)
00469 {
00470 datum key;
00471 struct dbmdata *dbmp;
00472 DBM *dbm;
00473
00474 fdbm_modify(obj);
00475 GetDBM2(obj, dbmp, dbm);
00476 dbmp->di_size = -1;
00477 while (key = dbm_firstkey(dbm), key.dptr) {
00478 if (dbm_delete(dbm, key)) {
00479 rb_raise(rb_eDBMError, "dbm_delete failed");
00480 }
00481 }
00482 dbmp->di_size = 0;
00483
00484 return obj;
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494 static VALUE
00495 fdbm_invert(VALUE obj)
00496 {
00497 datum key, val;
00498 struct dbmdata *dbmp;
00499 DBM *dbm;
00500 VALUE keystr, valstr;
00501 VALUE hash = rb_hash_new();
00502
00503 GetDBM2(obj, dbmp, dbm);
00504 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00505 val = dbm_fetch(dbm, key);
00506 keystr = rb_tainted_str_new(key.dptr, key.dsize);
00507 valstr = rb_tainted_str_new(val.dptr, val.dsize);
00508 rb_hash_aset(hash, valstr, keystr);
00509 }
00510 return hash;
00511 }
00512
00513 static VALUE fdbm_store(VALUE,VALUE,VALUE);
00514
00515 static VALUE
00516 update_i(VALUE pair, VALUE dbm)
00517 {
00518 Check_Type(pair, T_ARRAY);
00519 if (RARRAY_LEN(pair) < 2) {
00520 rb_raise(rb_eArgError, "pair must be [key, value]");
00521 }
00522 fdbm_store(dbm, RARRAY_PTR(pair)[0], RARRAY_PTR(pair)[1]);
00523 return Qnil;
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 static VALUE
00535 fdbm_update(VALUE obj, VALUE other)
00536 {
00537 rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
00538 return obj;
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 static VALUE
00550 fdbm_replace(VALUE obj, VALUE other)
00551 {
00552 fdbm_clear(obj);
00553 rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
00554 return obj;
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 static VALUE
00566 fdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
00567 {
00568 datum key, val;
00569 struct dbmdata *dbmp;
00570 DBM *dbm;
00571
00572 fdbm_modify(obj);
00573 keystr = rb_obj_as_string(keystr);
00574 valstr = rb_obj_as_string(valstr);
00575
00576 key.dptr = RSTRING_PTR(keystr);
00577 key.dsize = (int)RSTRING_LEN(keystr);
00578
00579 val.dptr = RSTRING_PTR(valstr);
00580 val.dsize = (int)RSTRING_LEN(valstr);
00581
00582 GetDBM2(obj, dbmp, dbm);
00583 dbmp->di_size = -1;
00584 if (dbm_store(dbm, key, val, DBM_REPLACE)) {
00585 #ifdef HAVE_DBM_CLEARERR
00586 dbm_clearerr(dbm);
00587 #endif
00588 if (errno == EPERM) rb_sys_fail(0);
00589 rb_raise(rb_eDBMError, "dbm_store failed");
00590 }
00591
00592 return valstr;
00593 }
00594
00595
00596
00597
00598
00599
00600
00601 static VALUE
00602 fdbm_length(VALUE obj)
00603 {
00604 datum key;
00605 struct dbmdata *dbmp;
00606 DBM *dbm;
00607 int i = 0;
00608
00609 GetDBM2(obj, dbmp, dbm);
00610 if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
00611
00612 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00613 i++;
00614 }
00615 dbmp->di_size = i;
00616
00617 return INT2FIX(i);
00618 }
00619
00620
00621
00622
00623
00624
00625
00626 static VALUE
00627 fdbm_empty_p(VALUE obj)
00628 {
00629 datum key;
00630 struct dbmdata *dbmp;
00631 DBM *dbm;
00632 int i = 0;
00633
00634 GetDBM2(obj, dbmp, dbm);
00635 if (dbmp->di_size < 0) {
00636 dbm = dbmp->di_dbm;
00637
00638 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00639 i++;
00640 }
00641 }
00642 else {
00643 i = (int)dbmp->di_size;
00644 }
00645 if (i == 0) return Qtrue;
00646 return Qfalse;
00647 }
00648
00649
00650
00651
00652
00653
00654
00655 static VALUE
00656 fdbm_each_value(VALUE obj)
00657 {
00658 datum key, val;
00659 struct dbmdata *dbmp;
00660 DBM *dbm;
00661
00662 RETURN_ENUMERATOR(obj, 0, 0);
00663
00664 GetDBM2(obj, dbmp, dbm);
00665 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00666 val = dbm_fetch(dbm, key);
00667 rb_yield(rb_tainted_str_new(val.dptr, val.dsize));
00668 GetDBM2(obj, dbmp, dbm);
00669 }
00670 return obj;
00671 }
00672
00673
00674
00675
00676
00677
00678
00679 static VALUE
00680 fdbm_each_key(VALUE obj)
00681 {
00682 datum key;
00683 struct dbmdata *dbmp;
00684 DBM *dbm;
00685
00686 RETURN_ENUMERATOR(obj, 0, 0);
00687
00688 GetDBM2(obj, dbmp, dbm);
00689 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00690 rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
00691 GetDBM2(obj, dbmp, dbm);
00692 }
00693 return obj;
00694 }
00695
00696
00697
00698
00699
00700
00701
00702
00703 static VALUE
00704 fdbm_each_pair(VALUE obj)
00705 {
00706 datum key, val;
00707 DBM *dbm;
00708 struct dbmdata *dbmp;
00709 VALUE keystr, valstr;
00710
00711 RETURN_ENUMERATOR(obj, 0, 0);
00712
00713 GetDBM2(obj, dbmp, dbm);
00714
00715 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00716 val = dbm_fetch(dbm, key);
00717 keystr = rb_tainted_str_new(key.dptr, key.dsize);
00718 valstr = rb_tainted_str_new(val.dptr, val.dsize);
00719 rb_yield(rb_assoc_new(keystr, valstr));
00720 GetDBM2(obj, dbmp, dbm);
00721 }
00722
00723 return obj;
00724 }
00725
00726
00727
00728
00729
00730
00731
00732 static VALUE
00733 fdbm_keys(VALUE obj)
00734 {
00735 datum key;
00736 struct dbmdata *dbmp;
00737 DBM *dbm;
00738 VALUE ary;
00739
00740 GetDBM2(obj, dbmp, dbm);
00741
00742 ary = rb_ary_new();
00743 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00744 rb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize));
00745 }
00746
00747 return ary;
00748 }
00749
00750
00751
00752
00753
00754
00755
00756 static VALUE
00757 fdbm_values(VALUE obj)
00758 {
00759 datum key, val;
00760 struct dbmdata *dbmp;
00761 DBM *dbm;
00762 VALUE ary;
00763
00764 GetDBM2(obj, dbmp, dbm);
00765 ary = rb_ary_new();
00766 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00767 val = dbm_fetch(dbm, key);
00768 rb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize));
00769 }
00770
00771 return ary;
00772 }
00773
00774
00775
00776
00777
00778
00779
00780 static VALUE
00781 fdbm_has_key(VALUE obj, VALUE keystr)
00782 {
00783 datum key, val;
00784 struct dbmdata *dbmp;
00785 DBM *dbm;
00786
00787 ExportStringValue(keystr);
00788 key.dptr = RSTRING_PTR(keystr);
00789 key.dsize = (int)RSTRING_LEN(keystr);
00790
00791 GetDBM2(obj, dbmp, dbm);
00792 val = dbm_fetch(dbm, key);
00793 if (val.dptr) return Qtrue;
00794 return Qfalse;
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804 static VALUE
00805 fdbm_has_value(VALUE obj, VALUE valstr)
00806 {
00807 datum key, val;
00808 struct dbmdata *dbmp;
00809 DBM *dbm;
00810
00811 ExportStringValue(valstr);
00812 val.dptr = RSTRING_PTR(valstr);
00813 val.dsize = (int)RSTRING_LEN(valstr);
00814
00815 GetDBM2(obj, dbmp, dbm);
00816 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00817 val = dbm_fetch(dbm, key);
00818 if (val.dsize == (int)RSTRING_LEN(valstr) &&
00819 memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
00820 return Qtrue;
00821 }
00822 return Qfalse;
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832 static VALUE
00833 fdbm_to_a(VALUE obj)
00834 {
00835 datum key, val;
00836 struct dbmdata *dbmp;
00837 DBM *dbm;
00838 VALUE ary;
00839
00840 GetDBM2(obj, dbmp, dbm);
00841 ary = rb_ary_new();
00842 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00843 val = dbm_fetch(dbm, key);
00844 rb_ary_push(ary, rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
00845 rb_tainted_str_new(val.dptr, val.dsize)));
00846 }
00847
00848 return ary;
00849 }
00850
00851
00852
00853
00854
00855
00856
00857
00858 static VALUE
00859 fdbm_to_hash(VALUE obj)
00860 {
00861 datum key, val;
00862 struct dbmdata *dbmp;
00863 DBM *dbm;
00864 VALUE hash;
00865
00866 GetDBM2(obj, dbmp, dbm);
00867 hash = rb_hash_new();
00868 for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
00869 val = dbm_fetch(dbm, key);
00870 rb_hash_aset(hash, rb_tainted_str_new(key.dptr, key.dsize),
00871 rb_tainted_str_new(val.dptr, val.dsize));
00872 }
00873
00874 return hash;
00875 }
00876
00877
00878
00879
00880
00881
00882
00883
00884 static VALUE
00885 fdbm_reject(VALUE obj)
00886 {
00887 return rb_hash_delete_if(fdbm_to_hash(obj));
00888 }
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 void
00953 Init_dbm(void)
00954 {
00955 rb_cDBM = rb_define_class("DBM", rb_cObject);
00956
00957
00958
00959 rb_eDBMError = rb_define_class("DBMError", rb_eStandardError);
00960 rb_include_module(rb_cDBM, rb_mEnumerable);
00961
00962 rb_define_alloc_func(rb_cDBM, fdbm_alloc);
00963 rb_define_singleton_method(rb_cDBM, "open", fdbm_s_open, -1);
00964
00965 rb_define_method(rb_cDBM, "initialize", fdbm_initialize, -1);
00966 rb_define_method(rb_cDBM, "close", fdbm_close, 0);
00967 rb_define_method(rb_cDBM, "closed?", fdbm_closed, 0);
00968 rb_define_method(rb_cDBM, "[]", fdbm_aref, 1);
00969 rb_define_method(rb_cDBM, "fetch", fdbm_fetch_m, -1);
00970 rb_define_method(rb_cDBM, "[]=", fdbm_store, 2);
00971 rb_define_method(rb_cDBM, "store", fdbm_store, 2);
00972 rb_define_method(rb_cDBM, "index", fdbm_index, 1);
00973 rb_define_method(rb_cDBM, "key", fdbm_key, 1);
00974 rb_define_method(rb_cDBM, "select", fdbm_select, 0);
00975 rb_define_method(rb_cDBM, "values_at", fdbm_values_at, -1);
00976 rb_define_method(rb_cDBM, "length", fdbm_length, 0);
00977 rb_define_method(rb_cDBM, "size", fdbm_length, 0);
00978 rb_define_method(rb_cDBM, "empty?", fdbm_empty_p, 0);
00979 rb_define_method(rb_cDBM, "each", fdbm_each_pair, 0);
00980 rb_define_method(rb_cDBM, "each_value", fdbm_each_value, 0);
00981 rb_define_method(rb_cDBM, "each_key", fdbm_each_key, 0);
00982 rb_define_method(rb_cDBM, "each_pair", fdbm_each_pair, 0);
00983 rb_define_method(rb_cDBM, "keys", fdbm_keys, 0);
00984 rb_define_method(rb_cDBM, "values", fdbm_values, 0);
00985 rb_define_method(rb_cDBM, "shift", fdbm_shift, 0);
00986 rb_define_method(rb_cDBM, "delete", fdbm_delete, 1);
00987 rb_define_method(rb_cDBM, "delete_if", fdbm_delete_if, 0);
00988 rb_define_method(rb_cDBM, "reject!", fdbm_delete_if, 0);
00989 rb_define_method(rb_cDBM, "reject", fdbm_reject, 0);
00990 rb_define_method(rb_cDBM, "clear", fdbm_clear, 0);
00991 rb_define_method(rb_cDBM,"invert", fdbm_invert, 0);
00992 rb_define_method(rb_cDBM,"update", fdbm_update, 1);
00993 rb_define_method(rb_cDBM,"replace", fdbm_replace, 1);
00994
00995 rb_define_method(rb_cDBM, "include?", fdbm_has_key, 1);
00996 rb_define_method(rb_cDBM, "has_key?", fdbm_has_key, 1);
00997 rb_define_method(rb_cDBM, "member?", fdbm_has_key, 1);
00998 rb_define_method(rb_cDBM, "has_value?", fdbm_has_value, 1);
00999 rb_define_method(rb_cDBM, "key?", fdbm_has_key, 1);
01000 rb_define_method(rb_cDBM, "value?", fdbm_has_value, 1);
01001
01002 rb_define_method(rb_cDBM, "to_a", fdbm_to_a, 0);
01003 rb_define_method(rb_cDBM, "to_hash", fdbm_to_hash, 0);
01004
01005
01006 rb_define_const(rb_cDBM, "READER", INT2FIX(O_RDONLY|RUBY_DBM_RW_BIT));
01007
01008
01009 rb_define_const(rb_cDBM, "WRITER", INT2FIX(O_RDWR|RUBY_DBM_RW_BIT));
01010
01011
01012
01013
01014 rb_define_const(rb_cDBM, "WRCREAT", INT2FIX(O_RDWR|O_CREAT|RUBY_DBM_RW_BIT));
01015
01016
01017
01018
01019
01020 rb_define_const(rb_cDBM, "NEWDB", INT2FIX(O_RDWR|O_CREAT|O_TRUNC|RUBY_DBM_RW_BIT));
01021
01022 #if defined(HAVE_DB_VERSION)
01023
01024 rb_define_const(rb_cDBM, "VERSION", rb_str_new2(db_version(NULL, NULL, NULL)));
01025 #elif defined(HAVE_GDBM_VERSION)
01026
01027 rb_define_const(rb_cDBM, "VERSION", rb_str_new2(gdbm_version));
01028 #elif defined(HAVE_LIBVAR_GDBM_VERSION)
01029
01030
01031 {
01032 RUBY_EXTERN char *gdbm_version;
01033 rb_define_const(rb_cDBM, "VERSION", rb_str_new2(gdbm_version));
01034 }
01035 #elif defined(HAVE_DPVERSION)
01036 rb_define_const(rb_cDBM, "VERSION", rb_sprintf("QDBM %s", dpversion));
01037 #elif defined(_DB_H_)
01038 rb_define_const(rb_cDBM, "VERSION", rb_str_new2("Berkeley DB (unknown)"));
01039 #else
01040 rb_define_const(rb_cDBM, "VERSION", rb_str_new2("unknown"));
01041 #endif
01042 }
01043