decodeRow method

U1DResult? decodeRow(
  1. UBitArray row
)

Implementation

U1DResult? decodeRow(UBitArray row) {
  final List<int>? startInfo = _findStartPattern(row);
  if (startInfo == null) return null;
  final int startCode = startInfo[2];

  int codeSet;
  switch (startCode) {
    case UCode128Patterns.codeStartA:
      codeSet = UCode128Patterns.codeCodeA;
      break;
    case UCode128Patterns.codeStartB:
      codeSet = UCode128Patterns.codeCodeB;
      break;
    case UCode128Patterns.codeStartC:
      codeSet = UCode128Patterns.codeCodeC;
      break;
    default:
      return null;
  }

  bool done = false;
  bool isNextShifted = false;
  final StringBuffer result = StringBuffer();
  int lastStart = startInfo[0];
  int nextStart = startInfo[1];
  final Int32List counters = Int32List(6);
  int lastCode = 0;
  int code = 0;
  int checksumTotal = startCode;
  int multiplier = 0;
  bool lastCharacterWasPrintable = true;

  while (!done) {
    final bool unshift = isNextShifted;
    isNextShifted = false;
    lastCode = code;
    try {
      code = _decodeCode(row, counters, nextStart);
    } catch (_) {
      return null;
    }
    lastStart = nextStart;
    for (final int counter in counters) {
      nextStart += counter;
    }

    if (code != UCode128Patterns.codeStop) {
      lastCharacterWasPrintable = true;
      multiplier++;
      checksumTotal += multiplier * code;
    }

    switch (codeSet) {
      case UCode128Patterns.codeCodeA:
        if (code < 64) {
          result.writeCharCode(32 + code);
        } else if (code < 96) {
          result.writeCharCode(code - 64);
        } else {
          if (code != UCode128Patterns.codeStop) lastCharacterWasPrintable = false;
          switch (code) {
            case UCode128Patterns.codeFnc1:
              result.writeCharCode(29);
              break;
            case UCode128Patterns.codeShift:
              isNextShifted = true;
              codeSet = UCode128Patterns.codeCodeB;
              break;
            case UCode128Patterns.codeCodeB:
              codeSet = UCode128Patterns.codeCodeB;
              break;
            case UCode128Patterns.codeCodeC:
              codeSet = UCode128Patterns.codeCodeC;
              break;
            case UCode128Patterns.codeStop:
              done = true;
              break;
          }
        }
        break;
      case UCode128Patterns.codeCodeB:
        if (code < 96) {
          result.writeCharCode(32 + code);
        } else {
          if (code != UCode128Patterns.codeStop) lastCharacterWasPrintable = false;
          switch (code) {
            case UCode128Patterns.codeFnc1:
              result.writeCharCode(29);
              break;
            case UCode128Patterns.codeShift:
              isNextShifted = true;
              codeSet = UCode128Patterns.codeCodeA;
              break;
            case UCode128Patterns.codeCodeA:
              codeSet = UCode128Patterns.codeCodeA;
              break;
            case UCode128Patterns.codeCodeC:
              codeSet = UCode128Patterns.codeCodeC;
              break;
            case UCode128Patterns.codeStop:
              done = true;
              break;
          }
        }
        break;
      case UCode128Patterns.codeCodeC:
        if (code < 100) {
          if (code < 10) result.write("0");
          result.write(code);
        } else {
          if (code != UCode128Patterns.codeStop) lastCharacterWasPrintable = false;
          switch (code) {
            case UCode128Patterns.codeFnc1:
              result.writeCharCode(29);
              break;
            case UCode128Patterns.codeCodeA:
              codeSet = UCode128Patterns.codeCodeA;
              break;
            case UCode128Patterns.codeCodeB:
              codeSet = UCode128Patterns.codeCodeB;
              break;
            case UCode128Patterns.codeStop:
              done = true;
              break;
          }
        }
        break;
    }
    if (unshift) {
      codeSet = codeSet == UCode128Patterns.codeCodeA ? UCode128Patterns.codeCodeB : UCode128Patterns.codeCodeA;
    }
  }

  final int lastPatternSize = nextStart - lastStart;
  nextStart = row.getNextUnset(nextStart);
  if (!row.isRange(nextStart, min(row.size, nextStart + (nextStart - lastStart) ~/ 2), false)) return null;

  checksumTotal -= multiplier * lastCode;
  if (checksumTotal % 103 != lastCode) return null;

  String text = result.toString();
  if (text.isEmpty) return null;
  if (lastCharacterWasPrintable) {
    final int trim = codeSet == UCode128Patterns.codeCodeC ? 2 : 1;
    if (text.length < trim) return null;
    text = text.substring(0, text.length - trim);
  }
  if (text.isEmpty) return null;
  return U1DResult(UCodeFormat.code128, text, (startInfo[1] + startInfo[0]) / 2, lastStart + lastPatternSize / 2);
}