parse method
Parses input and returns the numeric value.
Throws FormatException when input cannot be parsed by this codec.
Implementation
@override
int parse(String input) {
var text = input.trim();
if (text.isEmpty) {
throw FormatException('Expected a $expectedDescription.', input);
}
final negative = text.startsWith('负');
if (negative) {
text = text.substring(1);
if (text.isEmpty) {
throw FormatException('Expected a $expectedDescription.', input);
}
}
if (text.runes.length == 1 &&
digitValues[String.fromCharCode(text.runes.single)] == 0) {
return 0;
}
var total = 0;
var section = 0;
int? number;
var numberAfterZero = false;
var numberIsAlternateTwo = false;
var lastSmallUnit = _initialSmallUnit;
var lastSectionUnit = _initialSectionUnit;
for (final char in text.runes.map(String.fromCharCode)) {
final digit = digitValues[char];
if (digit != null) {
if (number != null) {
if (number == 0 && digit != 0 && (section > 0 || total > 0)) {
number = digit;
numberAfterZero = true;
numberIsAlternateTwo = _isAlternateTwo(char);
continue;
}
throw FormatException(unexpectedDescription, input);
}
number = digit;
numberAfterZero = false;
numberIsAlternateTwo = _isAlternateTwo(char);
continue;
}
final smallUnit = smallUnitValues[char];
if (smallUnit != null) {
if (smallUnit >= lastSmallUnit) {
throw FormatException(unexpectedDescription, input);
}
final digit = number;
if ((digit == null || digit == 0) && !allowImplicitOneForSmallUnit) {
throw FormatException(unexpectedDescription, input);
}
if (numberIsAlternateTwo && smallUnit == 10) {
throw FormatException(unexpectedDescription, input);
}
if (digit == 0 && section == 0 && total == 0) {
throw FormatException(unexpectedDescription, input);
}
section += (digit == null || digit == 0 ? 1 : digit) * smallUnit;
number = null;
numberAfterZero = false;
numberIsAlternateTwo = false;
lastSmallUnit = smallUnit;
continue;
}
final sectionUnit = sectionUnitValues[char];
if (sectionUnit != null) {
if (sectionUnit >= lastSectionUnit) {
throw FormatException(unexpectedDescription, input);
}
final digit = number;
if (digit == 0) {
throw FormatException(unexpectedDescription, input);
}
section += digit ?? 0;
if (section == 0) {
throw FormatException(unexpectedDescription, input);
}
total += section * sectionUnit;
section = 0;
number = null;
numberAfterZero = false;
numberIsAlternateTwo = false;
lastSmallUnit = _initialSmallUnit;
lastSectionUnit = sectionUnit;
continue;
}
throw FormatException(unexpectedDescription, input);
}
if (number == 0) {
throw FormatException(unexpectedDescription, input);
}
final trailing = number == null
? 0
: _resolveTrailingNumber(
number,
numberAfterZero: numberAfterZero,
lastSmallUnit: lastSmallUnit,
lastSectionUnit: lastSectionUnit,
input: input,
);
final value = total + section + trailing;
return negative ? -value : value;
}