lookAheadTestIntern static method

int lookAheadTestIntern(
  1. String msg,
  2. int startPos,
  3. int currentMode
)

Implementation

static int lookAheadTestIntern(String msg, int startPos, int currentMode) {
  if (startPos >= msg.length) {
    return currentMode;
  }
  List<double> charCounts;
  //step J
  if (currentMode == asciiEncodation) {
    charCounts = [0, 1, 1, 1, 1, 1.25];
  } else {
    charCounts = [1, 2, 2, 2, 2, 2.25];
    charCounts[currentMode] = 0;
  }

  int charsProcessed = 0;
  final mins = Uint8List(6);
  final intCharCounts = Uint8List(6);
  while (true) {
    //step K
    if ((startPos + charsProcessed) == msg.length) {
      mins.fillRange(0, mins.length, 0);
      intCharCounts.fillRange(0, mins.length, 0);
      final min =
          _findMinimums(charCounts, intCharCounts, MathUtils.maxValue, mins);
      int minCount = _getMinimumCount(mins);

      if (intCharCounts[asciiEncodation] == min) {
        return asciiEncodation;
      }
      if (minCount == 1) {
        if (mins[base256Encodation] > 0) {
          return base256Encodation;
        }
        if (mins[edifactEncodation] > 0) {
          return edifactEncodation;
        }
        if (mins[textEncodation] > 0) {
          return textEncodation;
        }
        if (mins[x12Encodation] > 0) {
          return x12Encodation;
        }
      }

      // to fix result
      final dmin = charCounts.fold<double>(
        MathUtils.maxValue.toDouble(),
        (previousValue, element) => math.min(previousValue, element),
      );
      minCount = charCounts.where((element) => element == dmin).length;

      if (charCounts[asciiEncodation] == dmin) {
        return asciiEncodation;
      }
      if (minCount == 1) {
        return charCounts.indexOf(dmin);
      }

      return c40Encodation;
    }

    final c = msg.codeUnitAt(startPos + charsProcessed);
    charsProcessed++;

    //step L
    if (isDigit(c)) {
      charCounts[asciiEncodation] += 0.5;
    } else if (isExtendedASCII(c)) {
      charCounts[asciiEncodation] =
          (charCounts[asciiEncodation]).ceil().toDouble();
      charCounts[asciiEncodation] += 2.0;
    } else {
      charCounts[asciiEncodation] =
          (charCounts[asciiEncodation]).ceil().toDouble();
      charCounts[asciiEncodation]++;
    }

    //step M
    if (isNativeC40(c)) {
      charCounts[c40Encodation] += 2.0 / 3.0; //0.6666667;
    } else if (isExtendedASCII(c)) {
      charCounts[c40Encodation] += 8.0 / 3.0; //2.6666667;
    } else {
      charCounts[c40Encodation] += 4.0 / 3.0; //1.3333334;
    }

    //step N
    if (isNativeText(c)) {
      charCounts[textEncodation] += 2.0 / 3.0; //0.6666667;
    } else if (isExtendedASCII(c)) {
      charCounts[textEncodation] += 8.0 / 3.0; //2.6666667;
    } else {
      charCounts[textEncodation] += 4.0 / 3.0; //1.3333334;
    }

    //step O
    if (isNativeX12(c)) {
      charCounts[x12Encodation] += 2.0 / 3.0; //0.6666667;
    } else if (isExtendedASCII(c)) {
      charCounts[x12Encodation] += 13.0 / 3.0; //4.3333335;
    } else {
      charCounts[x12Encodation] += 10.0 / 3.0; //3.3333333;
    }

    //step P
    if (isNativeEDIFACT(c)) {
      charCounts[edifactEncodation] += 0.75; //3.0 / 4.0;
    } else if (isExtendedASCII(c)) {
      charCounts[edifactEncodation] += 4.25; //17.0 / 4.0;
    } else {
      charCounts[edifactEncodation] += 3.25; //13.0 / 4.0;
    }

    // step Q
    if (_isSpecialB256(c)) {
      charCounts[base256Encodation] += 4.0;
    } else {
      charCounts[base256Encodation]++;
    }

    //step R
    if (charsProcessed >= 4) {
      mins.fillRange(0, mins.length, 0);
      intCharCounts.fillRange(0, mins.length, 0);
      _findMinimums(charCounts, intCharCounts, MathUtils.maxValue, mins);

      if (intCharCounts[asciiEncodation] <
          min([
            intCharCounts[base256Encodation],
            intCharCounts[c40Encodation],
            intCharCounts[textEncodation],
            intCharCounts[x12Encodation],
            intCharCounts[edifactEncodation],
          ])) {
        return asciiEncodation;
      }
      if (intCharCounts[base256Encodation] < intCharCounts[asciiEncodation] ||
          intCharCounts[base256Encodation] + 1 <
              min([
                intCharCounts[c40Encodation],
                intCharCounts[textEncodation],
                intCharCounts[x12Encodation],
                intCharCounts[edifactEncodation],
              ])) {
        return base256Encodation;
      }
      if (intCharCounts[edifactEncodation] + 1 <
          min([
            intCharCounts[base256Encodation],
            intCharCounts[c40Encodation],
            intCharCounts[textEncodation],
            intCharCounts[x12Encodation],
            intCharCounts[asciiEncodation],
          ])) {
        return edifactEncodation;
      }
      if (intCharCounts[textEncodation] + 1 <
          min([
            intCharCounts[base256Encodation],
            intCharCounts[c40Encodation],
            intCharCounts[edifactEncodation],
            intCharCounts[x12Encodation],
            intCharCounts[asciiEncodation],
          ])) {
        return textEncodation;
      }
      if (intCharCounts[x12Encodation] + 1 <
          min([
            intCharCounts[base256Encodation],
            intCharCounts[c40Encodation],
            intCharCounts[edifactEncodation],
            intCharCounts[textEncodation],
            intCharCounts[asciiEncodation],
          ])) {
        return x12Encodation;
      }
      if (intCharCounts[c40Encodation] + 1 <
          min([
            intCharCounts[asciiEncodation],
            intCharCounts[base256Encodation],
            intCharCounts[edifactEncodation],
            intCharCounts[textEncodation]
          ])) {
        if (intCharCounts[c40Encodation] < intCharCounts[x12Encodation]) {
          return c40Encodation;
        }
        if (intCharCounts[c40Encodation] == intCharCounts[x12Encodation]) {
          int p = startPos + charsProcessed + 1;
          while (p < msg.length) {
            final tc = msg.codeUnitAt(p);
            if (_isX12TermSep(tc)) {
              return x12Encodation;
            }
            if (!isNativeX12(tc)) {
              break;
            }
            p++;
          }
          return c40Encodation;
        }
      }
    }
  }
}