static VALUE struct_alloc(VALUE klass) { VALUE size; long n; NEWOBJ(st, struct RStruct); OBJSETUP(st, klass, T_STRUCT); size = rb_struct_iv_get(klass, "__size__"); n = FIX2LONG(size); if (0 < n && n <= RSTRUCT_EMBED_LEN_MAX) { RBASIC(st)->flags &= ~RSTRUCT_EMBED_LEN_MASK; RBASIC(st)->flags |= n << RSTRUCT_EMBED_LEN_SHIFT; rb_mem_clear(st->as.ary, n); } else { if (n > 0) { GC_WB(&st->as.heap.ptr, xmalloc_ptrs(sizeof(VALUE) * n)); rb_mem_clear(st->as.heap.ptr, n); } else { st->as.heap.ptr = NULL; } st->as.heap.len = n; } return (VALUE)st; }
static size_t num_members(VALUE klass) { VALUE members; members = rb_struct_iv_get(klass, "__members__"); if (TYPE(members) != T_ARRAY) { rb_raise(rb_eTypeError, "broken members"); } return RARRAY_LEN(members); }
VALUE rb_struct_s_members(VALUE klass) { VALUE members = rb_struct_iv_get(klass, "__members__"); if (NIL_P(members)) { rb_raise(rb_eTypeError, "uninitialized struct"); } if (TYPE(members) != T_ARRAY) { rb_raise(rb_eTypeError, "corrupted struct"); } return members; }
static VALUE struct_alloc(VALUE klass) { VALUE size; long n; NEWOBJ(st, struct RStruct); OBJSETUP(st, klass, T_STRUCT); size = rb_struct_iv_get(klass, "__size__"); n = FIX2LONG(size); st->ptr = ALLOC_N(VALUE, n); rb_mem_clear(st->ptr, n); st->len = n; return (VALUE)st; }
VALUE rb_struct_new(VALUE klass, ...) { VALUE sz, *mem; long size, i; va_list args; sz = rb_struct_iv_get(klass, "__size__"); size = FIX2LONG(sz); mem = ALLOCA_N(VALUE, size); va_start(args, klass); for (i=0; i<size; i++) { mem[i] = va_arg(args, VALUE); } va_end(args); return rb_class_new_instance(size, mem, klass); }
static VALUE rb_struct_initialize(VALUE self, VALUE values) { VALUE klass = rb_obj_class(self); VALUE size; long n; rb_struct_modify(self); size = rb_struct_iv_get(klass, "__size__"); n = FIX2LONG(size); if (n < RARRAY(values)->len) { rb_raise(rb_eArgError, "struct size differs"); } MEMCPY(RSTRUCT(self)->ptr, RARRAY(values)->ptr, VALUE, RARRAY(values)->len); if (n > RARRAY(values)->len) { rb_mem_clear(RSTRUCT(self)->ptr+RARRAY(values)->len, n-RARRAY(values)->len); } return Qnil; }
VALUE rb_struct_initialize(VALUE self, SEL sel, VALUE values) { VALUE klass = rb_obj_class(self); VALUE size; long n; rb_struct_modify(self); size = rb_struct_iv_get(klass, "__size__"); n = FIX2LONG(size); if (n < RARRAY_LEN(values)) { rb_raise(rb_eArgError, "struct size differs"); } for (int i = 0; i < RARRAY_LEN(values); i++) { GC_WB(&RSTRUCT_PTR(self)[i], RARRAY_AT(values, i)); } if (n > RARRAY_LEN(values)) { for (int i = RARRAY_LEN(values); i < n; i++) { RSTRUCT_PTR(self)[i] = Qnil; } } return Qnil; }