Chromium Code Reviews| 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 class _FileInputStream extends _BaseDataInputStream implements InputStream { | 5 class _FileInputStream extends _BaseDataInputStream implements InputStream { |
| 6 _FileInputStream(RandomAccessFile this._file, int this._length) { | 6 _FileInputStream(String name) { |
| 7 _streamMarkedClosed = true; | 7 _file = new File(name); |
| 8 _checkScheduleCallbacks(); | 8 _data = []; |
| 9 _position = 0; | |
| 10 _file.errorHandler = (String s) { | |
| 11 if (_clientErrorHandler != null) { | |
| 12 _clientErrorHandler(); | |
| 13 } | |
| 14 }; | |
| 15 _file.open(); | |
| 16 _file.openHandler = (openedFile) { | |
| 17 _readDataFromFile(openedFile); | |
| 18 }; | |
| 9 } | 19 } |
| 10 | 20 |
| 11 _FileInputStream.fromStdio(int fd) { | 21 _FileInputStream.fromStdio(int fd) { |
| 12 assert(fd == 0); | 22 assert(fd == 0); |
| 13 _file = _File._openStdioSync(fd); | 23 _file = _File._openStdioSync(fd); |
| 14 _length = _file.lengthSync(); | 24 _data = []; |
| 15 _streamMarkedClosed = true; | 25 _position = 0; |
| 16 _checkScheduleCallbacks(); | 26 _readDataFromFile(_file); |
| 27 } | |
| 28 | |
| 29 void _readDataFromFile(RandomAccessFile openedFile) { | |
| 30 openedFile.errorHandler = (String s) { | |
| 31 if (_clientErrorHandler != null) { | |
| 32 _clientErrorHandler(); | |
| 33 } | |
| 34 }; | |
| 35 openedFile.length(); | |
|
Søren Gjesse
2012/02/28 07:40:25
What is length when the file is stdin?
Søren Gjesse
2012/02/28 08:10:26
This is correct. I forgot that the constructor _Fi
| |
| 36 openedFile.lengthHandler = (length) { | |
| 37 var contents = new ByteArray(length); | |
| 38 if (length != 0) { | |
| 39 openedFile.readList(contents, 0, length); | |
| 40 openedFile.readListHandler = (read) { | |
| 41 if (read != length) { | |
| 42 if (_clientErrorHandler != null) { | |
| 43 _clientErrorHandler(); | |
| 44 } | |
| 45 _streamMarkedClosed = true; | |
| 46 _checkScheduleCallbacks(); | |
| 47 } else { | |
| 48 _data = contents; | |
| 49 _streamMarkedClosed = true; | |
| 50 _checkScheduleCallbacks(); | |
| 51 } | |
| 52 openedFile.close(); | |
| 53 }; | |
| 54 } else { | |
| 55 _streamMarkedClosed = true; | |
| 56 _checkScheduleCallbacks(); | |
| 57 openedFile.close(); | |
| 58 } | |
| 59 }; | |
| 17 } | 60 } |
| 18 | 61 |
| 19 int available() { | 62 int available() { |
| 20 return _closed ? 0 : _length - _file.positionSync(); | 63 return _closed ? 0 : _data.length - _position; |
| 21 } | 64 } |
| 22 | 65 |
| 23 void pipe(OutputStream output, [bool close = true]) { | 66 void pipe(OutputStream output, [bool close = true]) { |
| 24 _pipe(this, output, close: close); | 67 _pipe(this, output, close: close); |
| 25 } | 68 } |
| 26 | 69 |
| 27 List<int> _read(int bytesToRead) { | 70 List<int> _read(int bytesToRead) { |
| 28 ByteArray result = new ByteArray(bytesToRead); | 71 ByteArray result = new ByteArray(bytesToRead); |
| 29 int bytesRead = _file.readListSync(result, 0, bytesToRead); | 72 result.setRange(0, bytesToRead, _data, _position); |
| 30 if (bytesRead < bytesToRead) { | 73 _position += bytesToRead; |
| 31 ByteArray buffer = new ByteArray(bytesRead); | |
| 32 buffer.setRange(0, bytesRead, result); | |
| 33 result = buffer; | |
| 34 } | |
| 35 _checkScheduleCallbacks(); | 74 _checkScheduleCallbacks(); |
| 36 return result; | 75 return result; |
| 37 } | 76 } |
| 38 | 77 |
| 39 int _readInto(List<int> buffer, int offset, int len) { | 78 int _readInto(List<int> buffer, int offset, int len) { |
| 40 int result = _file.readListSync(buffer, offset, len); | 79 buffer.setRange(offset, len, _data, _position); |
| 80 _position += len; | |
| 41 _checkScheduleCallbacks(); | 81 _checkScheduleCallbacks(); |
| 42 return result; | 82 return len; |
| 43 } | 83 } |
| 44 | 84 |
| 45 void _close() { | 85 void _close() { |
| 46 if (_closed) return; | 86 if (_closed) return; |
| 47 _file.closeSync(); | |
| 48 _closed = true; | 87 _closed = true; |
| 49 } | 88 } |
| 50 | 89 |
| 51 RandomAccessFile _file; | 90 File _file; |
| 52 int _length; | 91 List<int> _data; |
| 92 int _position; | |
| 53 bool _closed = false; | 93 bool _closed = false; |
| 54 } | 94 } |
| 55 | 95 |
| 56 | 96 |
| 57 class _FileOutputStream implements OutputStream { | 97 class _FileOutputStream implements OutputStream { |
| 58 _FileOutputStream(this._file); | 98 _FileOutputStream(String name, int mode) { |
| 99 _pendingOperations = new List<List<int>>(); | |
| 100 var f = new File(name); | |
| 101 f.open(mode); | |
| 102 f.openHandler = (openedFile) { | |
| 103 _file = openedFile; | |
| 104 _setupFileHandlers(); | |
| 105 _processPendingOperations(); | |
| 106 }; | |
| 107 f.errorHandler = (e) { | |
| 108 if (_errorHandler != null) _errorHandler(); | |
| 109 }; | |
| 110 } | |
| 59 | 111 |
| 60 _FileOutputStream.fromStdio(int fd) { | 112 _FileOutputStream.fromStdio(int fd) { |
| 61 assert(1 <= fd && fd <= 2); | 113 assert(1 <= fd && fd <= 2); |
| 62 _file = _File._openStdioSync(fd); | 114 _file = _File._openStdioSync(fd); |
| 115 _setupFileHandlers(); | |
| 116 } | |
| 117 | |
| 118 | |
| 119 void _setupFileHandlers() { | |
| 120 _file.errorHandler = (e) { | |
| 121 if (_errorHandler != null) _errorHandler(); | |
| 122 }; | |
| 123 _file.noPendingWriteHandler = () { | |
| 124 if (!_streamMarkedClosed && _noPendingWriteHandler != null) { | |
| 125 _noPendingWriteHandler(); | |
| 126 } | |
| 127 }; | |
| 128 _file.closeHandler = () { | |
| 129 if (_closeHandler != null) _closeHandler(); | |
| 130 }; | |
| 63 } | 131 } |
| 64 | 132 |
| 65 bool write(List<int> buffer, [bool copyBuffer = false]) { | 133 bool write(List<int> buffer, [bool copyBuffer = false]) { |
| 66 bool result = _write(buffer, 0, buffer.length); | 134 var data = buffer; |
| 67 if (result) { | 135 if (copyBuffer) { |
| 68 _checkScheduleCallbacks(); | 136 var length = buffer.length; |
| 137 data = new ByteArray(length); | |
| 138 data.setRange(0, length, buffer, 0); | |
| 69 } | 139 } |
| 70 return result; | 140 if (_file == null) { |
| 141 _pendingOperations.add(data); | |
| 142 } else { | |
| 143 _write(data, 0, data.length); | |
| 144 } | |
| 145 return false; | |
|
Søren Gjesse
2012/02/28 07:40:25
We should probably revisit whether write and write
Mads Ager (google)
2012/02/28 08:21:00
Agreed, we probably should.
| |
| 71 } | 146 } |
| 72 | 147 |
| 73 bool writeFrom(List<int> buffer, [int offset = 0, int len]) { | 148 bool writeFrom(List<int> buffer, [int offset = 0, int len]) { |
| 74 bool result = _write( | 149 // A copy is required by the interface. |
| 75 buffer, offset, (len == null) ? buffer.length - offset : len); | 150 var length = buffer.length - offset; |
| 76 if (result) { | 151 if (len != null) { |
| 77 _checkScheduleCallbacks(); | 152 if (len > length) throw new IndexOutOfRangeException(len); |
| 153 length = len; | |
| 78 } | 154 } |
| 79 return result; | 155 var copy = new ByteArray(length); |
| 156 copy.setRange(0, length, buffer, offset); | |
| 157 return write(copy); | |
| 80 } | 158 } |
| 81 | 159 |
| 82 void close() { | 160 void close() { |
| 83 if (_scheduledNoPendingWriteCallback != null) { | 161 if (_file == null) { |
| 84 _scheduledNoPendingWriteCallback.cancel(); | 162 _pendingOperations.add(null); |
| 85 } | 163 } else { |
| 86 if (!_streamMarkedClosed) { | 164 if (!_streamMarkedClosed) { |
| 87 _file.closeSync(); | 165 _file.close(); |
| 88 _streamMarkedClosed = true; | 166 _streamMarkedClosed = true; |
| 89 _checkScheduleCallbacks(); | 167 } |
| 90 } | 168 } |
| 91 } | 169 } |
| 92 | 170 |
| 93 void set noPendingWriteHandler(void callback()) { | 171 void set noPendingWriteHandler(void callback()) { |
| 94 _noPendingWriteHandler = callback; | 172 _noPendingWriteHandler = callback; |
| 95 _checkScheduleCallbacks(); | |
| 96 } | 173 } |
| 97 | 174 |
| 98 void set closeHandler(void callback()) { | 175 void set closeHandler(void callback()) { |
| 99 _closeHandler = callback; | 176 _closeHandler = callback; |
| 100 _checkScheduleCallbacks(); | |
| 101 } | 177 } |
| 102 | 178 |
| 103 void set errorHandler(void callback()) { | 179 void set errorHandler(void callback()) { |
| 104 // TODO(sgjesse): How to handle this? | 180 _errorHandler = callback; |
| 105 } | 181 } |
| 106 | 182 |
| 107 bool _write(List<int> buffer, int offset, int len) { | 183 void _processPendingOperations() { |
| 108 int bytesWritten = _file.writeListSync(buffer, offset, len); | 184 _pendingOperations.forEach((buffer) { |
| 109 if (bytesWritten == len) { | 185 (buffer != null) ? write(buffer) : close(); |
| 110 return true; | 186 }); |
| 111 } else { | 187 _pendingOperations = null; |
| 112 throw "FileOutputStream: write error"; | |
| 113 } | |
| 114 } | 188 } |
| 115 | 189 |
| 116 void _checkScheduleCallbacks() { | 190 void _write(List<int> buffer, int offset, int len) { |
| 117 void issueNoPendingWriteCallback(Timer timer) { | 191 _file.writeList(buffer, offset, len); |
| 118 _scheduledNoPendingWriteCallback = null; | |
| 119 if (_noPendingWriteHandler !== null) { | |
| 120 _noPendingWriteHandler(); | |
| 121 _checkScheduleCallbacks(); | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 void issueCloseCallback(Timer timer) { | |
| 126 if (_closeHandler !== null) _closeHandler(); | |
| 127 } | |
| 128 | |
| 129 // Schedule no pending write callbacks if the stream is not yet | |
| 130 // closed and close callback if it is closing. | |
| 131 if (!_closeCallbackCalled) { | |
| 132 if (_scheduledNoPendingWriteCallback == null) { | |
| 133 _scheduledNoPendingWriteCallback = | |
| 134 new Timer(issueNoPendingWriteCallback, 0); | |
| 135 } | |
| 136 if (_streamMarkedClosed && _scheduledCloseCallback == null) { | |
| 137 _scheduledCloseCallback = new Timer(issueCloseCallback, 0); | |
| 138 } | |
| 139 } | |
| 140 } | 192 } |
| 141 | 193 |
| 142 RandomAccessFile _file; | 194 RandomAccessFile _file; |
| 143 | 195 |
| 144 // When this is set to true the stream is marked closed. When a | 196 // When this is set to true the stream is marked closed. When a |
| 145 // stream is marked closed no more data can be written. | 197 // stream is marked closed no more data can be written. |
| 146 bool _streamMarkedClosed = false; | 198 bool _streamMarkedClosed = false; |
| 147 | 199 |
| 148 // When this is set to true the close callback has been called and | 200 // When this is set to true the close callback has been called and |
| 149 // the stream is fully closed. | 201 // the stream is fully closed. |
| 150 bool _closeCallbackCalled = false; | 202 bool _closeCallbackCalled = false; |
| 151 | 203 |
| 152 Timer _scheduledNoPendingWriteCallback; | 204 // List of pending writes that were issued before the underlying |
| 153 Timer _scheduledCloseCallback; | 205 // file was successfully opened. |
| 206 List<List<int>> _pendingOperations; | |
| 207 | |
| 154 Function _noPendingWriteHandler; | 208 Function _noPendingWriteHandler; |
| 155 Function _closeHandler; | 209 Function _closeHandler; |
| 210 Function _errorHandler; | |
| 156 } | 211 } |
| 157 | 212 |
| 158 | 213 |
| 159 // Helper class containing static file helper methods. | 214 // Helper class containing static file helper methods. |
| 160 class _FileUtils { | 215 class _FileUtils { |
| 161 static final kExistsRequest = 0; | 216 static final kExistsRequest = 0; |
| 162 static final kCreateRequest = 1; | 217 static final kCreateRequest = 1; |
| 163 static final kDeleteRequest = 2; | 218 static final kDeleteRequest = 2; |
| 164 static final kOpenRequest = 3; | 219 static final kOpenRequest = 3; |
| 165 static final kFullPathRequest = 4; | 220 static final kFullPathRequest = 4; |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 throw new FileIOException( | 509 throw new FileIOException( |
| 455 "Mixed use of synchronous and asynchronous API"); | 510 "Mixed use of synchronous and asynchronous API"); |
| 456 } | 511 } |
| 457 String result = _FileUtils.checkedFullPath(_name); | 512 String result = _FileUtils.checkedFullPath(_name); |
| 458 if (result == null) { | 513 if (result == null) { |
| 459 throw new FileIOException("fullPath failed"); | 514 throw new FileIOException("fullPath failed"); |
| 460 } | 515 } |
| 461 return result; | 516 return result; |
| 462 } | 517 } |
| 463 | 518 |
| 464 void openInputStream() { | 519 void openInputStream() { |
|
Søren Gjesse
2012/02/28 07:40:25
So you kept the Sync/non Sync versions for now?
Mads Ager (google)
2012/02/28 08:21:00
Yes, I will do a follow-up change today to get rid
| |
| 465 _asyncUsed = true; | 520 _asyncUsed = true; |
| 466 // Create a new file object to handle the opening of the file for | 521 // Create a new file object to handle the opening of the file for |
| 467 // creating an input stream. Currently the file input stream uses | 522 // creating an input stream. Currently the file input stream uses |
| 468 // synchronous calls on the opened file so we need to open it | 523 // synchronous calls on the opened file so we need to open it |
| 469 // synchronously. | 524 // synchronously. |
| 470 File file = new File(this._name); | 525 new Timer((t) { |
| 471 file.errorHandler = (String error) { | 526 if (_inputStreamHandler != null) { |
| 472 if (_errorHandler != null) _errorHandler(error); | 527 _inputStreamHandler(new _FileInputStream(_name)); |
| 473 }; | 528 } |
| 474 RandomAccessFile openedFile = file.openSync(); | 529 }, 0); |
| 475 InputStream stream = | |
| 476 new _FileInputStream(openedFile, openedFile.lengthSync()); | |
| 477 new Timer( | |
| 478 (Timer ignore) { | |
| 479 if (_inputStreamHandler != null) _inputStreamHandler(stream); | |
| 480 }, 0); | |
| 481 } | 530 } |
| 482 | 531 |
| 483 InputStream openInputStreamSync() { | 532 InputStream openInputStreamSync() { |
| 484 if (_asyncUsed) { | 533 return new _FileInputStream(_name); |
| 485 throw new FileIOException( | |
| 486 "Mixed use of synchronous and asynchronous API"); | |
| 487 } | |
| 488 RandomAccessFile openedFile = openSync(); | |
| 489 return new _FileInputStream(openedFile, openedFile.lengthSync()); | |
| 490 } | 534 } |
| 491 | 535 |
| 492 void openOutputStream([FileMode mode = FileMode.WRITE]) { | 536 void openOutputStream([FileMode mode = FileMode.WRITE]) { |
| 493 _asyncUsed = true; | 537 _asyncUsed = true; |
| 494 if (mode != FileMode.WRITE && | 538 if (mode != FileMode.WRITE && |
| 495 mode != FileMode.APPEND) { | 539 mode != FileMode.APPEND) { |
| 496 throw new FileIOException( | 540 throw new FileIOException( |
| 497 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); | 541 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); |
| 498 } | 542 } |
| 499 // Create a new file object to handle the opening of the file for | 543 OutputStream stream = new _FileOutputStream(_name, mode); |
| 500 // creating an input stream. Currently the file input stream uses | |
| 501 // synchronous calls on the opened file so we need to open it | |
| 502 // synchronously. | |
| 503 File file = new File(this._name); | |
| 504 file.errorHandler = (String error) { | |
| 505 if (_errorHandler != null) _errorHandler(error); | |
| 506 }; | |
| 507 RandomAccessFile openedFile = file.openSync(mode); | |
| 508 OutputStream stream = new _FileOutputStream(openedFile); | |
| 509 new Timer( | 544 new Timer( |
| 510 (Timer ignore) { | 545 (Timer ignore) { |
| 511 if (_outputStreamHandler != null) _outputStreamHandler(stream); | 546 if (_outputStreamHandler != null) _outputStreamHandler(stream); |
| 512 }, 0); | 547 }, 0); |
| 513 } | 548 } |
| 514 | 549 |
| 515 OutputStream openOutputStreamSync([FileMode mode = FileMode.WRITE]) { | 550 OutputStream openOutputStreamSync([FileMode mode = FileMode.WRITE]) { |
| 516 if (_asyncUsed) { | 551 if (_asyncUsed) { |
| 517 throw new FileIOException( | 552 throw new FileIOException( |
| 518 "Mixed use of synchronous and asynchronous API"); | 553 "Mixed use of synchronous and asynchronous API"); |
| 519 } | 554 } |
| 520 if (mode != FileMode.WRITE && | 555 if (mode != FileMode.WRITE && |
| 521 mode != FileMode.APPEND) { | 556 mode != FileMode.APPEND) { |
| 522 throw new FileIOException( | 557 throw new FileIOException( |
| 523 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); | 558 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); |
| 524 } | 559 } |
| 525 RandomAccessFile openedFile = openSync(mode); | 560 return new _FileOutputStream(_name, mode); |
| 526 return new _FileOutputStream(openedFile); | |
| 527 } | 561 } |
| 528 | 562 |
| 529 void readAsBytes() { | 563 void readAsBytes() { |
| 530 _asyncUsed = true; | 564 _asyncUsed = true; |
| 531 var chunks = new _BufferList(); | 565 var chunks = new _BufferList(); |
| 532 openInputStream(); | 566 var stream = openInputStreamSync(); |
| 533 inputStreamHandler = (inputStream) { | 567 stream.closeHandler = () { |
| 534 inputStream.closeHandler = () { | 568 if (_readAsBytesHandler != null) { |
| 535 if (_readAsBytesHandler != null) { | 569 _readAsBytesHandler(chunks.readBytes(chunks.length)); |
| 536 _readAsBytesHandler(chunks.readBytes(chunks.length)); | 570 } |
| 537 } | 571 }; |
| 538 }; | 572 stream.dataHandler = () { |
| 539 inputStream.dataHandler = () { | 573 var chunk = stream.read(); |
| 540 var chunk = inputStream.read(); | 574 chunks.add(chunk); |
| 541 chunks.add(chunk); | 575 }; |
| 542 }; | 576 stream.errorHandler = () { |
| 543 inputStream.errorHandler = () { | 577 if (_errorHandler != null) { |
| 544 if (_errorHandler != null) { | 578 _errorHandler("Failed to read file as bytes: $_name"); |
| 545 _errorHandler("Failed to read file as bytes: $_name"); | 579 } |
| 546 } | |
| 547 }; | |
| 548 }; | 580 }; |
| 549 } | 581 } |
| 550 | 582 |
| 551 List<int> readAsBytesSync() { | 583 List<int> readAsBytesSync() { |
| 552 if (_asyncUsed) { | 584 if (_asyncUsed) { |
| 553 throw new FileIOException( | 585 throw new FileIOException( |
| 554 "Mixed use of synchronous and asynchronous API"); | 586 "Mixed use of synchronous and asynchronous API"); |
| 555 } | 587 } |
| 556 var opened = openSync(); | 588 var opened = openSync(); |
| 557 var length = opened.lengthSync(); | 589 var length = opened.lengthSync(); |
| 558 var result = new ByteArray(length); | 590 var result = new ByteArray(length); |
| 559 var read = opened.readListSync(result, 0, length); | 591 var read = opened.readListSync(result, 0, length); |
| 560 if (read != length) { | 592 if (read != length) { |
| 561 throw new FileIOException("Failed reading file as bytes: $_name"); | 593 throw new FileIOException("Failed reading file as bytes: $_name"); |
| 562 } | 594 } |
| 595 opened.close(); | |
| 563 return result; | 596 return result; |
| 564 } | 597 } |
| 565 | 598 |
| 566 _StringDecoder _getDecoder(encoding) { | 599 _StringDecoder _getDecoder(encoding) { |
| 567 if (encoding == "UTF-8") { | 600 if (encoding == "UTF-8") { |
| 568 return new _UTF8Decoder(); | 601 return new _UTF8Decoder(); |
| 569 } else if (encoding == "ISO-8859-1") { | 602 } else if (encoding == "ISO-8859-1") { |
| 570 return new _Latin1Decoder(); | 603 return new _Latin1Decoder(); |
| 571 } else if (encoding == "ASCII") { | 604 } else if (encoding == "ASCII") { |
| 572 return new _AsciiDecoder(); | 605 return new _AsciiDecoder(); |
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1099 void set readByteHandler(void handler(int byte)) { | 1132 void set readByteHandler(void handler(int byte)) { |
| 1100 _readByteHandler = handler; | 1133 _readByteHandler = handler; |
| 1101 } | 1134 } |
| 1102 | 1135 |
| 1103 void set readListHandler(void handler(int read)) { | 1136 void set readListHandler(void handler(int read)) { |
| 1104 _readListHandler = handler; | 1137 _readListHandler = handler; |
| 1105 } | 1138 } |
| 1106 | 1139 |
| 1107 void set noPendingWriteHandler(void handler()) { | 1140 void set noPendingWriteHandler(void handler()) { |
| 1108 _noPendingWriteHandler = handler; | 1141 _noPendingWriteHandler = handler; |
| 1142 if (_pendingWrites == 0) { | |
| 1143 _noPendingWriteTimer = new Timer((t) { | |
| 1144 if (_noPendingWriteHandler != null) _noPendingWriteHandler(); | |
| 1145 }, 0); | |
| 1146 } | |
| 1109 } | 1147 } |
| 1110 | 1148 |
| 1111 void set positionHandler(void handler(int pos)) { | 1149 void set positionHandler(void handler(int pos)) { |
| 1112 _positionHandler = handler; | 1150 _positionHandler = handler; |
| 1113 } | 1151 } |
| 1114 | 1152 |
| 1115 void set setPositionHandler(void handler()) { | 1153 void set setPositionHandler(void handler()) { |
| 1116 _setPositionHandler = handler; | 1154 _setPositionHandler = handler; |
| 1117 } | 1155 } |
| 1118 | 1156 |
| 1119 void set truncateHandler(void handler()) { | 1157 void set truncateHandler(void handler()) { |
| 1120 _truncateHandler = handler; | 1158 _truncateHandler = handler; |
| 1121 } | 1159 } |
| 1122 | 1160 |
| 1123 void set lengthHandler(void handler(int length)) { | 1161 void set lengthHandler(void handler(int length)) { |
| 1124 _lengthHandler = handler; | 1162 _lengthHandler = handler; |
| 1125 } | 1163 } |
| 1126 | 1164 |
| 1127 void set flushHandler(void handler()) { | 1165 void set flushHandler(void handler()) { |
| 1128 _flushHandler = handler; | 1166 _flushHandler = handler; |
| 1129 } | 1167 } |
| 1130 | 1168 |
| 1131 void _ensureFileService() { | 1169 void _ensureFileService() { |
| 1132 if (_fileService == null) { | 1170 if (_fileService == null) { |
| 1133 _fileService = _FileUtils.newServicePort(); | 1171 _fileService = _FileUtils.newServicePort(); |
| 1134 } | 1172 } |
| 1135 } | 1173 } |
| 1136 | 1174 |
| 1137 void _writeEnqueued() => _pendingWrites++; | 1175 void _writeEnqueued() { |
| 1176 _pendingWrites++; | |
| 1177 if (_noPendingWriteTimer != null) { | |
| 1178 _noPendingWriteTimer.cancel(); | |
| 1179 _noPendingWriteTimer = null; | |
| 1180 } | |
| 1181 } | |
| 1138 | 1182 |
| 1139 void _writeCompleted() { | 1183 void _writeCompleted() { |
| 1140 _pendingWrites--; | 1184 _pendingWrites--; |
| 1141 if (_pendingWrites == 0 && _noPendingWriteHandler != null) { | 1185 if (_pendingWrites == 0 && _noPendingWriteHandler != null) { |
| 1142 _noPendingWriteHandler(); | 1186 _noPendingWriteHandler(); |
| 1143 } | 1187 } |
| 1144 } | 1188 } |
| 1145 | 1189 |
| 1146 | 1190 |
| 1147 String _name; | 1191 String _name; |
| 1148 int _id; | 1192 int _id; |
| 1149 bool _asyncUsed; | 1193 bool _asyncUsed; |
| 1150 int _pendingWrites = 0; | 1194 int _pendingWrites = 0; |
| 1151 | 1195 |
| 1152 SendPort _fileService; | 1196 SendPort _fileService; |
| 1153 | 1197 |
| 1198 Timer _noPendingWriteTimer; | |
| 1199 | |
| 1154 Function _closeHandler; | 1200 Function _closeHandler; |
| 1155 Function _readByteHandler; | 1201 Function _readByteHandler; |
| 1156 Function _readListHandler; | 1202 Function _readListHandler; |
| 1157 Function _noPendingWriteHandler; | 1203 Function _noPendingWriteHandler; |
| 1158 Function _positionHandler; | 1204 Function _positionHandler; |
| 1159 Function _setPositionHandler; | 1205 Function _setPositionHandler; |
| 1160 Function _truncateHandler; | 1206 Function _truncateHandler; |
| 1161 Function _lengthHandler; | 1207 Function _lengthHandler; |
| 1162 Function _flushHandler; | 1208 Function _flushHandler; |
| 1163 Function _errorHandler; | 1209 Function _errorHandler; |
| 1164 } | 1210 } |
| OLD | NEW |