/* * call-seq: * IDN::Punycode.decode(string) => string * * Converts Punycode to a string in UTF-8 format. * * Raises IDN::Punycode::PunycodeError on failure. */ static VALUE decode(VALUE self, VALUE str) { int rc; punycode_uint *ustr; size_t len; char *buf = NULL; VALUE retv; str = rb_check_convert_type(str, T_STRING, "String", "to_s"); len = RSTRING(str)->len; ustr = malloc(len * sizeof(punycode_uint)); if (ustr == NULL) { rb_raise(rb_eNoMemError, "cannot allocate memory (%d bytes)", len); return Qnil; } rc = punycode_decode(RSTRING(str)->len, RSTRING(str)->ptr, &len, ustr, NULL); if (rc != PUNYCODE_SUCCESS) { xfree(ustr); rb_raise(ePunycodeError, "%s (%d)", punycode_strerror(rc), rc); return Qnil; } buf = stringprep_ucs4_to_utf8(ustr, len, NULL, &len); retv = rb_str_new(buf, len); xfree(ustr); xfree(buf); return retv; }