| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// Helper functionality to make working with IO easier. | 5 /// Helper functionality to make working with IO easier. |
| 6 library io; | 6 library io; |
| 7 | 7 |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:io'; | 9 import 'dart:io'; |
| 10 import 'dart:isolate'; | 10 import 'dart:isolate'; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 | 124 |
| 125 /// Writes [stream] to a new file at [path], which may be a [String] or a | 125 /// Writes [stream] to a new file at [path], which may be a [String] or a |
| 126 /// [File]. Will replace any file already at that path. Completes when the file | 126 /// [File]. Will replace any file already at that path. Completes when the file |
| 127 /// is done being written. | 127 /// is done being written. |
| 128 Future<File> createFileFromStream(InputStream stream, path) { | 128 Future<File> createFileFromStream(InputStream stream, path) { |
| 129 path = _getPath(path); | 129 path = _getPath(path); |
| 130 | 130 |
| 131 log.io("Creating $path from stream."); | 131 log.io("Creating $path from stream."); |
| 132 | 132 |
| 133 var completer = new Completer<File>(); | 133 var completer = new Completer<File>(); |
| 134 var completed = false; |
| 134 var file = new File(path); | 135 var file = new File(path); |
| 135 var outputStream = file.openOutputStream(); | 136 var outputStream = file.openOutputStream(); |
| 136 stream.pipe(outputStream); | 137 stream.pipe(outputStream); |
| 137 | 138 |
| 138 outputStream.onClosed = () { | 139 outputStream.onClosed = () { |
| 139 log.fine("Created $path from stream."); | 140 log.fine("Created $path from stream."); |
| 141 completed = true; |
| 140 completer.complete(file); | 142 completer.complete(file); |
| 141 }; | 143 }; |
| 142 | 144 |
| 143 // TODO(nweiz): remove this when issue 4061 is fixed. | 145 // TODO(nweiz): remove this when issue 4061 is fixed. |
| 144 var stackTrace; | 146 var stackTrace; |
| 145 try { | 147 try { |
| 146 throw ""; | 148 throw ""; |
| 147 } catch (_, localStackTrace) { | 149 } catch (_, localStackTrace) { |
| 148 stackTrace = localStackTrace; | 150 stackTrace = localStackTrace; |
| 149 } | 151 } |
| 150 | 152 |
| 151 completeError(error) { | 153 completeError(error) { |
| 152 if (!completer.isComplete) { | 154 if (!completed) { |
| 153 completer.completeException(error, stackTrace); | 155 completed = true; |
| 156 completer.completeError(error, stackTrace); |
| 154 } else { | 157 } else { |
| 155 log.fine("Got error after stream was closed: $error"); | 158 log.fine("Got error after stream was closed: $error"); |
| 156 } | 159 } |
| 157 } | 160 } |
| 158 | 161 |
| 159 stream.onError = completeError; | 162 stream.onError = completeError; |
| 160 outputStream.onError = completeError; | 163 outputStream.onError = completeError; |
| 161 | 164 |
| 162 return completer.future; | 165 return completer.future; |
| 163 } | 166 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 | 259 |
| 257 // TODO(nweiz): remove this when issue 4061 is fixed. | 260 // TODO(nweiz): remove this when issue 4061 is fixed. |
| 258 var stackTrace; | 261 var stackTrace; |
| 259 try { | 262 try { |
| 260 throw ""; | 263 throw ""; |
| 261 } catch (_, localStackTrace) { | 264 } catch (_, localStackTrace) { |
| 262 stackTrace = localStackTrace; | 265 stackTrace = localStackTrace; |
| 263 } | 266 } |
| 264 | 267 |
| 265 var children = []; | 268 var children = []; |
| 266 lister.onError = (error) => completer.completeException(error, stackTrace); | 269 lister.onError = (error) => completer.completeError(error, stackTrace); |
| 267 lister.onDir = (file) { | 270 lister.onDir = (file) { |
| 268 if (!includeHiddenFiles && basename(file).startsWith('.')) return; | 271 if (!includeHiddenFiles && basename(file).startsWith('.')) return; |
| 269 file = join(dir, basename(file)); | 272 file = join(dir, basename(file)); |
| 270 contents.add(file); | 273 contents.add(file); |
| 271 | 274 |
| 272 // TODO(nweiz): don't manually recurse once issue 7358 is fixed. Note that | 275 // TODO(nweiz): don't manually recurse once issue 7358 is fixed. Note that |
| 273 // once we remove the manual recursion, we'll need to explicitly filter | 276 // once we remove the manual recursion, we'll need to explicitly filter |
| 274 // out files in hidden directories. | 277 // out files in hidden directories. |
| 275 if (recursive) { | 278 if (recursive) { |
| 276 children.add(doList(new Directory(file), listedDirectories)); | 279 children.add(doList(new Directory(file), listedDirectories)); |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 | 483 |
| 481 stream.onLine = () { | 484 stream.onLine = () { |
| 482 removeCallbacks(); | 485 removeCallbacks(); |
| 483 var line = stream.readLine(); | 486 var line = stream.readLine(); |
| 484 log.io('Read line: $line'); | 487 log.io('Read line: $line'); |
| 485 completer.complete(line); | 488 completer.complete(line); |
| 486 }; | 489 }; |
| 487 | 490 |
| 488 stream.onError = (e) { | 491 stream.onError = (e) { |
| 489 removeCallbacks(); | 492 removeCallbacks(); |
| 490 completer.completeException(e, stackTrace); | 493 completer.completeError(e, stackTrace); |
| 491 }; | 494 }; |
| 492 | 495 |
| 493 return completer.future; | 496 return completer.future; |
| 494 } | 497 } |
| 495 | 498 |
| 496 /// Takes all input from [source] and writes it to [sink]. | 499 /// Takes all input from [source] and writes it to [sink]. |
| 497 /// | 500 /// |
| 498 /// Returns a future that completes when [source] is closed. | 501 /// Returns a future that completes when [source] is closed. |
| 499 Future pipeInputToInput(InputStream source, ListInputStream sink) { | 502 Future pipeInputToInput(InputStream source, ListInputStream sink) { |
| 500 var completer = new Completer(); | 503 var completer = new Completer(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 528 try { | 531 try { |
| 529 throw ""; | 532 throw ""; |
| 530 } catch (_, localStackTrace) { | 533 } catch (_, localStackTrace) { |
| 531 stackTrace = localStackTrace; | 534 stackTrace = localStackTrace; |
| 532 } | 535 } |
| 533 | 536 |
| 534 var completer = new Completer<List<int>>(); | 537 var completer = new Completer<List<int>>(); |
| 535 var buffer = <int>[]; | 538 var buffer = <int>[]; |
| 536 stream.onClosed = () => completer.complete(buffer); | 539 stream.onClosed = () => completer.complete(buffer); |
| 537 stream.onData = () => buffer.addAll(stream.read()); | 540 stream.onData = () => buffer.addAll(stream.read()); |
| 538 stream.onError = (e) => completer.completeException(e, stackTrace); | 541 stream.onError = (e) => completer.completeError(e, stackTrace); |
| 539 return completer.future; | 542 return completer.future; |
| 540 } | 543 } |
| 541 | 544 |
| 542 /// Buffers all input from a StringInputStream and returns it as a future. | 545 /// Buffers all input from a StringInputStream and returns it as a future. |
| 543 Future<String> consumeStringInputStream(StringInputStream stream) { | 546 Future<String> consumeStringInputStream(StringInputStream stream) { |
| 544 if (stream.closed) return new Future.immediate(''); | 547 if (stream.closed) return new Future.immediate(''); |
| 545 | 548 |
| 546 // TODO(nweiz): remove this when issue 4061 is fixed. | 549 // TODO(nweiz): remove this when issue 4061 is fixed. |
| 547 var stackTrace; | 550 var stackTrace; |
| 548 try { | 551 try { |
| 549 throw ""; | 552 throw ""; |
| 550 } catch (_, localStackTrace) { | 553 } catch (_, localStackTrace) { |
| 551 stackTrace = localStackTrace; | 554 stackTrace = localStackTrace; |
| 552 } | 555 } |
| 553 | 556 |
| 554 var completer = new Completer<String>(); | 557 var completer = new Completer<String>(); |
| 555 var buffer = new StringBuffer(); | 558 var buffer = new StringBuffer(); |
| 556 stream.onClosed = () => completer.complete(buffer.toString()); | 559 stream.onClosed = () => completer.complete(buffer.toString()); |
| 557 stream.onData = () => buffer.add(stream.read()); | 560 stream.onData = () => buffer.add(stream.read()); |
| 558 stream.onError = (e) => completer.completeException(e, stackTrace); | 561 stream.onError = (e) => completer.completeError(e, stackTrace); |
| 559 return completer.future; | 562 return completer.future; |
| 560 } | 563 } |
| 561 | 564 |
| 562 /// Wrap an InputStream in a ListInputStream. This eagerly drains the [source] | 565 /// Wrap an InputStream in a ListInputStream. This eagerly drains the [source] |
| 563 /// input stream. This is useful for spawned processes which will not exit until | 566 /// input stream. This is useful for spawned processes which will not exit until |
| 564 /// their output streams have been drained. | 567 /// their output streams have been drained. |
| 565 /// TODO(rnystrom): We should use this logic anywhere we spawn a process. | 568 /// TODO(rnystrom): We should use this logic anywhere we spawn a process. |
| 566 InputStream wrapInputStream(InputStream source) { | 569 InputStream wrapInputStream(InputStream source) { |
| 567 var sink = new ListInputStream(); | 570 var sink = new ListInputStream(); |
| 568 pipeInputToInput(source, sink); | 571 pipeInputToInput(source, sink); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 /// However, if [milliseconds] pass before [input] has completed, it completes | 667 /// However, if [milliseconds] pass before [input] has completed, it completes |
| 665 /// with a [TimeoutException] with [description] (which should be a fragment | 668 /// with a [TimeoutException] with [description] (which should be a fragment |
| 666 /// describing the action that timed out). | 669 /// describing the action that timed out). |
| 667 /// | 670 /// |
| 668 /// Note that timing out will not cancel the asynchronous operation behind | 671 /// Note that timing out will not cancel the asynchronous operation behind |
| 669 /// [input]. | 672 /// [input]. |
| 670 Future timeout(Future input, int milliseconds, String description) { | 673 Future timeout(Future input, int milliseconds, String description) { |
| 671 bool completed = false; | 674 bool completed = false; |
| 672 var completer = new Completer(); | 675 var completer = new Completer(); |
| 673 var timer = new Timer(milliseconds, (_) { | 676 var timer = new Timer(milliseconds, (_) { |
| 674 completer = true; | 677 completed = true; |
| 675 completer.completeError(new TimeoutException( | 678 completer.completeError(new TimeoutException( |
| 676 'Timed out while $description.')); | 679 'Timed out while $description.')); |
| 677 }); | 680 }); |
| 678 input | 681 input |
| 679 .then((value) { | 682 .then((value) { |
| 680 if (completed) return; | 683 if (completed) return; |
| 681 timer.cancel(); | 684 timer.cancel(); |
| 682 completer.complete(value); | 685 completer.complete(value); |
| 683 }) | 686 }) |
| 684 .catchError((e) { | 687 .catchError((e) { |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 Directory _getDirectory(entry) { | 967 Directory _getDirectory(entry) { |
| 965 if (entry is Directory) return entry; | 968 if (entry is Directory) return entry; |
| 966 return new Directory(entry); | 969 return new Directory(entry); |
| 967 } | 970 } |
| 968 | 971 |
| 969 /// Gets a [Uri] for [uri], which can either already be one, or be a [String]. | 972 /// Gets a [Uri] for [uri], which can either already be one, or be a [String]. |
| 970 Uri _getUri(uri) { | 973 Uri _getUri(uri) { |
| 971 if (uri is Uri) return uri; | 974 if (uri is Uri) return uri; |
| 972 return new Uri.fromString(uri); | 975 return new Uri.fromString(uri); |
| 973 } | 976 } |
| OLD | NEW |