Ruby 1.9.3p327(2012-11-10revision37606)
ext/-test-/st/numhash/numhash.c
Go to the documentation of this file.
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