Chromium Code Reviews| Index: runtime/bin/file_impl.dart |
| diff --git a/runtime/bin/file_impl.dart b/runtime/bin/file_impl.dart |
| index d33d269e343f8d0b7b6797a84f0a85274f49726a..ab0cc092ca336cc25af06c6380d02cbdadb3e8e6 100644 |
| --- a/runtime/bin/file_impl.dart |
| +++ b/runtime/bin/file_impl.dart |
| @@ -3,59 +3,67 @@ |
| // BSD-style license that can be found in the LICENSE file. |
| class _FileInputStream extends _BaseDataInputStream implements InputStream { |
| - _FileInputStream(String name) { |
| + _FileInputStream(String name) |
| + : _data = [], |
| + _position = 0, |
| + _filePosition = 0 { |
| var file = new File(name); |
| - _data = []; |
| - _position = 0; |
| - var chained = file.open(FileMode.READ).chain((openedFile) { |
| - return _readDataFromFile(openedFile); |
| - }); |
| - chained.handleException((e) { |
| + var future = file.open(FileMode.READ); |
| + future.handleException((e) { |
| _reportError(e); |
| return true; |
| - }); |
| + }); |
|
Søren Gjesse
2012/06/07 12:17:13
Indentation.
Bill Hesse
2012/06/07 13:15:08
Done.
|
| + future.then(_setupOpenedFile); |
| } |
| - _FileInputStream.fromStdio(int fd) { |
| + _FileInputStream.fromStdio(int fd) |
| + : _data = [], |
| + _position = 0, |
| + _filePosition = 0 { |
| assert(fd == 0); |
| - var file = _File._openStdioSync(fd); |
| - _data = []; |
| - _position = 0; |
| - _readDataFromFile(file).handleException((e) { |
| + _setupOpenedFile(_File._openStdioSync(fd)); |
| + } |
| + |
| + void _setupOpenedFile(RandomAccessFile openedFile) { |
| + _openedFile = openedFile; |
| + var chained = _openedFile.length().chain((len) { |
| + _fileLength = len; |
| + return _fillBuffer(); |
| + }); |
| + chained.handleException((e) { |
| _reportError(e); |
| return true; |
| }); |
| + chained.then((ignored) => _checkScheduleCallbacks()); |
| } |
| - Future<RandomAccessFile> _closeAfterRead(RandomAccessFile openedFile) { |
| - return openedFile.close().transform((ignore) { |
| - _streamMarkedClosed = true; |
| - _checkScheduleCallbacks(); |
| - return openedFile; |
| - }); |
| - } |
| + Future<int> _fillBuffer() { |
| + Expect.equals(_position, _data.length); |
| + // Expect.isTrue(_filePosition < _fileLength); |
|
Søren Gjesse
2012/06/07 12:17:13
Code in comments.
Bill Hesse
2012/06/07 13:15:08
Done.
|
| - Future<RandomAccessFile> _readDataFromFile(RandomAccessFile openedFile) { |
| - return openedFile.length().chain((length) { |
| - var contents = new Uint8List(length); |
| - if (length != 0) { |
| - return openedFile.readList(contents, 0, length).chain((read) { |
| - if (read != length) { |
| - throw new FileIOException( |
| - 'Failed reading file contents in FileInputStream'); |
| - } else { |
| - _data = contents; |
| - } |
| - return _closeAfterRead(openedFile); |
| - }); |
| - } else { |
| - return _closeAfterRead(openedFile); |
| + int size = Math.min(_bufferLength, _fileLength - _filePosition); |
| + if (_data.length != size) { |
| + _data = new Uint8List(size); |
| + } |
| + var future = _openedFile.readList(_data, 0, _data.length); |
|
Bill Hesse
2012/06/07 13:15:08
tab?
|
| + future.transform((read) { |
|
Bill Hesse
2012/06/07 13:15:08
future = future.transform
Fixed.
|
| + _filePosition += read; |
| + if (read != _data.length) { |
| + _data.removeRange(read, _data.length - read); |
| + } |
| + _position = 0; |
| + |
| + if (_fileLength == _filePosition) { |
| + _streamMarkedClosed = true; |
| + _openedFile.close(); |
| } |
| + return read; |
| }); |
| + return future; |
| } |
| int available() { |
| - return _closed ? 0 : _data.length - _position; |
| + return closed ? 0 : _data.length - _position; |
| } |
| void pipe(OutputStream output, [bool close = true]) { |
| @@ -66,25 +74,45 @@ class _FileInputStream extends _BaseDataInputStream implements InputStream { |
| List<int> result = new Uint8List(bytesToRead); |
|
Søren Gjesse
2012/06/07 12:17:13
Maybe we can avoid the copying here if reading the
Bill Hesse
2012/06/07 13:15:08
Done.
|
| result.setRange(0, bytesToRead, _data, _position); |
| _position += bytesToRead; |
| - _checkScheduleCallbacks(); |
| + if (_position == _data.length && !_streamMarkedClosed) { |
| + _fillBuffer().then((ignored) { |
| + _checkScheduleCallbacks(); |
| + }); |
| + } else { |
| + _checkScheduleCallbacks(); |
| + } |
| return result; |
| } |
| int _readInto(List<int> buffer, int offset, int len) { |
| buffer.setRange(offset, len, _data, _position); |
| _position += len; |
|
Søren Gjesse
2012/06/07 12:17:13
Maybe refactor the duplicate (here and above in _r
Bill Hesse
2012/06/07 13:15:08
Done.
|
| - _checkScheduleCallbacks(); |
| + if (_position == _data.length && !_streamMarkedClosed) { |
| + _fillBuffer().then((ignored) { |
| + _checkScheduleCallbacks(); |
| + }); |
| + } else { |
| + _checkScheduleCallbacks(); |
| + } |
| return len; |
| } |
| void _close() { |
| - if (_closed) return; |
| - _closed = true; |
| + _streamMarkedClosed = true; |
| + _data = []; |
| + _position = 0; |
| + if (!_openedFile.closed) { |
| + _openedFile.close(); |
| + } |
| } |
| + static final int _bufferLength = 64 * 1024; |
| + |
| + RandomAccessFile _openedFile; |
| List<int> _data; |
| int _position; |
| - bool _closed = false; |
| + int _filePosition; |
| + int _fileLength; |
| } |
| @@ -685,13 +713,13 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| Future<RandomAccessFile> close() { |
| Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
| - if (_isClosed) return _completeWithClosedException(completer); |
| + if (closed) return _completeWithClosedException(completer); |
| _ensureFileService(); |
| List request = new List(2); |
| request[0] = _FileUtils.CLOSE_REQUEST; |
| request[1] = _id; |
| // Set the id_ to 0 (NULL) to ensure the no more async requests |
| - // can be issues for this file. |
| + // can be issued for this file. |
| _id = 0; |
| return _fileService.call(request).transform((result) { |
| if (result != -1) { |
| @@ -714,7 +742,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| Future<int> readByte() { |
| _ensureFileService(); |
| Completer<int> completer = new Completer<int>(); |
| - if (_isClosed) return _completeWithClosedException(completer); |
| + if (closed) return _completeWithClosedException(completer); |
| List request = new List(2); |
| request[0] = _FileUtils.READ_BYTE_REQUEST; |
| request[1] = _id; |
| @@ -749,7 +777,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| }); |
| return completer.future; |
| }; |
| - if (_isClosed) return _completeWithClosedException(completer); |
| + if (closed) return _completeWithClosedException(completer); |
| List request = new List(3); |
| request[0] = _FileUtils.READ_LIST_REQUEST; |
| request[1] = _id; |
| @@ -799,7 +827,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| }); |
| return completer.future; |
| } |
| - if (_isClosed) return _completeWithClosedException(completer); |
| + if (closed) return _completeWithClosedException(completer); |
| List request = new List(3); |
| request[0] = _FileUtils.WRITE_BYTE_REQUEST; |
| request[1] = _id; |
| @@ -840,7 +868,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| }); |
| return completer.future; |
| } |
| - if (_isClosed) return _completeWithClosedException(completer); |
| + if (closed) return _completeWithClosedException(completer); |
| List result; |
| try { |
| @@ -894,7 +922,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| [Encoding encoding = Encoding.UTF_8]) { |
| _ensureFileService(); |
| Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
| - if (_isClosed) return _completeWithClosedException(completer); |
| + if (closed) return _completeWithClosedException(completer); |
| List request = new List(3); |
| request[0] = _FileUtils.WRITE_STRING_REQUEST; |
| request[1] = _id; |
| @@ -920,7 +948,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| Future<int> position() { |
| _ensureFileService(); |
| Completer<int> completer = new Completer<int>(); |
| - if (_isClosed) return _completeWithClosedException(completer); |
| + if (closed) return _completeWithClosedException(completer); |
| List request = new List(2); |
| request[0] = _FileUtils.POSITION_REQUEST; |
| request[1] = _id; |
| @@ -945,7 +973,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| Future<RandomAccessFile> setPosition(int position) { |
| _ensureFileService(); |
| Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
| - if (_isClosed) return _completeWithClosedException(completer); |
| + if (closed) return _completeWithClosedException(completer); |
| List request = new List(3); |
| request[0] = _FileUtils.SET_POSITION_REQUEST; |
| request[1] = _id; |
| @@ -970,7 +998,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| Future<RandomAccessFile> truncate(int length) { |
| _ensureFileService(); |
| Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
| - if (_isClosed) return _completeWithClosedException(completer); |
| + if (closed) return _completeWithClosedException(completer); |
| List request = new List(3); |
| request[0] = _FileUtils.TRUNCATE_REQUEST; |
| request[1] = _id; |
| @@ -995,7 +1023,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| Future<int> length() { |
| _ensureFileService(); |
| Completer<int> completer = new Completer<int>(); |
| - if (_isClosed) return _completeWithClosedException(completer); |
| + if (closed) return _completeWithClosedException(completer); |
| List request = new List(2); |
| request[0] = _FileUtils.LENGTH_REQUEST; |
| request[1] = _id; |
| @@ -1020,7 +1048,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| Future<RandomAccessFile> flush() { |
| _ensureFileService(); |
| Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
| - if (_isClosed) return _completeWithClosedException(completer); |
| + if (closed) return _completeWithClosedException(completer); |
| List request = new List(2); |
| request[0] = _FileUtils.FLUSH_REQUEST; |
| request[1] = _id; |
| @@ -1049,10 +1077,10 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| } |
| } |
| - bool get _isClosed() => _id == 0; |
| + bool get closed() => _id == 0; |
| void _checkNotClosed() { |
| - if (_isClosed) { |
| + if (closed) { |
| throw new FileIOException("File closed '$_name'"); |
| } |
| } |