Chromium Code Reviews| Index: sdk/lib/io/stdio.dart |
| diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart |
| index afa7ea013bb0fe8a9a123bb1393c75f39034a545..e42b7cbf3b2686ad97f27f7f370a26d92726c6aa 100644 |
| --- a/sdk/lib/io/stdio.dart |
| +++ b/sdk/lib/io/stdio.dart |
| @@ -10,6 +10,7 @@ const int _STDIO_HANDLE_TYPE_FILE = 2; |
| const int _STDIO_HANDLE_TYPE_SOCKET = 3; |
| const int _STDIO_HANDLE_TYPE_OTHER = 4; |
| + |
| class _StdStream extends Stream<List<int>> { |
| final Stream<List<int>> _stream; |
| @@ -27,6 +28,77 @@ class _StdStream extends Stream<List<int>> { |
| } |
| } |
| + |
| +class _StdinEventSink { |
| + Function add; |
| + Function addError; |
| + Function close; |
| + _StdinEventSink(this.add, this.addError, this.close); |
| +} |
| + |
| +/** |
| + * [Stdin] class that enable both synchronous and asynchronous reads from the |
| + * stdin pipe. |
| + * |
| + * Mixing synchronous and asynchronous reads is undefined. |
| + */ |
| +class Stdin extends _StdStream { |
| + Stdin._(Stream<List<int>> stream) : super(stream); |
| + |
| + /** |
| + * Read a line from stdin. This call will block until a full line is |
| + * available. The line will contain the newline character(s). |
| + * |
| + * If at end of file, `null` is returned. |
| + * |
| + * If at end of file, while some data is already read, that data is returned. |
| + */ |
| + String readLineSync({Encoding encoding: Encoding.SYSTEM, |
| + bool retainNewlines: false}) { |
| + var decoder = new StringDecoder(encoding)._decoder; |
| + var line = new StringBuffer(); |
| + bool end = false; |
| + var sink = new _StdinEventSink( |
| + (chunk) { |
|
Bill Hesse
2013/07/02 11:31:54
Why is chunk not char, or rune? It seems misleadi
Anders Johnsen
2013/07/02 12:21:27
Done.
|
| + if (chunk == '\n') end = true; |
| + line.write(chunk); |
| + }, |
| + (error) { |
| + throw error; |
| + }, () {}); |
| + |
| + while (!end) { |
| + int b = readByteSync(); |
| + if (b >= 0) { |
| + decoder.handleData([b], sink); |
| + } else { |
| + decoder.handleDone(sink); |
| + break; |
| + } |
| + } |
| + |
| + if (line.isEmpty) return null; |
| + line = line.toString(); |
| + int trim = 0; |
| + if (!retainNewlines) { |
|
Bill Hesse
2013/07/02 11:31:54
I would have put this into the sink object, with m
Anders Johnsen
2013/07/02 12:21:27
Done.
|
| + if (line.endsWith('\r\n')) { |
| + trim = 2; |
| + } else if (line.endsWith('\n')) { |
| + trim = 1; |
| + } |
| + } |
| + return line.substring(0, line.length - trim); |
| + } |
| + |
| + /** |
| + * Read a byte from stdin. This call will block until a byte is available. |
| + * |
| + * If at end of file, -1 is returned. |
| + */ |
| + int readByteSync(); |
| +} |
| + |
| + |
| class _StdSink implements IOSink { |
| final IOSink _sink; |