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 |