%module DBM %{ #include #include %} // map datum to String %typemap(ruby,in) datum *(datum temp) { $target = &temp; $target->dptr = STR2CSTR($source); $target->dsize = RSTRING($source)->len; } %typemap(ruby,out) datum { $target = rb_str_new($source->dptr, $source->dsize); } typedef struct dbm { // Class constants const int INSERT = DBM_INSERT; const int REPLACE = DBM_REPLACE; %addmethods { // Constructor. Called when DBM.new is invoked in Ruby. DBM(char *name, int flags = O_RDWR | O_CREAT, int mode = 0666) { return dbm_open(name, flags, mode); } // Destrcutor. Called when object is garbage-collected in Ruby. ~DBM() { dbm_close(self); } // Class method wrapping dbm_open. static DBM *open(char *name, int flags = O_RDWR|O_CREAT, int mode = 0666); // Instance methods wrapping existing C functions. void close(); int store(datum key, datum content, int flag = DBM_REPLACE); datum fetch(datum key); #ifdef SWIGRUBY // Ruby specific code // Instance methods wrapping given C code. // `DBM *self' is always available. VALUE keys() { datum key; VALUE ary; ary = rb_ary_new(); for (key = dbm_firstkey(self); key.dptr; key = dbm_nextkey(self)) { rb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize)); } return ary; } VALUE values() { datum key, val; VALUE ary; ary = rb_ary_new(); for (key = dbm_firstkey(self); key.dptr; key = dbm_nextkey(self)) { val = dbm_fetch(self, key); rb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize)); } return ary; } void each() { datum key, val; VALUE ary; for (key = dbm_firstkey(self); key.dptr; key = dbm_nextkey(self)) { val = dbm_fetch(self, key); ary = rb_ary_new(); rb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize)); rb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize)); rb_yield(ary); } } int has_key(datum key) { return(dbm_fetch(self, key).dptr != NULL); } // `pred' pragma // predicate returns true/false and is suffixed with '?' %pragma(ruby) pred = "has_key"; #endif } // Swig %name directive cannot handle operator like method name. // So ruby module provides `alias' pragma. %pragma(ruby) alias = "[] fetch"; %pragma(ruby) alias = "[]= store "; // `close' method means release of the resource. // So further access to such a resource must raise exception. %pragma(ruby) free = "close"; // `include' pragma. %pragma(ruby) include = "Enumerable"; } DBM;