| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of dart.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 // Read the file in blocks of size 64k. | 7 // Read the file in blocks of size 64k. |
| 8 const int _BLOCK_SIZE = 64 * 1024; | 8 const int _BLOCK_SIZE = 64 * 1024; |
| 9 | 9 |
| 10 | 10 |
| 11 class _FileStream extends Stream<List<int>> { | 11 class _FileStream extends Stream<List<int>> { |
| 12 // Stream controller. | 12 // Stream controller. |
| 13 StreamController<List<int>> _controller; | 13 StreamController<List<int>> _controller; |
| 14 | 14 |
| 15 // Information about the underlying file. | 15 // Information about the underlying file. |
| 16 String _path; | 16 String _path; |
| 17 RandomAccessFile _openedFile; | 17 RandomAccessFile _openedFile; |
| 18 int _position; | 18 int _position; |
| 19 int _end; |
| 19 | 20 |
| 20 // Has the stream been paused or unsubscribed? | 21 // Has the stream been paused or unsubscribed? |
| 21 bool _paused = false; | 22 bool _paused = false; |
| 22 bool _unsubscribed = false; | 23 bool _unsubscribed = false; |
| 23 | 24 |
| 24 // Is there a read currently in progress? | 25 // Is there a read currently in progress? |
| 25 bool _readInProgress = false; | 26 bool _readInProgress = false; |
| 26 | 27 |
| 27 // Block read but not yet send because stream is paused. | 28 // Block read but not yet send because stream is paused. |
| 28 List<int> _currentBlock; | 29 List<int> _currentBlock; |
| 29 | 30 |
| 30 _FileStream(String this._path) : _position = 0 { | 31 _FileStream(String this._path, this._position, this._end) { |
| 31 _setupController(); | 32 _setupController(); |
| 32 } | 33 } |
| 33 | 34 |
| 34 _FileStream.forStdin() : _position = 0 { | 35 _FileStream.forStdin() : _position = 0 { |
| 35 _setupController(); | 36 _setupController(); |
| 36 } | 37 } |
| 37 | 38 |
| 38 StreamSubscription<List<int>> listen(void onData(List<int> event), | 39 StreamSubscription<List<int>> listen(void onData(List<int> event), |
| 39 {void onError(error), | 40 {void onError(error), |
| 40 void onDone(), | 41 void onDone(), |
| (...skipping 23 matching lines...) Expand all Loading... |
| 64 return closeFuture; | 65 return closeFuture; |
| 65 } else { | 66 } else { |
| 66 return new Future.value(); | 67 return new Future.value(); |
| 67 } | 68 } |
| 68 } | 69 } |
| 69 | 70 |
| 70 void _readBlock() { | 71 void _readBlock() { |
| 71 // Don't start a new read if one is already in progress. | 72 // Don't start a new read if one is already in progress. |
| 72 if (_readInProgress) return; | 73 if (_readInProgress) return; |
| 73 _readInProgress = true; | 74 _readInProgress = true; |
| 74 _openedFile.read(_BLOCK_SIZE) | 75 int readBytes = _BLOCK_SIZE; |
| 76 if (_end != null) { |
| 77 readBytes = min(readBytes, _end - _position); |
| 78 if (readBytes < 0) { |
| 79 throw new RangeError("Bad end position: $_end"); |
| 80 } |
| 81 } |
| 82 _openedFile.read(readBytes) |
| 75 .then((block) { | 83 .then((block) { |
| 76 _readInProgress = false; | 84 _readInProgress = false; |
| 77 if (block.length == 0) { | 85 if (block.length == 0) { |
| 78 if (!_unsubscribed) { | 86 if (!_unsubscribed) { |
| 79 _closeFile().then((_) { _controller.close(); }); | 87 _closeFile().then((_) { _controller.close(); }); |
| 80 _unsubscribed = true; | 88 _unsubscribed = true; |
| 81 } | 89 } |
| 82 return; | 90 return; |
| 83 } | 91 } |
| 84 _position += block.length; | 92 _position += block.length; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 101 void _start() { | 109 void _start() { |
| 102 Future<RandomAccessFile> openFuture; | 110 Future<RandomAccessFile> openFuture; |
| 103 if (_path != null) { | 111 if (_path != null) { |
| 104 openFuture = new File(_path).open(mode: FileMode.READ); | 112 openFuture = new File(_path).open(mode: FileMode.READ); |
| 105 } else { | 113 } else { |
| 106 openFuture = new Future.value(_File._openStdioSync(0)); | 114 openFuture = new Future.value(_File._openStdioSync(0)); |
| 107 } | 115 } |
| 108 openFuture | 116 openFuture |
| 109 .then((RandomAccessFile opened) { | 117 .then((RandomAccessFile opened) { |
| 110 _openedFile = opened; | 118 _openedFile = opened; |
| 111 _readBlock(); | 119 if (_position == null) { |
| 120 _position = 0; |
| 121 } |
| 122 if (_position > 0) { |
| 123 return opened.setPosition(_position); |
| 124 } else if (_position < 0) { |
| 125 throw new RangeError("Bad start position: $_position"); |
| 126 } |
| 112 }) | 127 }) |
| 128 .then((_) => _readBlock()) |
| 113 .catchError((e) { | 129 .catchError((e) { |
| 114 _controller.addError(e); | 130 _controller.addError(e); |
| 115 _controller.close(); | 131 _controller.close(); |
| 116 }); | 132 }); |
| 117 } | 133 } |
| 118 | 134 |
| 119 void _resume() { | 135 void _resume() { |
| 120 _paused = false; | 136 _paused = false; |
| 121 if (_currentBlock != null) { | 137 if (_currentBlock != null) { |
| 122 _controller.add(_currentBlock); | 138 _controller.add(_currentBlock); |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 } | 439 } |
| 424 | 440 |
| 425 external static _fullPath(String path); | 441 external static _fullPath(String path); |
| 426 | 442 |
| 427 String fullPathSync() { | 443 String fullPathSync() { |
| 428 var result = _fullPath(_path); | 444 var result = _fullPath(_path); |
| 429 throwIfError(result, "Cannot retrieve full path for file '$_path'"); | 445 throwIfError(result, "Cannot retrieve full path for file '$_path'"); |
| 430 return result; | 446 return result; |
| 431 } | 447 } |
| 432 | 448 |
| 433 Stream<List<int>> openRead() { | 449 Stream<List<int>> openRead([int start, int end]) { |
| 434 return new _FileStream(_path); | 450 return new _FileStream(_path, start, end); |
| 435 } | 451 } |
| 436 | 452 |
| 437 IOSink openWrite({FileMode mode: FileMode.WRITE, | 453 IOSink openWrite({FileMode mode: FileMode.WRITE, |
| 438 Encoding encoding: Encoding.UTF_8}) { | 454 Encoding encoding: Encoding.UTF_8}) { |
| 439 if (mode != FileMode.WRITE && | 455 if (mode != FileMode.WRITE && |
| 440 mode != FileMode.APPEND) { | 456 mode != FileMode.APPEND) { |
| 441 throw new FileIOException( | 457 throw new FileIOException( |
| 442 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); | 458 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); |
| 443 } | 459 } |
| 444 var consumer = new _FileStreamConsumer(this, mode); | 460 var consumer = new _FileStreamConsumer(this, mode); |
| (...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 new FileIOException("File closed '$_path'")); | 1027 new FileIOException("File closed '$_path'")); |
| 1012 }); | 1028 }); |
| 1013 return completer.future; | 1029 return completer.future; |
| 1014 } | 1030 } |
| 1015 | 1031 |
| 1016 final String _path; | 1032 final String _path; |
| 1017 int _id; | 1033 int _id; |
| 1018 | 1034 |
| 1019 SendPort _fileService; | 1035 SendPort _fileService; |
| 1020 } | 1036 } |
| OLD | NEW |