| 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(File file) { | 6 _FileInputStream(RandomAccessFile this._file, int this._length) { |
| 7 _file = file.openSync(); | |
| 8 _length = _file.lengthSync(); | |
| 9 _streamMarkedClosed = true; | 7 _streamMarkedClosed = true; |
| 10 _checkScheduleCallbacks(); | 8 _checkScheduleCallbacks(); |
| 11 } | 9 } |
| 12 | 10 |
| 13 _FileInputStream.fromStdio(int fd) { | 11 _FileInputStream.fromStdio(int fd) { |
| 14 assert(fd == 0); | 12 assert(fd == 0); |
| 15 _file = _File._openStdioSync(fd); | 13 _file = _File._openStdioSync(fd); |
| 16 _length = _file.lengthSync(); | 14 _length = _file.lengthSync(); |
| 17 _streamMarkedClosed = true; | 15 _streamMarkedClosed = true; |
| 18 _checkScheduleCallbacks(); | 16 _checkScheduleCallbacks(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 _closed = true; | 48 _closed = true; |
| 51 } | 49 } |
| 52 | 50 |
| 53 RandomAccessFile _file; | 51 RandomAccessFile _file; |
| 54 int _length; | 52 int _length; |
| 55 bool _closed = false; | 53 bool _closed = false; |
| 56 } | 54 } |
| 57 | 55 |
| 58 | 56 |
| 59 class _FileOutputStream implements OutputStream { | 57 class _FileOutputStream implements OutputStream { |
| 60 _FileOutputStream(File file, FileMode mode) { | 58 _FileOutputStream(this._file); |
| 61 _file = file.openSync(mode); | |
| 62 } | |
| 63 | 59 |
| 64 _FileOutputStream.fromStdio(int fd) { | 60 _FileOutputStream.fromStdio(int fd) { |
| 65 assert(1 <= fd && fd <= 2); | 61 assert(1 <= fd && fd <= 2); |
| 66 _file = _File._openStdioSync(fd); | 62 _file = _File._openStdioSync(fd); |
| 67 } | 63 } |
| 68 | 64 |
| 69 bool write(List<int> buffer, [bool copyBuffer = false]) { | 65 bool write(List<int> buffer, [bool copyBuffer = false]) { |
| 70 return _write(buffer, 0, buffer.length); | 66 bool result = _write(buffer, 0, buffer.length); |
| 67 if (result) { |
| 68 _checkScheduleCallbacks(); |
| 69 } |
| 70 return result; |
| 71 } | 71 } |
| 72 | 72 |
| 73 bool writeFrom(List<int> buffer, [int offset = 0, int len]) { | 73 bool writeFrom(List<int> buffer, [int offset = 0, int len]) { |
| 74 return _write( | 74 bool result = _write( |
| 75 buffer, offset, (len == null) ? buffer.length - offset : len); | 75 buffer, offset, (len == null) ? buffer.length - offset : len); |
| 76 if (result) { |
| 77 _checkScheduleCallbacks(); |
| 78 } |
| 79 return result; |
| 76 } | 80 } |
| 77 | 81 |
| 78 void close() { | 82 void close() { |
| 79 _file.closeSync(); | 83 if (_scheduledNoPendingWriteCallback != null) { |
| 84 _scheduledNoPendingWriteCallback.cancel(); |
| 85 } |
| 86 if (!_streamMarkedClosed) { |
| 87 _file.closeSync(); |
| 88 _streamMarkedClosed = true; |
| 89 _checkScheduleCallbacks(); |
| 90 } |
| 80 } | 91 } |
| 81 | 92 |
| 82 void set noPendingWriteHandler(void callback()) { | 93 void set noPendingWriteHandler(void callback()) { |
| 83 // TODO(sgjesse): How to handle this? | 94 _noPendingWriteHandler = callback; |
| 95 _checkScheduleCallbacks(); |
| 84 } | 96 } |
| 85 | 97 |
| 86 void set closeHandler(void callback()) { | 98 void set closeHandler(void callback()) { |
| 87 // TODO(sgjesse): How to handle this? | 99 _closeHandler = callback; |
| 100 _checkScheduleCallbacks(); |
| 88 } | 101 } |
| 89 | 102 |
| 90 void set errorHandler(void callback()) { | 103 void set errorHandler(void callback()) { |
| 91 // TODO(sgjesse): How to handle this? | 104 // TODO(sgjesse): How to handle this? |
| 92 } | 105 } |
| 93 | 106 |
| 94 bool _write(List<int> buffer, int offset, int len) { | 107 bool _write(List<int> buffer, int offset, int len) { |
| 95 int bytesWritten = _file.writeListSync(buffer, offset, len); | 108 int bytesWritten = _file.writeListSync(buffer, offset, len); |
| 96 if (bytesWritten == len) { | 109 if (bytesWritten == len) { |
| 97 return true; | 110 return true; |
| 98 } else { | 111 } else { |
| 99 throw "FileOutputStream: write error"; | 112 throw "FileOutputStream: write error"; |
| 100 } | 113 } |
| 101 } | 114 } |
| 102 | 115 |
| 116 void _checkScheduleCallbacks() { |
| 117 void issueNoPendingWriteCallback(Timer timer) { |
| 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 } |
| 141 |
| 103 RandomAccessFile _file; | 142 RandomAccessFile _file; |
| 143 |
| 144 // When this is set to true the stream is marked closed. When a |
| 145 // stream is marked closed no more data can be written. |
| 146 bool _streamMarkedClosed = false; |
| 147 |
| 148 // When this is set to true the close callback has been called and |
| 149 // the stream is fully closed. |
| 150 bool _closeCallbackCalled = false; |
| 151 |
| 152 Timer _scheduledNoPendingWriteCallback; |
| 153 Timer _scheduledCloseCallback; |
| 154 Function _noPendingWriteHandler; |
| 155 Function _closeHandler; |
| 104 } | 156 } |
| 105 | 157 |
| 106 | 158 |
| 107 class _FileOperation { | 159 class _FileOperation { |
| 108 abstract void execute(ReceivePort port); | 160 abstract void execute(ReceivePort port); |
| 109 | 161 |
| 110 void set replyPort(SendPort port) { | 162 void set replyPort(SendPort port) { |
| 111 _replyPort = port; | 163 _replyPort = port; |
| 112 } | 164 } |
| 113 | 165 |
| (...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 throw new FileIOException( | 712 throw new FileIOException( |
| 661 "Mixed use of synchronous and asynchronous API"); | 713 "Mixed use of synchronous and asynchronous API"); |
| 662 } | 714 } |
| 663 String result = _FileUtils.checkedFullPath(_name); | 715 String result = _FileUtils.checkedFullPath(_name); |
| 664 if (result == null) { | 716 if (result == null) { |
| 665 throw new FileIOException("fullPath failed"); | 717 throw new FileIOException("fullPath failed"); |
| 666 } | 718 } |
| 667 return result; | 719 return result; |
| 668 } | 720 } |
| 669 | 721 |
| 670 InputStream openInputStream() => new _FileInputStream(this); | 722 void openInputStream() { |
| 723 // Create a new file object to handle the opening of the file for |
| 724 // creating an input stream. Currently the file input stream uses |
| 725 // synchronous calls on the opened file so we need to open it |
| 726 // synchronously. |
| 727 File file = new File(this._name); |
| 728 file.errorHandler = (String error) { |
| 729 if (_errorHandler != null) _errorHandler(error); |
| 730 }; |
| 731 RandomAccessFile openedFile = file.openSync(); |
| 732 InputStream stream = |
| 733 new _FileInputStream(openedFile, openedFile.lengthSync()); |
| 734 new Timer( |
| 735 (Timer ignore) { |
| 736 if (_inputStreamHandler != null) _inputStreamHandler(stream); |
| 737 }, 0); |
| 738 } |
| 671 | 739 |
| 672 OutputStream openOutputStream([FileMode mode = FileMode.WRITE]) { | 740 InputStream openInputStreamSync() { |
| 741 if (_asyncUsed) { |
| 742 throw new FileIOException( |
| 743 "Mixed use of synchronous and asynchronous API"); |
| 744 } |
| 745 RandomAccessFile openedFile = openSync(); |
| 746 return new _FileInputStream(openedFile, openedFile.lengthSync()); |
| 747 } |
| 748 |
| 749 void openOutputStream([FileMode mode = FileMode.WRITE]) { |
| 673 if (mode != FileMode.WRITE && | 750 if (mode != FileMode.WRITE && |
| 674 mode != FileMode.APPEND) { | 751 mode != FileMode.APPEND) { |
| 675 throw new FileIOException( | 752 throw new FileIOException( |
| 676 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); | 753 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); |
| 677 } | 754 } |
| 678 return new _FileOutputStream(this, mode); | 755 // Create a new file object to handle the opening of the file for |
| 756 // creating an input stream. Currently the file input stream uses |
| 757 // synchronous calls on the opened file so we need to open it |
| 758 // synchronously. |
| 759 File file = new File(this._name); |
| 760 file.errorHandler = (String error) { |
| 761 if (_errorHandler != null) _errorHandler(error); |
| 762 }; |
| 763 RandomAccessFile openedFile = file.openSync(mode); |
| 764 OutputStream stream = new _FileOutputStream(openedFile); |
| 765 new Timer( |
| 766 (Timer ignore) { |
| 767 if (_outputStreamHandler != null) _outputStreamHandler(stream); |
| 768 }, 0); |
| 769 } |
| 770 |
| 771 OutputStream openOutputStreamSync([FileMode mode = FileMode.WRITE]) { |
| 772 if (_asyncUsed) { |
| 773 throw new FileIOException( |
| 774 "Mixed use of synchronous and asynchronous API"); |
| 775 } |
| 776 if (mode != FileMode.WRITE && |
| 777 mode != FileMode.APPEND) { |
| 778 throw new FileIOException( |
| 779 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); |
| 780 } |
| 781 RandomAccessFile openedFile = openSync(mode); |
| 782 return new _FileOutputStream(openedFile); |
| 679 } | 783 } |
| 680 | 784 |
| 681 String get name() => _name; | 785 String get name() => _name; |
| 682 | 786 |
| 683 void set existsHandler(void handler(bool exists)) { | 787 void set existsHandler(void handler(bool exists)) { |
| 684 _existsHandler = handler; | 788 _existsHandler = handler; |
| 685 } | 789 } |
| 686 | 790 |
| 687 void set createHandler(void handler()) { | 791 void set createHandler(void handler()) { |
| 688 _createHandler = handler; | 792 _createHandler = handler; |
| 689 } | 793 } |
| 690 | 794 |
| 691 void set deleteHandler(void handler()) { | 795 void set deleteHandler(void handler()) { |
| 692 _deleteHandler = handler; | 796 _deleteHandler = handler; |
| 693 } | 797 } |
| 694 | 798 |
| 695 void set openHandler(void handler(RandomAccessFile file)) { | 799 void set openHandler(void handler(RandomAccessFile file)) { |
| 696 _openHandler = handler; | 800 _openHandler = handler; |
| 697 } | 801 } |
| 698 | 802 |
| 803 void set inputStreamHandler(void handler(InputStream stream)) { |
| 804 _inputStreamHandler = handler; |
| 805 } |
| 806 |
| 807 void set outputStreamHandler(void handler(OutputStream stream)) { |
| 808 _outputStreamHandler = handler; |
| 809 } |
| 810 |
| 699 void set fullPathHandler(void handler(String)) { | 811 void set fullPathHandler(void handler(String)) { |
| 700 _fullPathHandler = handler; | 812 _fullPathHandler = handler; |
| 701 } | 813 } |
| 702 | 814 |
| 703 void set errorHandler(void handler(String error)) { | 815 void set errorHandler(void handler(String error)) { |
| 704 _errorHandler = handler; | 816 _errorHandler = handler; |
| 705 } | 817 } |
| 706 | 818 |
| 707 String _name; | 819 String _name; |
| 708 bool _asyncUsed; | 820 bool _asyncUsed; |
| 709 | 821 |
| 710 _FileOperationScheduler _scheduler; | 822 _FileOperationScheduler _scheduler; |
| 711 | 823 |
| 712 var _existsHandler; | 824 Function _existsHandler; |
| 713 var _createHandler; | 825 Function _createHandler; |
| 714 var _deleteHandler; | 826 Function _deleteHandler; |
| 715 var _openHandler; | 827 Function _openHandler; |
| 716 var _fullPathHandler; | 828 Function _inputStreamHandler; |
| 717 var _errorHandler; | 829 Function _outputStreamHandler; |
| 830 Function _fullPathHandler; |
| 831 Function _errorHandler; |
| 718 } | 832 } |
| 719 | 833 |
| 720 | 834 |
| 721 class _RandomAccessFile implements RandomAccessFile { | 835 class _RandomAccessFile implements RandomAccessFile { |
| 722 _RandomAccessFile(int this._id, String this._name) | 836 _RandomAccessFile(int this._id, String this._name) |
| 723 : _scheduler = new _FileOperationScheduler(), | 837 : _scheduler = new _FileOperationScheduler(), |
| 724 _asyncUsed = false; | 838 _asyncUsed = false; |
| 725 | 839 |
| 726 void close() { | 840 void close() { |
| 727 _asyncUsed = true; | 841 _asyncUsed = true; |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1108 void set flushHandler(void handler()) { | 1222 void set flushHandler(void handler()) { |
| 1109 _flushHandler = handler; | 1223 _flushHandler = handler; |
| 1110 } | 1224 } |
| 1111 | 1225 |
| 1112 String _name; | 1226 String _name; |
| 1113 int _id; | 1227 int _id; |
| 1114 bool _asyncUsed; | 1228 bool _asyncUsed; |
| 1115 | 1229 |
| 1116 _FileOperationScheduler _scheduler; | 1230 _FileOperationScheduler _scheduler; |
| 1117 | 1231 |
| 1118 var _closeHandler; | 1232 Function _closeHandler; |
| 1119 var _readByteHandler; | 1233 Function _readByteHandler; |
| 1120 var _readListHandler; | 1234 Function _readListHandler; |
| 1121 var _noPendingWriteHandler; | 1235 Function _noPendingWriteHandler; |
| 1122 var _positionHandler; | 1236 Function _positionHandler; |
| 1123 var _setPositionHandler; | 1237 Function _setPositionHandler; |
| 1124 var _truncateHandler; | 1238 Function _truncateHandler; |
| 1125 var _lengthHandler; | 1239 Function _lengthHandler; |
| 1126 var _flushHandler; | 1240 Function _flushHandler; |
| 1127 var _errorHandler; | 1241 Function _errorHandler; |
| 1128 } | 1242 } |
| OLD | NEW |