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 == ASCII_ENCODATION) {
    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.MAX_VALUE, mins);
      int minCount = _getMinimumCount(mins);

      if (intCharCounts[ASCII_ENCODATION] == min) {
        return ASCII_ENCODATION;
      }
      if (minCount == 1) {
        if (mins[BASE256_ENCODATION] > 0) {
          return BASE256_ENCODATION;
        }
        if (mins[EDIFACT_ENCODATION] > 0) {
          return EDIFACT_ENCODATION;
        }
        if (mins[TEXT_ENCODATION] > 0) {
          return TEXT_ENCODATION;
        }
        if (mins[X12_ENCODATION] > 0) {
          return X12_ENCODATION;
        }
      }

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

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

      return C40_ENCODATION;
    }

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

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

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

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

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

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

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

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

      if (intCharCounts[ASCII_ENCODATION] <
          min([
            intCharCounts[BASE256_ENCODATION],
            intCharCounts[C40_ENCODATION],
            intCharCounts[TEXT_ENCODATION],
            intCharCounts[X12_ENCODATION],
            intCharCounts[EDIFACT_ENCODATION],
          ])) {
        return ASCII_ENCODATION;
      }
      if (intCharCounts[BASE256_ENCODATION] <
              intCharCounts[ASCII_ENCODATION] ||
          intCharCounts[BASE256_ENCODATION] + 1 <
              min([
                intCharCounts[C40_ENCODATION],
                intCharCounts[TEXT_ENCODATION],
                intCharCounts[X12_ENCODATION],
                intCharCounts[EDIFACT_ENCODATION],
              ])) {
        return BASE256_ENCODATION;
      }
      if (intCharCounts[EDIFACT_ENCODATION] + 1 <
          min([
            intCharCounts[BASE256_ENCODATION],
            intCharCounts[C40_ENCODATION],
            intCharCounts[TEXT_ENCODATION],
            intCharCounts[X12_ENCODATION],
            intCharCounts[ASCII_ENCODATION],
          ])) {
        return EDIFACT_ENCODATION;
      }
      if (intCharCounts[TEXT_ENCODATION] + 1 <
          min([
            intCharCounts[BASE256_ENCODATION],
            intCharCounts[C40_ENCODATION],
            intCharCounts[EDIFACT_ENCODATION],
            intCharCounts[X12_ENCODATION],
            intCharCounts[ASCII_ENCODATION],
          ])) {
        return TEXT_ENCODATION;
      }
      if (intCharCounts[X12_ENCODATION] + 1 <
          min([
            intCharCounts[BASE256_ENCODATION],
            intCharCounts[C40_ENCODATION],
            intCharCounts[EDIFACT_ENCODATION],
            intCharCounts[TEXT_ENCODATION],
            intCharCounts[ASCII_ENCODATION],
          ])) {
        return X12_ENCODATION;
      }
      if (intCharCounts[C40_ENCODATION] + 1 <
          min([
            intCharCounts[ASCII_ENCODATION],
            intCharCounts[BASE256_ENCODATION],
            intCharCounts[EDIFACT_ENCODATION],
            intCharCounts[TEXT_ENCODATION]
          ])) {
        if (intCharCounts[C40_ENCODATION] < intCharCounts[X12_ENCODATION]) {
          return C40_ENCODATION;
        }
        if (intCharCounts[C40_ENCODATION] == intCharCounts[X12_ENCODATION]) {
          int p = startPos + charsProcessed + 1;
          while (p < msg.length) {
            final tc = msg.codeUnitAt(p);
            if (_isX12TermSep(tc)) {
              return X12_ENCODATION;
            }
            if (!isNativeX12(tc)) {
              break;
            }
            p++;
          }
          return C40_ENCODATION;
        }
      }
    }
  }
}