Module IDN::Punycode
In: ext/idna.c

The Punycode module of LibIDN Ruby Bindings.

Example usage

  require 'idn'
  include IDN

  str = Punycode.decode('egbpdaj6bu4bxfgehfvwxn')

Methods

decode   encode  

Classes and Modules

Class IDN::Punycode::PunycodeError

Public Class methods

Converts Punycode to a string in UTF-8 format.

Raises IDN::Punycode::PunycodeError on failure.

[Source]

/*
 * 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.

[Source]

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

[Validate]