Ruby 1.9.3p327(2012-11-10revision37606)
|
00001 #include <ruby.h> 00002 #include <ruby/st.h> 00003 00004 static void 00005 numhash_free(void *ptr) 00006 { 00007 if (ptr) st_free_table(ptr); 00008 } 00009 00010 static VALUE 00011 numhash_alloc(VALUE klass) 00012 { 00013 return Data_Wrap_Struct(klass, 0, numhash_free, 0); 00014 } 00015 00016 static VALUE 00017 numhash_init(VALUE self) 00018 { 00019 st_table *tbl = (st_table *)DATA_PTR(self); 00020 if (tbl) st_free_table(tbl); 00021 DATA_PTR(self) = st_init_numtable(); 00022 return self; 00023 } 00024 00025 static VALUE 00026 numhash_aref(VALUE self, VALUE key) 00027 { 00028 st_data_t data; 00029 if (!SPECIAL_CONST_P(key)) rb_raise(rb_eArgError, "not a special const"); 00030 if (st_lookup((st_table *)DATA_PTR(self), (st_data_t)key, &data)) 00031 return (VALUE)data; 00032 return Qnil; 00033 } 00034 00035 static VALUE 00036 numhash_aset(VALUE self, VALUE key, VALUE data) 00037 { 00038 if (!SPECIAL_CONST_P(key)) rb_raise(rb_eArgError, "not a special const"); 00039 if (!SPECIAL_CONST_P(data)) rb_raise(rb_eArgError, "not a special const"); 00040 st_insert((st_table *)DATA_PTR(self), (st_data_t)key, (st_data_t)data); 00041 return self; 00042 } 00043 00044 static int 00045 numhash_i(st_data_t key, st_data_t value, st_data_t arg, int error) 00046 { 00047 VALUE ret; 00048 if (key == 0 && value == 0 && error == 1) rb_raise(rb_eRuntimeError, "numhash modified"); 00049 ret = rb_yield_values(3, (VALUE)key, (VALUE)value, (VALUE)arg); 00050 if (ret == Qtrue) return ST_CHECK; 00051 return ST_CONTINUE; 00052 } 00053 00054 static VALUE 00055 numhash_each(VALUE self) 00056 { 00057 return st_foreach((st_table *)DATA_PTR(self), numhash_i, self) ? Qtrue : Qfalse; 00058 } 00059 00060 void 00061 Init_numhash(void) 00062 { 00063 VALUE st = rb_define_class_under(rb_define_module("Bug"), "StNumHash", rb_cData); 00064 rb_define_alloc_func(st, numhash_alloc); 00065 rb_define_method(st, "initialize", numhash_init, 0); 00066 rb_define_method(st, "[]", numhash_aref, 1); 00067 rb_define_method(st, "[]=", numhash_aset, 2); 00068 rb_define_method(st, "each", numhash_each, 0); 00069 } 00070