decodeRow method
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);
}