readLineSync method Null safety

String? readLineSync (
  1. {Encoding encoding: systemEncoding,
  2. bool retainNewlines: false}
)

Read a line from stdin.

Blocks until a full line is available.

Lines my be terminated by either <CR><LF> or <LF>. On Windows in cases where the stdioType of stdin is StdioType.terminal the terminator may also be a single <CR>.

Input bytes are converted to a string by encoding. If encoding is omitted, it defaults to systemEncoding.

If retainNewlines is false, the returned String will not include the final line terminator. If true, the returned String will include the line terminator. Default is false.

If end-of-file is reached after any bytes have been read from stdin, that data is returned without a line terminator. Returns null if no bytes preceded the end of input.

Implementation

String? readLineSync(
    {Encoding encoding: systemEncoding, bool retainNewlines: false}) {
  const CR = 13;
  const LF = 10;
  final List<int> line = <int>[];
  // On Windows, if lineMode is disabled, only CR is received.
  bool crIsNewline = Platform.isWindows &&
      (stdioType(stdin) == StdioType.terminal) &&
      !lineMode;
  if (retainNewlines) {
    int byte;
    do {
      byte = readByteSync();
      if (byte < 0) {
        break;
      }
      line.add(byte);
    } while (byte != LF && !(byte == CR && crIsNewline));
    if (line.isEmpty) {
      return null;
    }
  } else if (crIsNewline) {
    // CR and LF are both line terminators, neither is retained.
    while (true) {
      int byte = readByteSync();
      if (byte < 0) {
        if (line.isEmpty) return null;
        break;
      }
      if (byte == LF || byte == CR) break;
      line.add(byte);
    }
  } else {
    // Case having to handle CR LF as a single unretained line terminator.
    outer:
    while (true) {
      int byte = readByteSync();
      if (byte == LF) break;
      if (byte == CR) {
        do {
          byte = readByteSync();
          if (byte == LF) break outer;

          line.add(CR);
        } while (byte == CR);
        // Fall through and handle non-CR character.
      }
      if (byte < 0) {
        if (line.isEmpty) return null;
        break;
      }
      line.add(byte);
    }
  }
  return encoding.decode(line);
}