num? _parseNumberValue()

in lib/src/loader.dart [292:372]


  num? _parseNumberValue(String contents,
      {bool allowInt = true, bool allowFloat = true}) {
    assert(allowInt || allowFloat);

    var firstChar = contents.codeUnitAt(0);
    var length = contents.length;

    // Quick check for single digit integers.
    if (allowInt && length == 1) {
      var value = firstChar - $0;
      return value >= 0 && value <= 9 ? value : null;
    }

    var secondChar = contents.codeUnitAt(1);

    // Hexadecimal or octal integers.
    if (allowInt && firstChar == $0) {
      // int.tryParse supports 0x natively.
      if (secondChar == $x) return int.tryParse(contents);

      if (secondChar == $o) {
        var afterRadix = contents.substring(2);
        return int.tryParse(afterRadix, radix: 8);
      }
    }

    // Int or float starting with a digit or a +/- sign.
    if ((firstChar >= $0 && firstChar <= $9) ||
        ((firstChar == $plus || firstChar == $minus) &&
            secondChar >= $0 &&
            secondChar <= $9)) {
      // Try to parse an int or, failing that, a double.
      num? result;
      if (allowInt) {
        // Pass "radix: 10" explicitly to ensure that "-0x10", which is valid
        // Dart but invalid YAML, doesn't get parsed.
        result = int.tryParse(contents, radix: 10);
      }

      if (allowFloat) result ??= double.tryParse(contents);
      return result;
    }

    if (!allowFloat) return null;

    // Now the only possibility is to parse a float starting with a dot or a
    // sign and a dot, or the signed/unsigned infinity values and not-a-numbers.
    if ((firstChar == $dot && secondChar >= $0 && secondChar <= $9) ||
        (firstChar == $minus || firstChar == $plus) && secondChar == $dot) {
      // Starting with a . and a number or a sign followed by a dot.
      if (length == 5) {
        switch (contents) {
          case '+.inf':
          case '+.Inf':
          case '+.INF':
            return double.infinity;
          case '-.inf':
          case '-.Inf':
          case '-.INF':
            return -double.infinity;
        }
      }

      return double.tryParse(contents);
    }

    if (length == 4 && firstChar == $dot) {
      switch (contents) {
        case '.inf':
        case '.Inf':
        case '.INF':
          return double.infinity;
        case '.nan':
        case '.NaN':
        case '.NAN':
          return double.nan;
      }
    }

    return null;
  }