Chromium Code Reviews| Index: runtime/bin/file_impl.dart |
| diff --git a/runtime/bin/file_impl.dart b/runtime/bin/file_impl.dart |
| index 771a9b9e85692284c7a93a1b9e853fd2115f5e79..bd84b1f18aa0ab8c0c5d551dc591d65f951fc361 100644 |
| --- a/runtime/bin/file_impl.dart |
| +++ b/runtime/bin/file_impl.dart |
| @@ -104,325 +104,25 @@ class _FileOutputStream implements OutputStream { |
| } |
| -class _FileOperation { |
| - abstract void execute(ReceivePort port); |
| - |
| - void set replyPort(SendPort port) { |
| - _replyPort = port; |
| - } |
| - |
| - bool isWrite() => false; |
| - |
| - SendPort _replyPort; |
| -} |
| - |
| - |
| -class _ExistsOperation extends _FileOperation { |
| - _ExistsOperation(String this._name); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.exists(_name), port.toSendPort()); |
| - } |
| - |
| - String _name; |
| -} |
| - |
| - |
| -class _OpenOperation extends _FileOperation { |
| - _OpenOperation(String this._name, int this._mode); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.checkedOpen(_name, _mode), |
| - port.toSendPort()); |
| - } |
| - |
| - String _name; |
| - int _mode; |
| -} |
| - |
| - |
| -class _CloseOperation extends _FileOperation { |
| - _CloseOperation(int this._id); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.close(_id), port.toSendPort()); |
| - } |
| - |
| - int _id; |
| -} |
| - |
| - |
| -class _ReadByteOperation extends _FileOperation { |
| - _ReadByteOperation(int this._id); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.readByte(_id), port.toSendPort()); |
| - } |
| - |
| - int _id; |
| -} |
| - |
| - |
| -class _ReadListResult { |
| - _ReadListResult(this.read, this.buffer); |
| - int read; |
| - List buffer; |
| -} |
| - |
| - |
| -class _ReadListOperation extends _FileOperation { |
| - _ReadListOperation(int this._id, |
| - int this._length, |
| - int this._offset, |
| - int this._bytes); |
| - |
| - void execute(ReceivePort port) { |
| - if (_bytes == 0) { |
| - _replyPort.send(0, port.toSendPort()); |
| - return; |
| - } |
| - int index = |
| - _FileUtils.checkReadWriteListArguments(_length, _offset, _bytes); |
| - if (index != 0) { |
| - _replyPort.send("index out of range in readList: $index", |
| - port.toSendPort()); |
| - return; |
| - } |
| - ByteArray buffer = new ByteArray(_bytes); |
| - var result = |
| - new _ReadListResult(_FileUtils.readList(_id, buffer, 0, _bytes), |
| - buffer); |
| - _replyPort.send(result, port.toSendPort()); |
| - } |
| - |
| - int _id; |
| - int _length; |
| - int _offset; |
| - int _bytes; |
| -} |
| - |
| - |
| -class _WriteByteOperation extends _FileOperation { |
| - _WriteByteOperation(int this._id, int this._value); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.writeByte(_id, _value), port.toSendPort()); |
| - } |
| - |
| - bool isWrite() => true; |
| - |
| - int _id; |
| - int _value; |
| -} |
| - |
| - |
| -class _WriteListOperation extends _FileOperation { |
| - _WriteListOperation(int this._id, |
| - List this._buffer, |
| - int this._offset, |
| - int this._bytes); |
| - |
| - void execute(ReceivePort port) { |
| - if (_bytes == 0) { |
| - _replyPort.send(0, port.toSendPort()); |
| - return; |
| - } |
| - int index = |
| - _FileUtils.checkReadWriteListArguments(_buffer.length, _offset, _bytes); |
| - if (index != 0) { |
| - _replyPort.send("index out of range in writeList: $index", |
| - port.toSendPort()); |
| - return; |
| - } |
| - var result = _FileUtils.writeList(_id, _buffer, _offset, _bytes); |
| - _replyPort.send(result, port.toSendPort()); |
| - } |
| - |
| - bool isWrite() => true; |
| - |
| - int _id; |
| - List _buffer; |
| - int _offset; |
| - int _bytes; |
| -} |
| - |
| - |
| -class _WriteStringOperation extends _FileOperation { |
| - _WriteStringOperation(int this._id, String this._string); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.checkedWriteString(_id, _string), |
| - port.toSendPort()); |
| - } |
| - |
| - bool isWrite() => true; |
| - |
| - int _id; |
| - String _string; |
| -} |
| - |
| - |
| -class _PositionOperation extends _FileOperation { |
| - _PositionOperation(int this._id); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.position(_id), port.toSendPort()); |
| - } |
| - |
| - int _id; |
| -} |
| - |
| - |
| -class _SetPositionOperation extends _FileOperation { |
| - _SetPositionOperation(int this._id, int this._position); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.setPosition(_id, _position), port.toSendPort()); |
| - } |
| - |
| - int _id; |
| - int _position; |
| -} |
| - |
| - |
| -class _TruncateOperation extends _FileOperation { |
| - _TruncateOperation(int this._id, int this._length); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.truncate(_id, _length), port.toSendPort()); |
| - } |
| - |
| - int _id; |
| - int _length; |
| -} |
| - |
| - |
| -class _LengthOperation extends _FileOperation { |
| - _LengthOperation(int this._id); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.length(_id), port.toSendPort()); |
| - } |
| - |
| - int _id; |
| -} |
| - |
| - |
| -class _FlushOperation extends _FileOperation { |
| - _FlushOperation(int this._id); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.flush(_id), port.toSendPort()); |
| - } |
| - |
| - int _id; |
| -} |
| - |
| - |
| -class _FullPathOperation extends _FileOperation { |
| - _FullPathOperation(String this._name); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.checkedFullPath(_name), port.toSendPort()); |
| - } |
| - |
| - String _name; |
| -} |
| - |
| - |
| -class _CreateOperation extends _FileOperation { |
| - _CreateOperation(String this._name); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.checkedCreate(_name), port.toSendPort()); |
| - } |
| - |
| - String _name; |
| -} |
| - |
| - |
| -class _DeleteOperation extends _FileOperation { |
| - _DeleteOperation(String this._name); |
| - |
| - void execute(ReceivePort port) { |
| - _replyPort.send(_FileUtils.checkedDelete(_name), port.toSendPort()); |
| - } |
| - |
| - String _name; |
| -} |
| - |
| - |
| -class _ExitOperation extends _FileOperation { |
| - void execute(ReceivePort port) { |
| - port.close(); |
| - } |
| -} |
| - |
| - |
| -class _FileOperationIsolate extends Isolate { |
| - _FileOperationIsolate() : super.heavy(); |
| - |
| - void handleOperation(_FileOperation message, SendPort ignored) { |
| - message.execute(port); |
| - port.receive(handleOperation); |
| - } |
| - |
| - void main() { |
| - port.receive(handleOperation); |
| - } |
| -} |
| - |
| - |
| -class _FileOperationScheduler { |
| - _FileOperationScheduler() : _queue = new Queue(); |
| - |
| - void schedule(SendPort port) { |
| - assert(_isolate != null); |
| - if (_queue.isEmpty()) { |
| - port.send(new _ExitOperation()); |
| - _isolate = null; |
| - } else { |
| - port.send(_queue.removeFirst()); |
| - } |
| - } |
| - |
| - void scheduleWrap(void callback(result, ignored)) { |
| - return (result, replyTo) { |
| - callback(result, replyTo); |
| - schedule(replyTo); |
| - }; |
| - } |
| - |
| - void enqueue(_FileOperation operation, void callback(result, ignored)) { |
| - ReceivePort replyPort = new ReceivePort.singleShot(); |
| - replyPort.receive(scheduleWrap(callback)); |
| - operation.replyPort = replyPort.toSendPort(); |
| - _queue.addLast(operation); |
| - if (_isolate == null) { |
| - _isolate = new _FileOperationIsolate(); |
| - _isolate.spawn().then((port) { |
| - schedule(port); |
| - }); |
| - } |
| - } |
| - |
| - bool noPendingWrite() { |
| - int queuedWrites = 0; |
| - _queue.forEach((operation) { |
| - if (operation.isWrite()) { |
| - queuedWrites++; |
| - } |
| - }); |
| - return queuedWrites == 0; |
| - } |
| - |
| - Queue<_FileOperation> _queue; |
| - _FileOperationIsolate _isolate; |
| -} |
| - |
| - |
| // Helper class containing static file helper methods. |
| class _FileUtils { |
| + static final kExistsRequest = 0; |
| + static final kCreateRequest = 1; |
| + static final kDeleteRequest = 2; |
| + static final kOpenRequest = 3; |
| + static final kFullPathRequest = 4; |
| + static final kCloseRequest = 5; |
| + static final kPositionRequest = 6; |
| + static final kSetPositionRequest = 7; |
| + static final kTruncateRequest = 8; |
| + static final kLengthRequest = 9; |
| + static final kFlushRequest = 10; |
| + static final kReadByteRequest = 11; |
| + static final kWriteByteRequest = 12; |
| + static final kReadListRequest = 13; |
| + static final kWriteListRequest = 14; |
| + static final kWriteStringRequest = 15; |
| + |
| static bool exists(String name) native "File_Exists"; |
| static int open(String name, int mode) native "File_Open"; |
| static bool create(String name) native "File_Create"; |
| @@ -466,6 +166,7 @@ class _FileUtils { |
| static int length(int id) native "File_Length"; |
| static int flush(int id) native "File_Flush"; |
| static int openStdio(int fd) native "File_OpenStdio"; |
| + static SendPort newServicePort() native "File_NewServicePort"; |
| static int checkedOpen(String name, int mode) { |
| if (name is !String || mode is !int) return 0; |
| @@ -504,11 +205,12 @@ class _FileUtils { |
| // Class for encapsulating the native implementation of files. |
| class _File implements File { |
| // Constructor for file. |
| - _File(String this._name) |
| - : _scheduler = new _FileOperationScheduler(), |
| - _asyncUsed = false; |
| + _File(String this._name) : _asyncUsed = false; |
| void exists() { |
| + if (_fileService == null) { |
|
Mads Ager (google)
2012/02/20 13:50:31
How about having an ensureFileService here as well
Søren Gjesse
2012/02/21 14:22:39
Done.
|
| + _fileService = _FileUtils.newServicePort(); |
| + } |
| _asyncUsed = true; |
| if (_name is !String) { |
| if (_errorHandler != null) { |
| @@ -516,12 +218,12 @@ class _File implements File { |
| } |
| return; |
| } |
| - var operation = new _ExistsOperation(_name); |
| - _scheduler.enqueue(operation, (result, ignored) { |
| - var handler = |
| - (_existsHandler != null) ? _existsHandler : (result) => null; |
| - handler(result); |
| - }); |
| + List request = new List(2); |
|
Mads Ager (google)
2012/02/20 13:50:31
Why not use list literals here?
var request = [ _
Søren Gjesse
2012/02/21 14:22:39
Yes, but we cannot serialize list literals :-( I w
|
| + request[0] = _FileUtils.kExistsRequest; |
| + request[1] = _name; |
| + _fileService.call(request).receive((exists, replyTo) { |
| + if (_existsHandler != null) _existsHandler(exists); |
|
Mads Ager (google)
2012/02/20 13:50:31
Indentation is off. Here and in the rest of the fi
Søren Gjesse
2012/02/21 14:22:39
Done (Emacs Dart mode thinks this is the way).
|
| + }); |
| } |
| bool existsSync() { |
| @@ -536,17 +238,20 @@ class _File implements File { |
| } |
| void create() { |
| + if (_fileService == null) { |
| + _fileService = _FileUtils.newServicePort(); |
| + } |
| _asyncUsed = true; |
| - var handleCreateResult = (created, ignored) { |
| - var handler = (_createHandler != null) ? _createHandler : () => null; |
| - if (created) { |
| - handler(); |
| - } else if (_errorHandler != null) { |
| - _errorHandler("Cannot create file: $_name"); |
| - } |
| - }; |
| - var operation = new _CreateOperation(_name); |
| - _scheduler.enqueue(operation, handleCreateResult); |
| + List request = new List(2); |
| + request[0] = _FileUtils.kCreateRequest; |
| + request[1] = _name; |
| + _fileService.call(request).receive((created, replyTo) { |
| + if (created) { |
| + if (_createHandler != null) _createHandler(); |
| + } else if (_errorHandler != null) { |
| + _errorHandler("Cannot create file: $_name"); |
| + } |
| + }); |
| } |
| void createSync() { |
| @@ -561,17 +266,20 @@ class _File implements File { |
| } |
| void delete() { |
| + if (_fileService == null) { |
| + _fileService = _FileUtils.newServicePort(); |
| + } |
| _asyncUsed = true; |
| - var handleDeleteResult = (created, ignored) { |
| - var handler = (_deleteHandler != null) ? _deleteHandler : () => null; |
| - if (created) { |
| - handler(); |
| - } else if (_errorHandler != null) { |
| - _errorHandler("Cannot delete file: $_name"); |
| - } |
| - }; |
| - var operation = new _DeleteOperation(_name); |
| - _scheduler.enqueue(operation, handleDeleteResult); |
| + List request = new List(2); |
| + request[0] = _FileUtils.kDeleteRequest; |
| + request[1] = _name; |
| + _fileService.call(request).receive((deleted, replyTo) { |
| + if (deleted) { |
| + if (_deleteHandler != null) _deleteHandler(); |
| + } else if (_errorHandler != null) { |
| + _errorHandler("Cannot delete file: $_name"); |
| + } |
| + }); |
| } |
| void deleteSync() { |
| @@ -586,6 +294,9 @@ class _File implements File { |
| } |
| void open([FileMode mode = FileMode.READ]) { |
| + if (_fileService == null) { |
| + _fileService = _FileUtils.newServicePort(); |
| + } |
| _asyncUsed = true; |
| if (mode != FileMode.READ && |
| mode != FileMode.WRITE && |
| @@ -596,22 +307,24 @@ class _File implements File { |
| return; |
| } |
| } |
| - var handleOpenResult = (id, ignored) { |
| - // If no open handler is present, close the file immediately to |
| - // avoid leaking an open file descriptor. |
| - var handler = _openHandler; |
| - if (handler === null) { |
| - handler = (file) => file.close(); |
| - } |
| - if (id != 0) { |
| - var randomAccessFile = new _RandomAccessFile(id, _name); |
| - handler(randomAccessFile); |
| - } else if (_errorHandler != null) { |
| - _errorHandler("Cannot open file: $_name"); |
| - } |
| - }; |
| - var operation = new _OpenOperation(_name, mode._mode); |
| - _scheduler.enqueue(operation, handleOpenResult); |
| + List request = new List(3); |
| + request[0] = _FileUtils.kOpenRequest; |
| + request[1] = _name; |
| + request[2] = mode._mode; // Direct int value for serialization. |
| + _fileService.call(request).receive((id, replyTo) { |
| + var handler = _openHandler; |
| + if (handler === null) { |
| + // If no open handler is present, close the file immediately to |
| + // avoid leaking an open file descriptor. |
| + handler = (file) => file.close(); |
| + } |
| + if (id != 0) { |
| + var randomAccessFile = new _RandomAccessFile(id, _name); |
| + handler(randomAccessFile); |
| + } else if (_errorHandler != null) { |
| + _errorHandler("Cannot open file: $_name"); |
| + } |
| + }); |
| } |
| RandomAccessFile openSync([FileMode mode = FileMode.READ]) { |
| @@ -641,18 +354,20 @@ class _File implements File { |
| } |
| void fullPath() { |
| + if (_fileService == null) { |
| + _fileService = _FileUtils.newServicePort(); |
| + } |
| _asyncUsed = true; |
| - var handleFullPathResult = (result, ignored) { |
| - var handler = _fullPathHandler; |
| - if (handler == null) handler = (path) => null; |
| - if (result != null) { |
| - handler(result); |
| - } else if (_errorHandler != null) { |
| - _errorHandler("fullPath failed"); |
| - } |
| - }; |
| - var operation = new _FullPathOperation(_name); |
| - _scheduler.enqueue(operation, handleFullPathResult); |
| + List request = new List(2); |
| + request[0] = _FileUtils.kFullPathRequest; |
| + request[1] = _name; |
| + _fileService.call(request).receive((result, replyTo) { |
| + if (result != null) { |
| + if (_fullPathHandler != null) _fullPathHandler(result); |
| + } else if (_errorHandler != null) { |
| + _errorHandler("fullPath failed"); |
| + } |
| + }); |
| } |
| String fullPathSync() { |
| @@ -707,7 +422,7 @@ class _File implements File { |
| String _name; |
| bool _asyncUsed; |
| - _FileOperationScheduler _scheduler; |
| + SendPort _fileService; |
| var _existsHandler; |
| var _createHandler; |
| @@ -719,23 +434,22 @@ class _File implements File { |
| class _RandomAccessFile implements RandomAccessFile { |
| - _RandomAccessFile(int this._id, String this._name) |
| - : _scheduler = new _FileOperationScheduler(), |
| - _asyncUsed = false; |
| + _RandomAccessFile(int this._id, String this._name) : _asyncUsed = false; |
| void close() { |
| + _ensureFileService(); |
| _asyncUsed = true; |
| - var handleCloseResult = (result, ignored) { |
| - var handler = (_closeHandler != null) ? _closeHandler : () => null; |
| - if (result != -1) { |
| - _id = result; |
| - handler(); |
| - } else if (_errorHandler != null) { |
| - _errorHandler("Cannot close file: $_name"); |
| - } |
| - }; |
| - var operation = new _CloseOperation(_id); |
| - _scheduler.enqueue(operation, handleCloseResult); |
| + List request = new List(2); |
| + request[0] = _FileUtils.kCloseRequest; |
| + request[1] = _id; |
| + _fileService.call(request).receive((result, replyTo) { |
| + if (result != -1) { |
| + _id = result; |
| + if (_closeHandler != null) _closeHandler(); |
| + } else if (_errorHandler != null) { |
| + _errorHandler("Cannot close file: $_name"); |
| + } |
| + }); |
| } |
| void closeSync() { |
| @@ -751,18 +465,18 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| void readByte() { |
| + _ensureFileService(); |
| _asyncUsed = true; |
| - var handleReadByteResult = (result, ignored) { |
| - var handler = |
| - (_readByteHandler != null) ? _readByteHandler : (byte) => null; |
| - if (result != -1) { |
| - handler(result); |
| - } else if (_errorHandler != null) { |
| - _errorHandler("readByte failed"); |
| - } |
| - }; |
| - var operation = new _ReadByteOperation(_id); |
| - _scheduler.enqueue(operation, handleReadByteResult); |
| + List request = new List(2); |
| + request[0] = _FileUtils.kReadByteRequest; |
| + request[1] = _id; |
| + _fileService.call(request).receive((result, replyTo) { |
| + if (result != -1) { |
| + if (_readByteHandler != null) _readByteHandler(result); |
| + } else if (_errorHandler != null) { |
| + _errorHandler("readByte failed"); |
| + } |
| + }); |
| } |
| int readByteSync() { |
| @@ -778,6 +492,7 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| void readList(List<int> buffer, int offset, int bytes) { |
| + _ensureFileService(); |
| _asyncUsed = true; |
| if (buffer is !List || offset is !int || bytes is !int) { |
| if (_errorHandler != null) { |
| @@ -785,21 +500,21 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| return; |
| }; |
| - var handleReadListResult = (result, ignored) { |
| - var handler = |
| - (_readListHandler != null) ? _readListHandler : (result) => null; |
| - if (result is _ReadListResult && result.read != -1) { |
| - var read = result.read; |
| - buffer.setRange(offset, read, result.buffer); |
| - handler(read); |
| - return; |
| - } |
| - if (_errorHandler != null) { |
| - _errorHandler(result is String ? result : "readList failed"); |
| - } |
| - }; |
| - var operation = new _ReadListOperation(_id, buffer.length, offset, bytes); |
| - _scheduler.enqueue(operation, handleReadListResult); |
| + List request = new List(3); |
| + request[0] = _FileUtils.kReadListRequest; |
| + request[1] = _id; |
| + request[2] = bytes; |
| + _fileService.call(request).receive((result, replyTo) { |
| + if (result is List && result.length == 2 && result[0] != -1) { |
| + var read = result[0]; |
| + var data = result[1]; |
| + buffer.setRange(offset, read, data); |
| + if (_readListHandler != null) _readListHandler(read); |
| + return; |
| + } else if (_errorHandler != null) { |
| + _errorHandler(result is String ? result : "readList failed"); |
| + } |
| + }); |
| } |
| int readListSync(List<int> buffer, int offset, int bytes) { |
| @@ -830,6 +545,7 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| void writeByte(int value) { |
| + _ensureFileService(); |
| _asyncUsed = true; |
| if (value is !int) { |
| if (_errorHandler != null) { |
| @@ -837,15 +553,18 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| return; |
| } |
| - var handleReadByteResult = (result, ignored) { |
| - if (result == -1 &&_errorHandler != null) { |
| - _errorHandler("writeByte failed"); |
| - return; |
| - } |
| - _checkPendingWrites(); |
| - }; |
| - var operation = new _WriteByteOperation(_id, value); |
| - _scheduler.enqueue(operation, handleReadByteResult); |
| + List request = new List(3); |
| + request[0] = _FileUtils.kWriteByteRequest; |
| + request[1] = _id; |
| + request[2] = value; |
| + _fileService.call(request).receive((result, replyTo) { |
| + if (result != -1) { |
| + // TODO(sgjesse): Handle no pending writes correctly. |
|
Mads Ager (google)
2012/02/20 13:50:31
This one looks important. This should be fixed bef
Søren Gjesse
2012/02/22 16:27:07
Done.
|
| + if (_noPendingWriteHandler != null) _noPendingWriteHandler(); |
| + } else { |
| + _errorHandler("writeByte failed"); |
| + } |
| + }); |
| } |
| int writeByteSync(int value) { |
| @@ -864,6 +583,7 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| void writeList(List<int> buffer, int offset, int bytes) { |
| + _ensureFileService(); |
| _asyncUsed = true; |
| if (buffer is !List || offset is !int || bytes is !int) { |
| if (_errorHandler != null) { |
| @@ -871,21 +591,20 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| return; |
| } |
| - var handleWriteListResult = (result, ignored) { |
| - if (result is !String && result != -1) { |
| - if (result < bytes) { |
| - writeList(buffer, offset + result, bytes - result); |
| + List request = new List(5); |
| + request[0] = _FileUtils.kWriteListRequest; |
| + request[1] = _id; |
| + request[2] = buffer; |
| + request[3] = offset; |
| + request[4] = bytes; |
| + _fileService.call(request).receive((result, replyTo) { |
| + if (result is !String && result != -1) { |
| + // TODO(sgjesse): Handle no pending writes correctly. |
| + if (_noPendingWriteHandler != null) _noPendingWriteHandler(); |
| } else { |
| - _checkPendingWrites(); |
| + _errorHandler(result is String ? result : "writeList failed"); |
| } |
| - return; |
| - } |
| - if (_errorHandler != null) { |
| - _errorHandler(result is String ? result : "writeList failed"); |
| - } |
| - }; |
| - var operation = new _WriteListOperation(_id, buffer, offset, bytes); |
| - _scheduler.enqueue(operation, handleWriteListResult); |
| + }); |
| } |
| int writeListSync(List<int> buffer, int offset, int bytes) { |
| @@ -910,20 +629,20 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| void writeString(String string) { |
| + _ensureFileService(); |
| _asyncUsed = true; |
| - var handleWriteStringResult = (result, ignored) { |
| - if (result == -1 &&_errorHandler != null) { |
| - _errorHandler("writeString failed"); |
| - return; |
| - } |
| - if (result < string.length) { |
| - writeString(string.substring(result)); |
| - } else { |
| - _checkPendingWrites(); |
| - } |
| - }; |
| - var operation = new _WriteStringOperation(_id, string); |
| - _scheduler.enqueue(operation, handleWriteStringResult); |
| + List request = new List(3); |
| + request[0] = _FileUtils.kWriteStringRequest; |
| + request[1] = _id; |
| + request[2] = string; |
| + _fileService.call(request).receive((result, replyTo) { |
| + if (result is !String && result != -1) { |
| + // TODO(sgjesse): Handle no pending writes correctly. |
| + if (_noPendingWriteHandler != null) _noPendingWriteHandler(); |
| + } else { |
| + _errorHandler(result is String ? result : "writeString failed"); |
| + } |
| + }); |
| } |
| int writeStringSync(String string) { |
| @@ -939,18 +658,18 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| void position() { |
| + _ensureFileService(); |
| _asyncUsed = true; |
| - var handlePositionResult = (result, ignored) { |
| - var handler = |
| - (_positionHandler != null) ? _positionHandler : (pos) => null; |
| - if (result == -1 && _errorHandler != null) { |
| - _errorHandler("position failed"); |
| - return; |
| - } |
| - handler(result); |
| - }; |
| - var operation = new _PositionOperation(_id); |
| - _scheduler.enqueue(operation, handlePositionResult); |
| + List request = new List(2); |
| + request[0] = _FileUtils.kPositionRequest; |
| + request[1] = _id; |
| + _fileService.call(request).receive((result, replyTo) { |
| + if (result != -1) { |
| + if (_positionHandler != null) _positionHandler(result); |
| + } else if (_errorHandler != null) { |
| + _errorHandler("position failed"); |
| + } |
| + }); |
| } |
| int positionSync() { |
| @@ -966,21 +685,23 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| void setPosition(int position) { |
| + _ensureFileService(); |
| _asyncUsed = true; |
| - var handleSetPositionResult = (result, ignored) { |
| - var handler = |
| - (_setPositionHandler != null) ? _setPositionHandler : () => null; |
| - if (result == false && _errorHandler != null) { |
| - _errorHandler("setPosition failed"); |
| - return; |
| - } |
| - handler(); |
| - }; |
| - var operation = new _SetPositionOperation(_id, position); |
| - _scheduler.enqueue(operation, handleSetPositionResult); |
| + List request = new List(3); |
| + request[0] = _FileUtils.kSetPositionRequest; |
| + request[1] = _id; |
| + request[2] = position; |
| + _fileService.call(request).receive((result, replyTo) { |
| + if (result) { |
| + if (_setPositionHandler != null) _setPositionHandler(); |
| + } else if (_errorHandler != null) { |
| + _errorHandler("setPosition failed"); |
| + } |
| + }); |
| } |
| void setPositionSync(int position) { |
| + _ensureFileService(); |
| if (_asyncUsed) { |
| throw new FileIOException( |
| "Mixed use of synchronous and asynchronous API"); |
| @@ -992,17 +713,19 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| void truncate(int length) { |
| + _ensureFileService(); |
| _asyncUsed = true; |
| - var handleTruncateResult = (result, ignored) { |
| - var handler = (_truncateHandler != null) ? _truncateHandler : () => null; |
| - if (result == false && _errorHandler != null) { |
| - _errorHandler("truncate failed"); |
| - return; |
| - } |
| - handler(); |
| - }; |
| - var operation = new _TruncateOperation(_id, length); |
| - _scheduler.enqueue(operation, handleTruncateResult); |
| + List request = new List(3); |
| + request[0] = _FileUtils.kTruncateRequest; |
| + request[1] = _id; |
| + request[2] = length; |
| + _fileService.call(request).receive((result, replyTo) { |
| + if (result) { |
| + if (_truncateHandler != null) _truncateHandler(); |
| + } else if (_errorHandler != null) { |
| + _errorHandler("truncate failed"); |
| + } |
| + }); |
| } |
| void truncateSync(int length) { |
| @@ -1017,17 +740,18 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| void length() { |
| + _ensureFileService(); |
| _asyncUsed = true; |
| - var handleLengthResult = (result, ignored) { |
| - var handler = (_lengthHandler != null) ? _lengthHandler : (pos) => null; |
| - if (result == -1 && _errorHandler != null) { |
| - _errorHandler("length failed"); |
| - return; |
| - } |
| - handler(result); |
| - }; |
| - var operation = new _LengthOperation(_id); |
| - _scheduler.enqueue(operation, handleLengthResult); |
| + List request = new List(2); |
| + request[0] = _FileUtils.kLengthRequest; |
| + request[1] = _id; |
| + _fileService.call(request).receive((result, replyTo) { |
| + if (result != -1) { |
| + if (_lengthHandler != null) _lengthHandler(result); |
| + } else if (_errorHandler != null) { |
| + _errorHandler("length failed"); |
| + } |
| + }); |
| } |
| int lengthSync() { |
| @@ -1043,17 +767,18 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| void flush() { |
| + _ensureFileService(); |
| _asyncUsed = true; |
| - var handleFlushResult = (result, ignored) { |
| - var handler = (_flushHandler != null) ? _flushHandler : (pos) => null; |
| - if (result == -1 && _errorHandler != null) { |
| - _errorHandler("flush failed"); |
| - return; |
| - } |
| - handler(); |
| - }; |
| - var operation = new _FlushOperation(_id); |
| - _scheduler.enqueue(operation, handleFlushResult); |
| + List request = new List(2); |
| + request[0] = _FileUtils.kFlushRequest; |
| + request[1] = _id; |
| + _fileService.call(request).receive((result, replyTo) { |
| + if (result != -1) { |
| + if (_flushHandler != null) _flushHandler(); |
| + } else if (_errorHandler != null) { |
| + _errorHandler("flush failed"); |
| + } |
| + }); |
| } |
| void flushSync() { |
| @@ -1109,11 +834,17 @@ class _RandomAccessFile implements RandomAccessFile { |
| _flushHandler = handler; |
| } |
| + void _ensureFileService() { |
| + if (_fileService == null) { |
| + _fileService = _FileUtils.newServicePort(); |
| + } |
| + } |
| + |
| String _name; |
| int _id; |
| bool _asyncUsed; |
| - _FileOperationScheduler _scheduler; |
| + SendPort _fileService; |
| var _closeHandler; |
| var _readByteHandler; |