convert method

  1. @override
Uint8List convert(
  1. covariant List<int> encoded
)
override

Converts encoded array of numbers with bit-length of source to an array of numbers with bit-length of target. The encoded array will be treated as a sequence of bits to convert.

If the encoded array contains negative numbers or numbers having more than the source bits, it will be treated as the end of the input sequence.

After consuming all of input sequence, if there are some non-zero partial word remains, it will throw FormatException.

Implementation

@override
Uint8List convert(List<int> encoded) {
  final table = alphabet;
  final pad = padding;
  final tlen = table.length;
  int len = encoded.length;

  // Padding is only valid as a trailing suffix, strip it here. A padding
  // character anywhere else is rejected as an invalid character.
  // decode table maps it to -1).
  if (pad != null) {
    while (len > 0 && encoded[len - 1] == pad) {
      len--;
    }
  }

  int i = 0, l = 0;
  int y0, y1, y2, y3, c0, c1, c2, c3;

  var out = Uint8List((len * 6) >> 3);

  // Fast path: complete 4-character groups into 3 bytes.
  int fastEnd = len - (len & 3);
  while (i < fastEnd) {
    y0 = encoded[i];
    y1 = encoded[i + 1];
    y2 = encoded[i + 2];
    y3 = encoded[i + 3];
    if (y0 < 0 ||
        y1 < 0 ||
        y2 < 0 ||
        y3 < 0 ||
        y0 >= tlen ||
        y1 >= tlen ||
        y2 >= tlen ||
        y3 >= tlen) {
      break;
    }
    c0 = table[y0];
    c1 = table[y1];
    c2 = table[y2];
    c3 = table[y3];
    if (c0 < 0 || c1 < 0 || c2 < 0 || c3 < 0) {
      break;
    }
    out[l++] = (c0 << 2) | (c1 >> 4);
    out[l++] = ((c1 & 0xF) << 4) | (c2 >> 2);
    out[l++] = ((c2 & 0x3) << 6) | c3;
    i += 4;
  }

  // Tail: the final partial group (and any group the fast path rejected).
  // No padding remains, so this only regroups bits and validates characters.
  int p = 0, n = 0, x, y;
  for (; i < len; ++i) {
    y = encoded[i];
    if (y < 0 || y >= tlen || (x = table[y]) < 0) {
      throw FormatException('Invalid character $y at $i');
    }
    p = (p << 6) ^ x;
    n += 6;
    while (n >= 8) {
      n -= 8;
      out[l++] = p >>> n;
      p &= (1 << n) - 1;
    }
  }

  // A non-zero partial word means the input was not a valid length.
  if (p > 0) {
    throw FormatException('Invalid length or non-zero trailing bits');
  }

  return out;
}