Пример #1
0
VALUE
rb_struct_aset(VALUE s, VALUE idx, VALUE val)
{
    long i;

    if (RB_TYPE_P(idx, T_SYMBOL)) {
        return rb_struct_aset_id(s, SYM2ID(idx), val);
    }
    if (RB_TYPE_P(idx, T_STRING)) {
        ID id = rb_check_id(&idx);
        if (!id) {
            rb_name_error_str(idx, "no member '%"PRIsVALUE"' in struct",
                              QUOTE(idx));
        }
        return rb_struct_aset_id(s, id, val);
    }

    i = NUM2LONG(idx);
    if (i < 0) i = RSTRUCT_LEN(s) + i;
    if (i < 0) {
        rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
                 i, RSTRUCT_LEN(s));
    }
    if (RSTRUCT_LEN(s) <= i) {
        rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
                 i, RSTRUCT_LEN(s));
    }
    rb_struct_modify(s);
    RSTRUCT_SET(s, i, val);
    return val;
}
Пример #2
0
static VALUE
rb_struct_aset_id(VALUE s, ID id, VALUE val)
{
    VALUE members, *ptr, *ptr_members;
    long i, len;

    members = rb_struct_members(s);
    len = RARRAY_LEN(members);
    rb_struct_modify(s);
    if (RSTRUCT_LEN(s) != len) {
	rb_raise(rb_eTypeError, "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;
	}
    }
    rb_name_error(id, "no member '%s' in struct", rb_id2name(id));

    UNREACHABLE;
}
Пример #3
0
static VALUE
rb_struct_set(VALUE obj, SEL sel, VALUE val)
{
    VALUE members, slot;
    long i;

    // foo=: -> foo
    char buf[100];
    const size_t s = strlcpy(buf, sel_getName(sel), sizeof buf);
    buf[s - 2] = '\0';
    ID field = rb_intern(buf);

    members = rb_struct_members(obj);
    rb_struct_modify(obj);
    for (i=0; i<RARRAY_LEN(members); i++) {
	slot = RARRAY_AT(members, i);
	if (SYM2ID(slot) == field) {
	    GC_WB(&RSTRUCT_PTR(obj)[i], val);
	    return val;
	}
    }
    rb_name_error(rb_frame_this_func(), "`%s' is not a struct member",
		  rb_id2name(field));
    return Qnil;		/* not reached */
}
Пример #4
0
static VALUE
make_struct(VALUE name, VALUE members, VALUE klass)
{
    VALUE nstr;
    ID id;
    long i, len;

    OBJ_FREEZE(members);
    if (NIL_P(name)) {
	nstr = rb_class_new(klass);
#if !WITH_OBJC
	rb_make_metaclass(nstr, RBASIC(klass)->klass);
#endif
	rb_class_inherited(klass, nstr);
    }
    else {
	/* old style: should we warn? */
	name = rb_str_to_str(name);
	id = rb_to_id(name);
	if (!rb_is_const_id(id)) {
	    rb_name_error(id, "identifier %s needs to be constant",
		    StringValuePtr(name));
	}
	if (rb_const_defined_at(klass, id)) {
	    rb_warn("redefining constant Struct::%s", StringValuePtr(name));
	    rb_mod_remove_const(klass, ID2SYM(id));
	}
	nstr = rb_define_class_under(klass, rb_id2name(id), klass);
    }
    rb_ivar_set(nstr, id_members, members);

    rb_objc_define_method(*(VALUE *)nstr, "alloc", struct_alloc, 0);
    rb_objc_define_method(*(VALUE *)nstr, "new", rb_class_new_instance_imp, -1);
    rb_objc_define_method(*(VALUE *)nstr, "[]", rb_class_new_instance_imp, -1);
    rb_objc_define_method(*(VALUE *)nstr, "members", rb_struct_s_members_m, 0);
    len = RARRAY_LEN(members);
    for (i=0; i< len; i++) {
	ID id = SYM2ID(RARRAY_AT(members, i));
	if (rb_is_local_id(id) || rb_is_const_id(id)) {
	    long j = i; /* Needed for block data reference. */
	/* Struct attribute reader */
	rb_objc_define_method(nstr, rb_id2name(id),
		pl_imp_implementationWithBlock(^(VALUE obj) {
		    return RSTRUCT_PTR(obj)[j];
		}), 0);
	/* Struct attribute writer */
	rb_objc_define_method(nstr, rb_id2name(rb_id_attrset(id)),
		pl_imp_implementationWithBlock(^(VALUE obj, VALUE val) {
		    VALUE *ptr = RSTRUCT_PTR(obj);
		    rb_struct_modify(obj);
		    GC_WB(&ptr[i], val);
		    return val;
		}), 1);
Пример #5
0
static VALUE
rb_struct_initialize_m(int argc, VALUE *argv, VALUE self)
{
    VALUE klass = rb_obj_class(self);
    long n;

    rb_struct_modify(self);
    n = num_members(klass);
    if (n < argc) {
	rb_raise(rb_eArgError, "struct size differs");
    }
    MEMCPY(RSTRUCT_PTR(self), argv, VALUE, argc);
    if (n > argc) {
	rb_mem_clear(RSTRUCT_PTR(self)+argc, n-argc);
    }
    return Qnil;
}
Пример #6
0
static VALUE
rb_struct_set(VALUE obj, VALUE val)
{
    VALUE members, slot;
    long i;

    members = rb_struct_members(obj);
    rb_struct_modify(obj);
    for (i=0; i<RARRAY_LEN(members); i++) {
	slot = RARRAY_PTR(members)[i];
	if (rb_id_attrset(SYM2ID(slot)) == rb_frame_this_func()) {
	    return RSTRUCT_PTR(obj)[i] = val;
	}
    }
    rb_name_error(rb_frame_this_func(), "`%s' is not a struct member",
		  rb_id2name(rb_frame_this_func()));
    return Qnil;		/* not reached */
}
Пример #7
0
static VALUE
rb_struct_initialize_m(int argc, const VALUE *argv, VALUE self)
{
    VALUE klass = rb_obj_class(self);
    long i, n;

    rb_struct_modify(self);
    n = num_members(klass);
    if (n < argc) {
        rb_raise(rb_eArgError, "struct size differs");
    }
    for (i=0; i<argc; i++) {
        RSTRUCT_SET(self, i, argv[i]);
    }
    if (n > argc) {
        rb_mem_clear((VALUE *)RSTRUCT_CONST_PTR(self)+argc, n-argc);
    }
    return Qnil;
}
Пример #8
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;
}
Пример #9
0
static VALUE
rb_struct_set(VALUE obj, VALUE val)
{
    VALUE members, slot;
    ID id;
    long i;

    members = rb_struct_members(obj);
    rb_struct_modify(obj);
    id = ruby_frame->orig_func;
    for (i=0; i<RARRAY(members)->len; i++) {
	slot = RARRAY(members)->ptr[i];
	if (rb_id_attrset(SYM2ID(slot)) == id) {
	    return RSTRUCT(obj)->ptr[i] = val;
	}
    }
    rb_name_error(ruby_frame->last_func, "`%s' is not a struct member",
		  rb_id2name(id));
    return Qnil;		/* not reached */
}
Пример #10
0
static VALUE
rb_struct_aset_id(VALUE s, ID id, VALUE val)
{
    VALUE members;
    long i, len;

    members = rb_struct_members(s);
    rb_struct_modify(s);
    len = RARRAY_LEN(members);
    if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) {
	rb_raise(rb_eTypeError, "struct size differs (%ld required %ld given)",
		 RARRAY_LEN(members), RSTRUCT_LEN(s));
    }
    for (i=0; i<len; i++) {
	if (SYM2ID(RARRAY_AT(members, i)) == id) {
	    GC_WB(&RSTRUCT_PTR(s)[i], val);
	    return val;
	}
    }
    rb_name_error(id, "no member '%s' in struct", rb_id2name(id));
}
Пример #11
0
static VALUE
rb_struct_aset_id(VALUE s, ID id, VALUE val)
{
    VALUE members;
    long i, len;

    members = rb_struct_members(s);
    rb_struct_modify(s);
    len = RARRAY(members)->len;
    if (RSTRUCT(s)->len != RARRAY(members)->len) {
	rb_raise(rb_eTypeError, "struct size differs (%d required %d given)",
		 RARRAY(members)->len, RSTRUCT(s)->len);
    }
    for (i=0; i<len; i++) {
	if (SYM2ID(RARRAY(members)->ptr[i]) == id) {
	    RSTRUCT(s)->ptr[i] = val;
	    return val;
	}
    }
    rb_name_error(id, "no member '%s' in struct", rb_id2name(id));
}
Пример #12
0
static VALUE
rb_struct_set(VALUE obj, VALUE val)
{
    VALUE members, slot;
    long i, len;

    members = rb_struct_members(obj);
    len = RARRAY_LEN(members);
    rb_struct_modify(obj);
    for (i=0; i<len; i++) {
        slot = RARRAY_AREF(members, i);
        if (rb_id_attrset(SYM2ID(slot)) == rb_frame_this_func()) {
            RSTRUCT_SET(obj, i, val);
            return val;
        }
    }
    rb_name_error(rb_frame_this_func(), "`%s' is not a struct member",
                  rb_id2name(rb_frame_this_func()));

    UNREACHABLE;
}
Пример #13
0
VALUE
rb_struct_aset(VALUE s, VALUE idx, VALUE val)
{
    long i;

    if (RB_TYPE_P(idx, T_STRING) || RB_TYPE_P(idx, T_SYMBOL)) {
	return rb_struct_aset_id(s, rb_to_id(idx), val);
    }

    i = NUM2LONG(idx);
    if (i < 0) i = RSTRUCT_LEN(s) + i;
    if (i < 0) {
        rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
		 i, RSTRUCT_LEN(s));
    }
    if (RSTRUCT_LEN(s) <= i) {
        rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
		 i, RSTRUCT_LEN(s));
    }
    rb_struct_modify(s);
    return RSTRUCT_PTR(s)[i] = val;
}
Пример #14
0
static VALUE
rb_struct_set(VALUE obj, VALUE val)
{
    VALUE members, slot, *ptr, *ptr_members;
    long i, len;

    members = rb_struct_members(obj);
    ptr_members = RARRAY_PTR(members);
    len = RARRAY_LEN(members);
    rb_struct_modify(obj);
    ptr = RSTRUCT_PTR(obj);
    for (i=0; i<len; i++) {
	slot = ptr_members[i];
	if (rb_id_attrset(SYM2ID(slot)) == rb_frame_this_func()) {
	    return ptr[i] = val;
	}
    }
    rb_name_error(rb_frame_this_func(), "`%s' is not a struct member",
		  rb_id2name(rb_frame_this_func()));

    UNREACHABLE;
}
Пример #15
0
VALUE
rb_struct_aset(VALUE s, VALUE idx, VALUE val)
{
    long i;

    if (TYPE(idx) == T_STRING || TYPE(idx) == T_SYMBOL) {
	return rb_struct_aset_id(s, rb_to_id(idx), val);
    }

    i = NUM2LONG(idx);
    if (i < 0) i = RSTRUCT(s)->len + i;
    if (i < 0) {
        rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
		 i, RSTRUCT(s)->len);
    }
    if (RSTRUCT(s)->len <= i) {
        rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
		 i, RSTRUCT(s)->len);
    }
    rb_struct_modify(s);
    return RSTRUCT(s)->ptr[i] = val;
}
Пример #16
0
static VALUE
rb_struct_aset_id(VALUE s, ID id, VALUE val)
{
    VALUE members = rb_struct_members(s);
    long i, len = RARRAY_LEN(members);

    if (RSTRUCT_LEN(s) != len) {
        rb_raise(rb_eTypeError, "struct size differs (%ld required %ld given)",
                 len, RSTRUCT_LEN(s));
    }

    for (i=0; i<len; i++) {
        if (SYM2ID(RARRAY_AREF(members, i)) == id) {
            rb_struct_modify(s);
            RSTRUCT_SET(s, i, val);
            return val;
        }
    }
    rb_name_error(id, "no member '%s' in struct", rb_id2name(id));

    UNREACHABLE;
}
Пример #17
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;
}
Пример #18
0
static VALUE
rb_struct_aset_imp(VALUE s, SEL sel, VALUE idx, VALUE val)
{
    long i;

    if (TYPE(idx) == T_STRING || TYPE(idx) == T_SYMBOL) {
	return rb_struct_aset_id(s, rb_to_id(idx), val);
    }

    i = NUM2LONG(idx);
    if (i < 0) i = RSTRUCT_LEN(s) + i;
    if (i < 0) {
        rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
		 i, RSTRUCT_LEN(s));
    }
    if (RSTRUCT_LEN(s) <= i) {
        rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
		 i, RSTRUCT_LEN(s));
    }
    rb_struct_modify(s);
    GC_WB(&RSTRUCT_PTR(s)[i], val);
    return val;
}