mrb_value mrb_struct_aset(mrb_state *mrb, mrb_value s) { long i; mrb_value idx; mrb_value val; mrb_get_args(mrb, "oo", &idx, &val); if (mrb_type(idx) == MRB_TT_STRING || mrb_type(idx) == MRB_TT_SYMBOL) { return mrb_struct_aset_id(mrb, s, mrb_to_id(mrb, idx), val); } i = mrb_fixnum(idx); if (i < 0) i = RSTRUCT_LEN(s) + i; if (i < 0) { mrb_raise(mrb, E_INDEX_ERROR, "offset %ld too small for struct(size:%ld)", i, RSTRUCT_LEN(s)); } if (RSTRUCT_LEN(s) <= i) { mrb_raise(mrb, E_INDEX_ERROR, "offset %ld too large for struct(size:%ld)", i, RSTRUCT_LEN(s)); } mrb_struct_modify(s); return RSTRUCT_PTR(s)[i] = val; }
static mrb_value mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val) { const char *name; int i, len; mrb_sym mid; mrb_value members, slot, *ptr, *ptr_members; /* get base id */ name = mrb_sym2name_len(mrb, mrb->ci->mid, &len); mid = mrb_intern2(mrb, name, len-1); /* omit last "=" */ members = mrb_struct_members(mrb, obj); ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); mrb_struct_modify(obj); ptr = RSTRUCT_PTR(obj); for (i=0; i<len; i++) { slot = ptr_members[i]; if (SYM2ID(slot) == mid) { return ptr[i] = val; } } mrb_name_error(mrb, mid, "`%s' is not a struct member", mrb_sym2name(mrb, mid)); return mrb_nil_value(); /* not reached */ }
static mrb_value mrb_struct_initialize_withArg(mrb_state *mrb, int argc, mrb_value *argv, mrb_value self) { struct RClass *klass = mrb_obj_class(mrb, self); int n; struct RStruct *st; mrb_struct_modify(self); n = num_members(mrb, klass); if (n < argc) { mrb_raise(mrb, E_ARGUMENT_ERROR, "struct size differs"); } st = RSTRUCT(self); st->ptr = (mrb_value *)mrb_calloc(mrb, sizeof(mrb_value), n); st->len = n; memcpy(st->ptr, argv, sizeof(mrb_value)*argc); return self; }
static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) { mrb_value members, *ptr; const mrb_value *ptr_members; mrb_int i, len; members = struct_members(mrb, s); len = RARRAY_LEN(members); ptr = RSTRUCT_PTR(s); ptr_members = RARRAY_PTR(members); for (i=0; i<len; i++) { if (mrb_symbol(ptr_members[i]) == id) { mrb_struct_modify(mrb, s); ptr[i] = val; return val; } } mrb_name_error(mrb, id, "no member '%S' in struct", mrb_sym2str(mrb, id)); return val; /* not reach */ }
static mrb_value mrb_struct_initialize_withArg(mrb_state *mrb, int argc, mrb_value *argv, mrb_value self) { struct RClass *klass = mrb_obj_class(mrb, self); long n; struct RStruct *st; mrb_struct_modify(self); n = num_members(mrb, klass); if (n < argc) { mrb_raise(mrb, E_ARGUMENT_ERROR, "struct size differs"); } st = RSTRUCT(self); st->ptr = malloc(sizeof(mrb_value)*argc); st->len = n; memcpy(st->ptr, argv, sizeof(mrb_value)*argc); //if (n > argc) { // mrb_mem_clear(RSTRUCT_PTR(self)+argc, n-argc); //} return self; }
static mrb_value mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val) { mrb_value members, slot, *ptr, *ptr_members; long i, len; members = mrb_struct_members(mrb, obj); ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); mrb_struct_modify(obj); ptr = RSTRUCT_PTR(obj); for (i=0; i<len; i++) { slot = ptr_members[i]; if (mrb_id_attrset(SYM2ID(slot)) == 0/*rb_frame_this_func(mrb)*/) { return ptr[i] = val; } } mrb_name_error(mrb, 0/*rb_frame_this_func(mrb)*/, "`%s' is not a struct member", mrb_sym2name(mrb, 0/*rb_frame_this_func(mrb)*/)); return mrb_nil_value(); /* not reached */ }
static mrb_value mrb_struct_aset(mrb_state *mrb, mrb_value s) { mrb_int i; mrb_value idx; mrb_value val; mrb_get_args(mrb, "oo", &idx, &val); if (mrb_string_p(idx)) { mrb_value sym = mrb_check_intern_str(mrb, idx); if (mrb_nil_p(sym)) { mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx); } idx = sym; } if (mrb_symbol_p(idx)) { return mrb_struct_aset_sym(mrb, s, mrb_symbol(idx), val); } i = mrb_int(mrb, idx); if (i < 0) i = RSTRUCT_LEN(s) + i; if (i < 0) { mrb_raisef(mrb, E_INDEX_ERROR, "offset %S too small for struct(size:%S)", mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); } if (RSTRUCT_LEN(s) <= i) { mrb_raisef(mrb, E_INDEX_ERROR, "offset %S too large for struct(size:%S)", mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); } mrb_struct_modify(mrb, s); return RSTRUCT_PTR(s)[i] = val; }
static mrb_value mrb_struct_aset_id(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) { mrb_value members, *ptr, *ptr_members; long i, len; members = mrb_struct_members(mrb, s); len = RARRAY_LEN(members); mrb_struct_modify(s); if (RSTRUCT_LEN(s) != len) { mrb_raise(mrb, E_TYPE_ERROR, "struct size differs (%ld required %ld given)", len, RSTRUCT_LEN(s)); } ptr = RSTRUCT_PTR(s); ptr_members = RARRAY_PTR(members); for (i=0; i<len; i++) { if (SYM2ID(ptr_members[i]) == id) { ptr[i] = val; return val; } } mrb_name_error(mrb, id, "no member '%s' in struct", mrb_sym2name(mrb, id)); return val; /* not reach */ }