readLineSync method
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.termimal
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);
}