punycodeDecode function

String punycodeDecode(
  1. String inputString
)

Implementation

String punycodeDecode(String inputString) {
  var input = inputString.codeUnits;
  // -- {
  // --   punycode_uint n, out, i, max_out, bias,
  // --                  b, j, in, oldi, w, k, digit, t;
  // --   /* Initialize the state: */
  // --
  // --   n = initial_n;
  // --   out = i = 0;
  // --   max_out = *output_length;
  // --   bias = initial_bias;
  var output = <int>[];
  int n = _initialN,
      i = 0,
      bias = _initialBias,
      b,
      j,
      iin,
      oldI,
      w,
      k,
      digit,
      t;

  // --   /* Handle the basic code points:  Let b be the number of input code */
  // --   /* points before the last delimiter, or 0 if there is none, then    */
  // --   /* copy the first b code points to the output.                      */
  // --
  // --   for (b = j = 0;  j < input_length;  ++j) if (delim(input[j])) b = j;
  for (b = j = 0; j < input.length; j++) {
    if (_isDelim(input[j])) {
      b = j;
    }
  }

  // This shouldn't be possible.
  // --   if (b > max_out) return punycode_big_output;

  // --   for (j = 0;  j < b;  ++j) {
  // --     if (case_flags) case_flags[out] = flagged(input[j]);
  // --     if (!basic(input[j])) return punycode_bad_input;
  // --     output[out++] = input[j];
  // --   }
  for (j = 0; j < b; j++) {
    if (!_isBasic(input[j])) {
      // TODO improve Exception
      throw new Exception('Bad input.');
    }
    output.add(input[j]);
  }

  // --   /* Main decoding loop:  Start just after the last delimiter if any  */
  // --   /* basic code points were copied; start at the beginning otherwise. */
  // --
  // --   for (in = b > 0 ? b + 1 : 0;  in < input_length;  ++out) {
  for (iin = b > 0 ? b + 1 : 0; iin < input.length;) {
    // --     /* in is the index of the next character to be consumed, and */
    // --     /* out is the number of code points in the output array.     */
    // --
    // --     /* Decode a generalized variable-length integer into delta,  */
    // --     /* which gets added to i.  The overflow checking is easier   */
    // --     /* if we increase i as we go, then subtract off its starting */
    // --     /* value at the end to obtain delta.                         */
    // --
    // --     for (oldi = i, w = 1, k = base;  ;  k += base) {
    // --       if (in >= input_length) return punycode_bad_input;
    // --       digit = decode_digit(input[in++]);
    // --       if (digit >= base) return punycode_bad_input;
    // --       if (digit > (maxint - i) / w) return punycode_overflow;
    // --       i += digit * w;
    // --       t = k <= bias /* + tmin */ ? tmin :     /* +tmin not needed */
    // --           k >= bias + tmax ? tmax : k - bias;
    // --       if (digit < t) break;
    // --       if (w > maxint / (base - t)) return punycode_overflow;
    // --       w *= (base - t);
    // --     }
    oldI = i;
    w = 1;
    k = _base;
    for (;; k += _base) {
      // ignore: invariant_booleans
      if (iin >= input.length) {
        // ToDo improve Exception
        throw new Exception('Bad input.');
      }
      digit = _decodeDigit(input[iin++]);
      if (digit >= _base) {
        // ToDo improve Exception
        throw new Exception('Bad input.');
      }
      i += digit * w;
      t = k <= bias
          ? _tMin
          : k >= bias + _tMax
              ? _tMax
              : k - bias;
      if (digit < t) break;
      w *= (_base - t);
    }

    // --     bias = adapt(i - oldi, out + 1, oldi == 0);
    bias = _adapt(i - oldI, output.length + 1, oldI == 0);

    // --     /* i was supposed to wrap around from out+1 to 0,   */
    // --     /* incrementing n each time, so we'll fix that now: */
    // --
    // --     if (i / (out + 1) > maxint - n) return punycode_overflow;
    // --     n += i / (out + 1);
    // --     i %= (out + 1);
    n += i ~/ (output.length + 1);
    i %= (output.length + 1);

    // --     /* Insert n at position i of the output: */
    // --
    // --     /* not needed for Punycode: */
    // --     /* if (decode_digit(n) <= base) return punycode_invalid_input; */
    // --     if (out >= max_out) return punycode_big_output;

    // --     if (case_flags) {
    // --       memmove(case_flags + i + 1, case_flags + i, out - i);
    // --       /* Case of last character determines uppercase flag: */
    // --       case_flags[i] = flagged(input[in - 1]);
    // --     }

    // --     memmove(output + i + 1, output + i, (out - i) * sizeof *output);
    // --     output[i++] = n;
    output.insert(i++, n);
    // --   }
  }

  // --   *output_length = out;
  // --   return punycode_success;
  return new String.fromCharCodes(output);
  // -- }
}