VALUE
rb_struct_aref(VALUE s, VALUE idx)
{
    long i;

    if (RB_TYPE_P(idx, T_SYMBOL)) {
        return rb_struct_aref_id(s, SYM2ID(idx));
    }
    else 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_aref_id(s, id);
    }

    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));
    return RSTRUCT_GET(s, i);
}
static VALUE
rb_struct_select(int argc, VALUE *argv, VALUE s)
{
    VALUE result;
    long i;

    rb_check_arity(argc, 0, 0);
    RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
    result = rb_ary_new();
    for (i = 0; i < RSTRUCT_LEN(s); i++) {
        if (RTEST(rb_yield(RSTRUCT_GET(s, i)))) {
            rb_ary_push(result, RSTRUCT_GET(s, i));
        }
    }

    return result;
}
Beispiel #3
0
static VALUE
get_array(VALUE obj, int idx)
{
    VALUE ary = RSTRUCT_GET(obj, idx);
    if (!RB_TYPE_P(ary, T_ARRAY)) {
	rb_raise(rb_eTypeError, "%+"PRIsVALUE" not initialized", obj);
    }
    return ary;
}
static VALUE
rb_struct_each(VALUE s)
{
    long i;

    RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
    for (i=0; i<RSTRUCT_LEN(s); i++) {
        rb_yield(RSTRUCT_GET(s, i));
    }
    return s;
}
static VALUE
rb_struct_to_h(VALUE s)
{
    VALUE h = rb_hash_new();
    VALUE members = rb_struct_members(s);
    long i;

    for (i=0; i<RSTRUCT_LEN(s); i++) {
        rb_hash_aset(h, rb_ary_entry(members, i), RSTRUCT_GET(s, i));
    }
    return h;
}
static VALUE
rb_struct_aref_id(VALUE s, ID id)
{
    VALUE members = rb_struct_members(s);
    long i, len = RARRAY_LEN(members);

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

    UNREACHABLE;
}
static VALUE
rb_struct_each_pair(VALUE s)
{
    VALUE members;
    long i;

    RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
    members = rb_struct_members(s);
    if (rb_block_arity() > 1) {
        for (i=0; i<RSTRUCT_LEN(s); i++) {
            VALUE key = rb_ary_entry(members, i);
            VALUE value = RSTRUCT_GET(s, i);
            rb_yield_values(2, key, value);
        }
    }
    else {
        for (i=0; i<RSTRUCT_LEN(s); i++) {
            VALUE key = rb_ary_entry(members, i);
            VALUE value = RSTRUCT_GET(s, i);
            rb_yield(rb_assoc_new(key, value));
        }
    }
    return s;
}
/* :nodoc: */
VALUE
rb_struct_init_copy(VALUE copy, VALUE s)
{
    long i, len;

    if (!OBJ_INIT_COPY(copy, s)) return copy;
    if (RSTRUCT_LEN(copy) != RSTRUCT_LEN(s)) {
        rb_raise(rb_eTypeError, "struct size mismatch");
    }

    for (i=0, len=RSTRUCT_LEN(copy); i<len; i++) {
        RSTRUCT_SET(copy, i, RSTRUCT_GET(s, i));
    }

    return copy;
}
VALUE
rb_struct_getmember(VALUE obj, ID id)
{
    VALUE members, slot;
    long i, len;

    members = rb_struct_members(obj);
    slot = ID2SYM(id);
    len = RARRAY_LEN(members);
    for (i=0; i<len; i++) {
        if (RARRAY_AREF(members, i) == slot) {
            return RSTRUCT_GET(obj, i);
        }
    }
    rb_name_error(id, "%s is not struct member", rb_id2name(id));

    UNREACHABLE;
}
static VALUE
inspect_struct(VALUE s, VALUE dummy, int recur)
{
    VALUE cname = rb_class_name(rb_obj_class(s));
    VALUE members, str = rb_str_new2("#<struct ");
    long i, len;
    char first = RSTRING_PTR(cname)[0];

    if (recur || first != '#') {
        rb_str_append(str, cname);
    }
    if (recur) {
        return rb_str_cat2(str, ":...>");
    }

    members = rb_struct_members(s);
    len = RSTRUCT_LEN(s);

    for (i=0; i<len; i++) {
        VALUE slot;
        ID id;

        if (i > 0) {
            rb_str_cat2(str, ", ");
        }
        else if (first != '#') {
            rb_str_cat2(str, " ");
        }
        slot = RARRAY_AREF(members, i);
        id = SYM2ID(slot);
        if (rb_is_local_id(id) || rb_is_const_id(id)) {
            rb_str_append(str, rb_id2str(id));
        }
        else {
            rb_str_append(str, rb_inspect(slot));
        }
        rb_str_cat2(str, "=");
        rb_str_append(str, rb_inspect(RSTRUCT_GET(s, i)));
    }
    rb_str_cat2(str, ">");
    OBJ_INFECT(str, s);

    return str;
}
static VALUE rb_struct_ref9(VALUE obj) {
    return RSTRUCT_GET(obj, 9);
}
Beispiel #12
0
// Range类型支持
QVector<QVariant> MarshallRuby::VALUE2Variant2(VALUE v)
{
    QVector<QVariant> rvs(1);
    QVariant rv;
    QString str, str2;
    void *ci = NULL;
    QObject *obj = NULL;

    VALUE v1;
    VALUE v2;
    VALUE v3;
    
    switch (TYPE(v)) {
    case T_NONE:  rv = QVariant(); break;
    case T_FIXNUM: rv = (int)FIX2INT(v); break;
    case T_STRING:  rv = RSTRING_PTR(v); break;
    case T_FLOAT:  rv = RFLOAT_VALUE(v); break;
    case T_NIL:   rv = 0; break;
    case T_TRUE:  rv = true; break;
    case T_FALSE: rv = false; break;
    case T_OBJECT:
        str = QString(rb_class2name(RBASIC_CLASS(v)));
        ci = Qom::inst()->getObject(v);
        // obj = dynamic_cast<QObject*>(ci);
        qDebug()<<"unimpl VALUE:"<<str<<ci<<obj;
        // rv = QVariant(QMetaType::VoidStar, ci);
        rv = QVariant::fromValue(ci);
        break;
    case T_ARRAY: {
        QStringList ary;
        // ary << "a123" << "b3456";
        qDebug()<<RARRAY_LEN(v)<<QT_VERSION;
        for (int i = 0; i < RARRAY_LEN(v); i++) {
            // FIXME: 也可能是对象数组,如Qt5::QString,但toString方法不好用。
            // FIXME: 如,[Qt5::QApplication.translate("MainWindow", "acbc", nil), "efgggggg", "hijjjjjjjj"]
            ary << VALUE2Variant(rb_ary_entry(v, i)).toString();
        }
        rv = QVariant(ary);
    }; break;
    case T_STRUCT: {
        str = rb_class2name(RBASIC_CLASS(v));
        if (str == "Range") {
            // qDebug()<<"Range is struct???"<<BUILTIN_TYPE(v)
            //         <<rb_class2name(RBASIC_CLASS(v))
            //         <<RSTRUCT_LEN(v);
            v1 = RSTRUCT_GET(v, 0);
            v2 = RSTRUCT_GET(v, 1);
            v3 = RSTRUCT_GET(v, 2);
            // qDebug()<<TYPE(v1)<<TYPE(v2)<<TYPE(v3);
            // qDebug()<<FIX2INT(v1)<<FIX2INT(v2);

            rv = QVariant(FIX2INT(v1));
            rvs.append(QVariant(FIX2INT(v2)));
        } else {
            qDebug()<<"unsupported struct type:"<<str;
        }
    }; break;
    case T_CLASS:
    default:
        qDebug()<<"unknown VALUE type:"<<TYPE(v);
        break;
    }
    
    rvs[0] = rv;
    return (rvs);
}