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; }
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); }
// 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); }