static VALUE iow_internal_object_id(VALUE self) { VALUE obj = (VALUE)DATA_PTR(self); return rb_obj_id(obj); }
/** * USDT::Probe#name */ static VALUE probe_name(VALUE self) { usdt_probedef_t **p = DATA_PTR(self); usdt_probedef_t *probedef = *p; return ID2SYM(rb_intern(probedef->name)); }
/* * * Solve for the diffusional velocities in the Stefan-Maxwell equations * */ void LiquidTransport::stefan_maxwell_solve() { int i, j, a; doublereal tmp; int VIM = m_nDim; m_B.resize(m_nsp, VIM); //! grab a local copy of the molecular weights const vector_fp& M = m_thermo->molecularWeights(); /* * Update the concentrations in the mixture. */ update_conc(); double T = m_thermo->temperature(); m_thermo->getStandardVolumes(DATA_PTR(volume_specPM_)); m_thermo->getActivityCoefficients(DATA_PTR(actCoeffMolar_)); /* * Calculate the electrochemical potential gradient. This is the * driving force for relative diffusional transport. * * Here we calculate * * c_i * (grad (mu_i) + S_i grad T - M_i / dens * grad P * * This is Eqn. 13-1 p. 318 Newman. The original equation is from * Hershfeld, Curtis, and Bird. * * S_i is the partial molar entropy of species i. This term will cancel * out a lot of the grad T terms in grad (mu_i), therefore simplifying * the expression. * * Ok I think there may be many ways to do this. One way is to do it via basis * functions, at the nodes, as a function of the variables in the problem. * * For calculation of molality based thermo systems, we current get * the molar based values. This may change. * * Note, we have broken the symmetry of the matrix here, due to * consideratins involving species concentrations going to zero. * */ for (i = 0; i < m_nsp; i++) { double xi_denom = m_molefracs_tran[i]; for (a = 0; a < VIM; a++) { m_ck_Grad_mu[a*m_nsp + i] = m_chargeSpecies[i] * concTot_ * Faraday * m_Grad_V[a] + concTot_ * (volume_specPM_[i] - M[i]/dens_) * m_Grad_P[a] + concTot_ * GasConstant * T * m_Grad_lnAC[a*m_nsp+i] / actCoeffMolar_[i] + concTot_ * GasConstant * T * m_Grad_X[a*m_nsp+i] / xi_denom; } } if (m_thermo->activityConvention() == cAC_CONVENTION_MOLALITY) { int iSolvent = 0; double mwSolvent = m_thermo->molecularWeight(iSolvent); double mnaught = mwSolvent/ 1000.; double lnmnaught = log(mnaught); for (i = 1; i < m_nsp; i++) { for (a = 0; a < VIM; a++) { m_ck_Grad_mu[a*m_nsp + i] -= m_concentrations[i] * GasConstant * m_Grad_T[a] * lnmnaught; } } } /* * Just for Note, m_A(i,j) refers to the ith row and jth column. * They are still fortran ordered, so that i varies fastest. */ switch (VIM) { case 1: /* 1-D approximation */ m_B(0,0) = 0.0; for (j = 0; j < m_nsp; j++) { m_A(0,j) = M[j] * m_concentrations[j]; } for (i = 1; i < m_nsp; i++){ m_B(i,0) = m_ck_Grad_mu[i] / (GasConstant * T); m_A(i,i) = 0.0; for (j = 0; j < m_nsp; j++){ if (j != i) { tmp = m_concentrations[j] / m_DiffCoeff_StefMax(i,j); m_A(i,i) += tmp; m_A(i,j) = - tmp; } } } //! invert and solve the system Ax = b. Answer is in m_B solve(m_A, m_B); break; case 2: /* 2-D approximation */ m_B(0,0) = 0.0; m_B(0,1) = 0.0; for (j = 0; j < m_nsp; j++) { m_A(0,j) = M[j] * m_concentrations[j]; } for (i = 1; i < m_nsp; i++){ m_B(i,0) = m_ck_Grad_mu[i] / (GasConstant * T); m_B(i,1) = m_ck_Grad_mu[m_nsp + i] / (GasConstant * T); m_A(i,i) = 0.0; for (j = 0; j < m_nsp; j++) { if (j != i) { tmp = m_concentrations[j] / m_DiffCoeff_StefMax(i,j); m_A(i,i) += tmp; m_A(i,j) = - tmp; } } } //! invert and solve the system Ax = b. Answer is in m_B solve(m_A, m_B); break; case 3: /* 3-D approximation */ m_B(0,0) = 0.0; m_B(0,1) = 0.0; m_B(0,2) = 0.0; for (j = 0; j < m_nsp; j++) { m_A(0,j) = M[j] * m_concentrations[j]; } for (i = 1; i < m_nsp; i++){ m_B(i,0) = m_ck_Grad_mu[i] / (GasConstant * T); m_B(i,1) = m_ck_Grad_mu[m_nsp + i] / (GasConstant * T); m_B(i,2) = m_ck_Grad_mu[2*m_nsp + i] / (GasConstant * T); m_A(i,i) = 0.0; for (j = 0; j < m_nsp; j++) { if (j != i) { tmp = m_concentrations[j] / m_DiffCoeff_StefMax(i,j); m_A(i,i) += tmp; m_A(i,j) = - tmp; } } } //! invert and solve the system Ax = b. Answer is in m_B solve(m_A, m_B); break; default: printf("uninmplemetnd\n"); throw CanteraError("routine", "not done"); break; } for (a = 0; a < VIM; a++) { for (j = 0; j < m_nsp; j++) { m_flux(j,a) = M[j] * m_concentrations[j] * m_B(j,a); } } }
static VALUE Node_init(int argc, VALUE *args, VALUE self) { vx_graph graph = 0; vx_kernel kernel = 0; Check_Type(self, T_DATA); if (argc <= 1) rb_raise(rb_eArgError, "Not enough arguments"); graph = (vx_graph)DATA_PTR(args[0]); if (argc == 2) // Kernel { Check_Type(args[1], T_DATA); kernel = (vx_kernel)DATA_PTR(args[1]); DATA_PTR(self) = (void *)vxCreateGenericNode(graph, kernel); } else if (argc == 3) // graph, [string|enum], array of hashes { vx_node node = 0; VALUE kern = args[1]; VALUE array = args[2]; long param = 0; if (TYPE(kern) == T_STRING) kernel = vxGetKernelByName(context, RSTRING_PTR(kern)); else if (TYPE(kern) == T_FIXNUM) kernel = vxGetKernelByEnum(context, FIX2INT(kern)); else if (TYPE(kern) == T_DATA) // a OpenVX::Kernel kernel = (vx_kernel)DATA_PTR(kern); else rb_raise(rb_eTypeError, "kernel must be a string, fixnum, or OpenVX::Kernel"); if (kernel == 0) rb_raise(rb_eNameError, "kernel could not be found in OpenVX"); Check_Type(array, T_ARRAY); node = vxCreateGenericNode(graph, kernel); if (node == 0) rb_raise(rb_eTypeError, "node could not be created!"); REXT_PRINT("Array of parameters has len = %ld\n", RARRAY_LEN(array)); for (param = 0; param < RARRAY_LEN(array) ; param++) { VALUE ref,hash; vx_reference ref2 = 0; vx_status status = 0; const char *name = NULL; hash = rb_ary_entry(array, param); Check_Type(hash, T_HASH); ref = rb_hash_aref(hash, ID2SYM(rb_intern("ref"))); name = rb_obj_classname(ref); REXT_PRINT("ref class = %s\n", name); Check_Type(ref, T_DATA); ref2 = (vx_reference)DATA_PTR(ref); status = vxSetParameterByIndex(node, param, ref2); REXT_PRINT("status = %d\n", status); } DATA_PTR(self) = (void *)node; } else { rb_raise(rb_eArgError, "incorrect number of arguments"); } return Qnil; }
/* 1 - success, 0 - error */ static int set_oci_number_from_num(OCINumber *result, VALUE num, int force, OCIError *errhp) { signed long sl; double dbl; if (!RTEST(rb_obj_is_kind_of(num, rb_cNumeric))) rb_raise(rb_eTypeError, "expect Numeric but %s", rb_class2name(CLASS_OF(num))); if (rb_respond_to(num, id_finite_p) && !RTEST(rb_funcall(num, id_finite_p, 0))) { rb_raise(rb_eTypeError, "cannot accept number which isn't finite."); } switch (rb_type(num)) { case T_FIXNUM: /* set from long. */ sl = NUM2LONG(num); oci_lc(OCINumberFromInt(errhp, &sl, sizeof(sl), OCI_NUMBER_SIGNED, result)); return 1; case T_FLOAT: /* set from double. */ dbl = NUM2DBL(num); oci_lc(OCINumberFromReal(errhp, &dbl, sizeof(dbl), result)); return 1; case T_BIGNUM: /* change via string. */ num = rb_big2str(num, 10); set_oci_number_from_str(result, num, Qnil, Qnil, errhp); return 1; } if (RTEST(rb_obj_is_instance_of(num, cOCINumber))) { /* OCI::Number */ oci_lc(OCINumberAssign(errhp, DATA_PTR(num), result)); return 1; } if (rb_respond_to(num, id_split)) { /* BigDecimal */ VALUE split = rb_funcall(num, id_split, 0); if (TYPE(split) == T_ARRAY && RARRAY_LEN(split) == 4) { /* * sign, significant_digits, base, exponent = num.split * onum = sign * "0.#{significant_digits}".to_f * (base ** exponent) */ VALUE *ary = RARRAY_PTR(split); int sign; OCINumber digits; int exponent; int digits_len; OCINumber work; /* check sign */ if (TYPE(ary[0]) != T_FIXNUM) { goto is_not_big_decimal; } sign = FIX2INT(ary[0]); /* check digits */ StringValue(ary[1]); digits_len = RSTRING_LEN(ary[1]); set_oci_number_from_str(&digits, ary[1], Qnil, Qnil, errhp); /* check base */ if (TYPE(ary[2]) != T_FIXNUM || FIX2LONG(ary[2]) != 10) { goto is_not_big_decimal; } /* check exponent */ if (TYPE(ary[3]) != T_FIXNUM) { goto is_not_big_decimal; } exponent = FIX2INT(ary[3]); if (have_OCINumberShift) { /* Oracle 8.1 or upper */ oci_lc(OCINumberShift(errhp, &digits, exponent - digits_len, &work)); } else { /* Oracle 8.0 */ int n = 10; OCINumber base; OCINumber exp; oci_lc(OCINumberFromInt(errhp, &n, sizeof(n), OCI_NUMBER_SIGNED, &base)); oci_lc(OCINumberIntPower(errhp, &base, exponent - digits_len, &exp)); oci_lc(OCINumberMul(errhp, &digits, &exp, &work)); } if (sign >= 0) { oci_lc(OCINumberAssign(errhp, &work, result)); } else { oci_lc(OCINumberNeg(errhp, &work, result)); } return 1; } } is_not_big_decimal: if (rb_respond_to(num, id_numerator) && rb_respond_to(num, id_denominator)) { /* Rational */ OCINumber numerator; OCINumber denominator; if (set_oci_number_from_num(&numerator, rb_funcall(num, id_numerator, 0), 0, errhp) && set_oci_number_from_num(&denominator, rb_funcall(num, id_denominator, 0), 0, errhp)) { oci_lc(OCINumberDiv(errhp, &numerator, &denominator, result)); return 1; } } if (force) { /* change via string as a last resort. */ /* TODO: if error, raise TypeError instead of OCI::Error */ set_oci_number_from_str(result, num, Qnil, Qnil, errhp); return 1; } return 0; }
static VALUE gdkpango_attr_emboss_color_initialize(VALUE self, VALUE color) { DATA_PTR(self) = gdk_pango_attr_emboss_color_new(RVAL2GDKCOLOR(color)); return Qnil; }
static VALUE gdkpango_attr_stipple_initialize(VALUE self, VALUE stipple) { DATA_PTR(self) = gdk_pango_attr_stipple_new(GDK_BITMAP(RVAL2GOBJ(stipple))); return Qnil; }
static mrb_value mrb_ipvs_service_get_proto(mrb_state *mrb, mrb_value self){ struct mrb_ipvs_entry *ie; ie = DATA_PTR(self); return mrb_str_new_cstr(mrb, ie->svc.protocol == IPPROTO_TCP ? "TCP" : "UDP"); }
static mrb_value mrb_ipvs_service_get_sched_name(mrb_state *mrb, mrb_value self){ struct mrb_ipvs_entry *ie; ie = DATA_PTR(self); return mrb_str_new_cstr(mrb, ie->svc.sched_name); }
static mrb_value mrb_ipvs_dest_get_weight(mrb_state *mrb, mrb_value self){ struct mrb_ipvs_entry *ie; ie = DATA_PTR(self); return mrb_fixnum_value(ie->dest.weight); }
static mrb_value mrb_ipvs_service_get_port(mrb_state *mrb, mrb_value self){ struct mrb_ipvs_entry *ie; ie = DATA_PTR(self); return mrb_fixnum_value(ntohs(ie->svc.port)); }
VALUE rb_data_typed_object_zalloc(VALUE ruby_class, size_t size, const rb_data_type_t *data_type) { VALUE obj = rb_data_typed_object_wrap(ruby_class, 0, data_type); DATA_PTR(obj) = calloc(1, size); return obj; }
mrb_value mrb_servo_initialize(mrb_state *mrb, mrb_value self){ Servo *newServo = new Servo(); DATA_PTR(self) = newServo; DATA_TYPE(self) = &mrb_servo_type; return self; }
/* * call-seq: * XML::Dtd.new("DTD string") -> dtd * XML::Dtd.new("public", "system") -> dtd * XML::Dtd.new("name", "public", "system", document) -> external subset dtd * XML::Dtd.new("name", "public", "system", document, false) -> internal subset dtd * XML::Dtd.new("name", "public", "system", document, true) -> internal subset dtd * * Create a new Dtd from the specified public and system * identifiers. */ static VALUE rxml_dtd_initialize(int argc, VALUE *argv, VALUE self) { VALUE external, system, dtd_string; xmlParserInputBufferPtr buffer; xmlCharEncoding enc = XML_CHAR_ENCODING_NONE; xmlChar *new_string; xmlDtdPtr xdtd; // 1 argument -- string --> parsujeme jako dtd // 2 arguments -- public, system --> bude se hledat // 3 arguments -- public, system, name --> creates an external subset (any parameter may be nil) // 4 arguments -- public, system, name, doc --> creates an external subset (any parameter may be nil) // 5 arguments -- public, system, name, doc, true --> creates an internal subset (all but last parameter may be nil) switch (argc) { case 3: case 4: case 5: { VALUE name, doc, internal; const xmlChar *xname = NULL, *xpublic = NULL, *xsystem = NULL; xmlDocPtr xdoc = NULL; rb_scan_args(argc, argv, "32", &external, &system, &name, &doc, &internal); if (external != Qnil) { Check_Type(external, T_STRING); xpublic = (const xmlChar*) StringValuePtr(external); } if (system != Qnil) { Check_Type(system, T_STRING); xsystem = (const xmlChar*) StringValuePtr(system); } if (name != Qnil) { Check_Type(name, T_STRING); xname = (const xmlChar*) StringValuePtr(name); } if (doc != Qnil) { if (rb_obj_is_kind_of(doc, cXMLDocument) == Qfalse) rb_raise(rb_eTypeError, "Must pass an XML::Document object"); Data_Get_Struct(doc, xmlDoc, xdoc); } if (internal == Qnil || internal == Qfalse) xdtd = xmlNewDtd(xdoc, xname, xpublic, xsystem); else xdtd = xmlCreateIntSubset(xdoc, xname, xpublic, xsystem); if (xdtd == NULL) rxml_raise(&xmlLastError); /* Document will free this dtd now. */ RDATA(self)->dfree = NULL; DATA_PTR(self) = xdtd; xmlSetTreeDoc((xmlNodePtr) xdtd, xdoc); } break; case 2: rb_scan_args(argc, argv, "20", &external, &system); Check_Type(external, T_STRING); Check_Type(system, T_STRING); xdtd = xmlParseDTD((xmlChar*) StringValuePtr(external), (xmlChar*) StringValuePtr(system)); if (xdtd == NULL) rxml_raise(&xmlLastError); DATA_PTR(self) = xdtd; xmlSetTreeDoc((xmlNodePtr) xdtd, NULL); break; case 1: rb_scan_args(argc, argv, "10", &dtd_string); Check_Type(dtd_string, T_STRING); /* Note that buffer is freed by xmlParserInputBufferPush*/ buffer = xmlAllocParserInputBuffer(enc); new_string = xmlStrdup((xmlChar*) StringValuePtr(dtd_string)); xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*) new_string); xdtd = xmlIOParseDTD(NULL, buffer, enc); if (xdtd == NULL) rxml_raise(&xmlLastError); xmlFree(new_string); DATA_PTR(self) = xdtd; break; default: rb_raise(rb_eArgError, "wrong number of arguments"); } return self; }
mrb_value ofRuby3DPrimitive::getZ(mrb_state* mrb, mrb_value self) { Primitive* primivite; primivite = (Primitive*) DATA_PTR(self); return mrb_float_value(mrb, primivite->instance->getZ()); }
static mrb_value mrb_ipvs_service_del(mrb_state *mrb, mrb_value self){ ipvs_del_service(DATA_PTR(self)); return mrb_nil_value(); }
VALUE sws_typed_get_struct_data_ptr(VALUE self, VALUE obj) { struct sample_typed_wrapped_struct* bar; bar = (struct sample_typed_wrapped_struct*) DATA_PTR(obj); return INT2FIX(bar->foo); }
static VALUE rb_mod_define_method(int argc, VALUE *argv, VALUE mod) { ID id; VALUE body; NODE *node; int noex = NOEX_PUBLIC; if (argc == 1) { id = rb_to_id(argv[0]); body = rb_block_lambda(); } else if (argc == 2) { id = rb_to_id(argv[0]); body = argv[1]; if (!rb_obj_is_method(body) && !rb_obj_is_proc(body)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc/Method)", rb_obj_classname(body)); } } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc); } if (RDATA(body)->dmark == (RUBY_DATA_FUNC) bm_mark) { struct METHOD *method = (struct METHOD *)DATA_PTR(body); VALUE rclass = method->rclass; if (rclass != mod) { if (RCLASS_SINGLETON(rclass)) { rb_raise(rb_eTypeError, "can't bind singleton method to a different class"); } if (!RTEST(rb_class_inherited_p(mod, rclass))) { rb_raise(rb_eTypeError, "bind argument must be a subclass of %s", rb_class2name(rclass)); } } node = method->body; } else if (rb_obj_is_proc(body)) { rb_proc_t *proc; body = proc_dup(body); GetProcPtr(body, proc); if (BUILTIN_TYPE(proc->block.iseq) != T_NODE) { proc->block.iseq->defined_method_id = id; proc->block.iseq->klass = mod; proc->is_lambda = Qtrue; proc->is_from_method = Qtrue; } node = NEW_BMETHOD(body); } else { /* type error */ rb_raise(rb_eTypeError, "wrong argument type (expected Proc/Method)"); } /* TODO: visibility */ rb_add_method(mod, id, node, noex); return body; }
static VALUE gdkpango_attr_embossed_initialize(VALUE self, VALUE embossed) { DATA_PTR(self) = gdk_pango_attr_embossed_new(RVAL2CBOOL(embossed)); return Qnil; }
VALUE rb_mpg123_tellframe(VALUE self) { return INT2FIX(mpg123_tellframe(DATA_PTR(self))); }
static VALUE Graph_init(VALUE self) { Check_Type(self, T_DATA); DATA_PTR(self) = (void *)vxCreateGraph(context); return Qnil; }
VALUE rb_mpg123_seek_frame(VALUE self, VALUE offset) { return INT2FIX(mpg123_seek_frame(DATA_PTR(self), FIX2INT(offset), SEEK_SET)); }
static VALUE Target_init(VALUE self, VALUE index) { vx_target target = vxGetTargetByIndex(context, FIX2UINT(index)); DATA_PTR(self) = (void *)target; return Qnil; }
VALUE rb_mpg123_timeframe(VALUE self, VALUE seconds) { return INT2FIX(mpg123_timeframe(DATA_PTR(self), NUM2DBL(seconds))); }
/** * USDT::Probe#function */ static VALUE probe_function(VALUE self) { usdt_probedef_t **p = DATA_PTR(self); usdt_probedef_t *probedef = *p; return ID2SYM(rb_intern(probedef->function)); }
VALUE rb_mpg123_close(VALUE self) { mpg123_close(DATA_PTR(self)); return self; }
/* :nodoc: */ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_reparentee_func prf) { VALUE reparented_obj ; xmlNodePtr reparentee, pivot, reparented, next_text, new_next_text ; if(!rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlNode)) rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node"); if(rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlDocument)) rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node"); Data_Get_Struct(reparentee_obj, xmlNode, reparentee); Data_Get_Struct(pivot_obj, xmlNode, pivot); if(XML_DOCUMENT_NODE == reparentee->type || XML_HTML_DOCUMENT_NODE == reparentee->type) rb_raise(rb_eArgError, "cannot reparent a document node"); xmlUnlinkNode(reparentee); if (reparentee->doc != pivot->doc || reparentee->type == XML_TEXT_NODE) { /* * if the reparentee is a text node, there's a very good chance it will be * merged with an adjacent text node after being reparented, and in that case * libxml will free the underlying C struct. * * since we clearly have a ruby object which references the underlying * memory, we can't let the C struct get freed. let's pickle the original * reparentee by rooting it; and then we'll reparent a duplicate of the * node that we don't care about preserving. * * alternatively, if the reparentee is from a different document than the * pivot node, libxml2 is going to get confused about which document's * "dictionary" the node's strings belong to (this is an otherwise * uninteresting libxml2 implementation detail). as a result, we cannot * reparent the actual reparentee, so we reparent a duplicate. */ NOKOGIRI_ROOT_NODE(reparentee); if (!(reparentee = xmlDocCopyNode(reparentee, pivot->doc, 1))) { rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)"); } } if (reparentee->type == XML_TEXT_NODE && pivot->next && pivot->next->type == XML_TEXT_NODE) { /* * libxml merges text nodes in a right-to-left fashion, meaning that if * there are two text nodes who would be adjacent, the right (or following, * or next) node will be merged into the left (or preceding, or previous) * node. * * and by "merged" I mean the string contents will be concatenated onto the * left node's contents, and then the node will be freed. * * which means that if we have a ruby object wrapped around the right node, * its memory would be freed out from under it. * * so, we detect this edge case and unlink-and-root the text node before it gets * merged. then we dup the node and insert that duplicate back into the * document where the real node was. * * yes, this is totally lame. */ next_text = pivot->next ; new_next_text = xmlDocCopyNode(next_text, pivot->doc, 1) ; xmlUnlinkNode(next_text); NOKOGIRI_ROOT_NODE(next_text); xmlAddNextSibling(pivot, new_next_text); } /* TODO: I really want to remove this. We shouldn't support 2.6.16 anymore */ if ( reparentee->type == XML_TEXT_NODE && pivot->type == XML_TEXT_NODE && is_2_6_16() ) { /* work around a string-handling bug in libxml 2.6.16. we'd rather leak than segfault. */ pivot->content = xmlStrdup(pivot->content); } if(!(reparented = (*prf)(pivot, reparentee))) { rb_raise(rb_eRuntimeError, "Could not reparent node"); } /* * make sure the ruby object is pointed at the just-reparented node, which * might be a duplicate (see above) or might be the result of merging * adjacent text nodes. */ DATA_PTR(reparentee_obj) = reparented ; relink_namespace(reparented); reparented_obj = Nokogiri_wrap_xml_node(Qnil, reparented); rb_funcall(reparented_obj, decorate_bang, 0); return reparented_obj ; }
VALUE rb_mpg123_spf(VALUE self) { return rb_float_new(mpg123_spf(DATA_PTR(self))); }
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8) { DATA_PTR(self.value()) = new T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); }
static VALUE iow_type(VALUE self) { VALUE obj = (VALUE)DATA_PTR(self); return type2sym(BUILTIN_TYPE(obj)); }