parse method

  1. @override
int parse(
  1. String input
)
inherited

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;
}