ext/sdbm/init.c


DEFINITIONS

This source file includes following functions.
  1. closed_sdbm
  2. free_sdbm
  3. fsdbm_close
  4. fsdbm_s_new
  5. fsdbm_initialize
  6. fsdbm_s_open
  7. fsdbm_fetch
  8. fsdbm_aref
  9. fsdbm_fetch_m
  10. fsdbm_index
  11. fsdbm_indexes
  12. fsdbm_select
  13. fsdbm_delete
  14. fsdbm_shift
  15. fsdbm_delete_if
  16. fsdbm_clear
  17. fsdbm_invert
  18. each_pair
  19. update_i
  20. fsdbm_update
  21. fsdbm_replace
  22. fsdbm_store
  23. fsdbm_length
  24. fsdbm_empty_p
  25. fsdbm_each_value
  26. fsdbm_each_key
  27. fsdbm_each_pair
  28. fsdbm_keys
  29. fsdbm_values
  30. fsdbm_has_key
  31. fsdbm_has_value
  32. fsdbm_to_a
  33. fsdbm_to_hash
  34. fsdbm_reject
  35. Init_sdbm


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