| Module | IDN::Punycode |
| In: |
ext/idna.c
|
The Punycode module of LibIDN Ruby Bindings.
require 'idn'
include IDN
str = Punycode.decode('egbpdaj6bu4bxfgehfvwxn')
Converts Punycode to a string in UTF-8 format.
Raises IDN::Punycode::PunycodeError on failure.
/*
* 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;
}
Converts a string in UTF-8 format to Punycode.
Raises IDN::Punycode::PunycodeError on failure.
/*
* call-seq:
* IDN::Punycode.encode(string) => string
*
* Converts a string in UTF-8 format to Punycode.
*
* Raises IDN::Punycode::PunycodeError on failure.
*/
static VALUE encode(VALUE self, VALUE str)
{
int rc;
punycode_uint *ustr;
size_t len;
size_t buflen = 0x100;
char *buf = NULL;
VALUE retv;
str = rb_check_convert_type(str, T_STRING, "String", "to_s");
ustr = stringprep_utf8_to_ucs4(RSTRING(str)->ptr, RSTRING(str)->len, &len);
while (1) {
buf = realloc(buf, buflen);
if (buf == NULL) {
xfree(ustr);
rb_raise(rb_eNoMemError, "cannot allocate memory (%d bytes)", buflen);
return Qnil;
}
rc = punycode_encode(len, ustr, NULL, &buflen, buf);
if (rc == PUNYCODE_SUCCESS) {
break;
} else if (rc == PUNYCODE_BIG_OUTPUT) {
buflen += 0x100;
} else {
xfree(ustr);
xfree(buf);
rb_raise(ePunycodeError, "%s (%d)", punycode_strerror(rc), rc);
return Qnil;
}
}
retv = rb_str_new(buf, buflen);
xfree(ustr);
xfree(buf);
return retv;
}