punycodeEncode function

String punycodeEncode(
  1. String inputString, {
  2. bool upperCase = false,
})

Implementation

String punycodeEncode(String inputString, {bool upperCase: false}) {
  var input = inputString.runes.toList(growable: false);

  final output = new StringBuffer();
  void toOut(int c) => output.writeCharCode(c);
  void allToOut(Iterable<int> cps) =>
      cps.forEach((cp) => output.writeCharCode(cp));

  // -- {
  // --   punycode_uint n, delta, h, b, out, max_out, bias, j, m, q, k, t;
  // --   /* Initialize the state: */
  // --
  // --   n = initial_n;
  // --   delta = out = 0;
  // --   max_out = *output_length;
  // --   bias = initial_bias;
  int n = _initialN;
  int delta = 0, h, b, bias = _initialBias, j;
  int? m;
  int q, k, t;

  // --   /* Handle the basic code points: */
  // --   for (j = 0;  j < input_length;  ++j) {
  // --     if (basic(input[j])) {
  // --       if (max_out - out < 2) return punycode_big_output;
  // --       output[out++] =
  // --         case_flags ?  encode_basic(input[j], case_flags[j]) : input[j];
  // --     }
  // --     /* else if (input[j] < n) return punycode_bad_input; */
  // --     /* (not needed for Punycode with unsigned code points) */
  // --   }
  allToOut(input.where(_isBasic).map((r) => _encodeBasic(r, upperCase)));

  // --   h = b = out;
  h = b = output.length;

  // --   /* h is the number of code points that have been handled, b is the  */
  // --   /* number of basic code points, and out is the number of characters */
  // --   /* that have been output.                                           */
  // --
  // --   if (b > 0) output[out++] = delimiter;
  if (b > 0) toOut(_delimiter);

  // --   /* Main encoding loop: */
  // --
  // --   while (h < input_length) {
  while (h < input.length) {
    // --     /* All non-basic code points < n have been     */
    // --     /* handled already.  Find the next larger one: */
    // --
    // --     for (m = maxint, j = 0;  j < input_length;  ++j) {
    // --       /* if (basic(input[j])) continue; */
    // --       /* (not needed for Punycode) */
    // --       if (input[j] >= n && input[j] < m) m = input[j];
    // --     }
    m = null;
    for (j = 0; j < input.length; j++) {
      int i = input[j];
      if (i >= n && (m == null || i < m)) {
        m = i;
      }
    }

    // --     /* Increase delta enough to advance the decoder's    */
    // --     /* <n,i> state to <m,0>, but guard against overflow: */
    // --
    // --     if (m - n > (maxint - delta) / (h + 1)) return punycode_overflow;
    // Currently no overflow protection.

    // --     delta += (m - n) * (h + 1);
    // --     n = m;
    delta += (m! - n) * (h + 1);
    n = m;

    // --     for (j = 0;  j < input_length;  ++j) {
    for (j = 0; j < input.length; j++) {
      // --       /* Punycode does not need to check whether input[j] is basic: */
      // --       if (input[j] < n /* || basic(input[j]) */ ) {
      // --         if (++delta == 0) return punycode_overflow;
      // --       }
      // Currently no overflow protection.
      if (input[j] < n) {
        delta++;
      }

      // --       if (input[j] == n) {
      // --         /* Represent delta as a generalized variable-length integer: */
      // --
      // --         for (q = delta, k = base;  ;  k += base) {
      // --           if (out >= max_out) return punycode_big_output;
      // --           t = k <= bias /* + tmin */ ? tmin :     /* +tmin not needed */
      // --               k >= bias + tmax ? tmax : k - bias;
      // --           if (q < t) break;
      // --           output[out++] = encode_digit(t + (q - t) % (base - t), 0);
      // --           q = (q - t) / (base - t);
      // --         }
      if (input[j] == n) {
        q = delta;
        k = _base;
        for (;; k += _base) {
          t = k <= bias
              ? _tMin
              : k >= bias + _tMax
                  ? _tMax
                  : k - bias;
          if (q < t) break;
          toOut(_encodeDigit(t + (q - t) % (_base - t), false));
          q = (q - t) ~/ (_base - t);
        }

        // --         output[out++] = encode_digit(q, case_flags && case_flags[j]);
        // --         bias = adapt(delta, h + 1, h == b);
        // --         delta = 0;
        // --         ++h;
        toOut(_encodeDigit(q, upperCase));
        bias = _adapt(delta, h + 1, h == b);
        delta = 0;
        h++;
        // --       }
      }
      // --     }
    }

    // --     ++delta, ++n;
    delta++;
    n++;
    // --   }
  }

  // --   *output_length = out;
  // --   return punycode_success;
  // -- }
  return output.toString();
}