示例#1
0
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;
}
示例#2
0
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);
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
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);
}
示例#6
0
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;
}
示例#7
0
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;
}