| 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(String name) { | 6 _FileInputStream(String name) |
| 7 : _data = [], |
| 8 _position = 0, |
| 9 _filePosition = 0 { |
| 7 var file = new File(name); | 10 var file = new File(name); |
| 8 _data = []; | 11 var future = file.open(FileMode.READ); |
| 9 _position = 0; | 12 future.handleException((e) { |
| 10 var chained = file.open(FileMode.READ).chain((openedFile) { | 13 _reportError(e); |
| 11 return _readDataFromFile(openedFile); | 14 return true; |
| 12 }); | 15 }); |
| 13 chained.handleException((e) { | 16 future.then(_setupOpenedFile); |
| 17 } |
| 18 |
| 19 _FileInputStream.fromStdio(int fd) |
| 20 : _data = [], |
| 21 _position = 0, |
| 22 _filePosition = 0 { |
| 23 assert(fd == 0); |
| 24 _setupOpenedFile(_File._openStdioSync(fd)); |
| 25 } |
| 26 |
| 27 void _setupOpenedFile(RandomAccessFile openedFile) { |
| 28 _openedFile = openedFile; |
| 29 if (_streamMarkedClosed) { |
| 30 // This input stream has already been closed. |
| 31 _fileLength = 0; |
| 32 _closeFile(); |
| 33 return; |
| 34 } |
| 35 var futureOpen = _openedFile.length(); |
| 36 futureOpen.then((len) { |
| 37 _fileLength = len; |
| 38 _fillBuffer(); |
| 39 }); |
| 40 futureOpen.handleException((e) { |
| 14 _reportError(e); | 41 _reportError(e); |
| 15 return true; | 42 return true; |
| 16 }); | 43 }); |
| 17 } | 44 } |
| 18 | 45 |
| 19 _FileInputStream.fromStdio(int fd) { | 46 void _closeFile() { |
| 20 assert(fd == 0); | 47 if (_openedFile == null) { |
| 21 var file = _File._openStdioSync(fd); | 48 _streamMarkedClosed = true; |
| 22 _data = []; | 49 return; |
| 23 _position = 0; | 50 } |
| 24 _readDataFromFile(file).handleException((e) { | 51 if (available() == 0) _cancelScheduledDataCallback(); |
| 25 _reportError(e); | 52 if (!_openedFile.closed) { |
| 26 return true; | 53 _openedFile.close().then((ignore) { |
| 27 }); | 54 _streamMarkedClosed = true; |
| 55 _checkScheduleCallbacks(); |
| 56 }); |
| 57 } |
| 28 } | 58 } |
| 29 | 59 |
| 30 Future<RandomAccessFile> _closeAfterRead(RandomAccessFile openedFile) { | 60 void _fillBuffer() { |
| 31 return openedFile.close().transform((ignore) { | 61 Expect.equals(_position, _data.length); |
| 32 _streamMarkedClosed = true; | 62 if (_openedFile == null) return; // Called before the file is opened. |
| 63 int size = Math.min(_bufferLength, _fileLength - _filePosition); |
| 64 if (size == 0) { |
| 65 _closeFile(); |
| 66 return; |
| 67 } |
| 68 if (_data.length != size) { |
| 69 _data = new Uint8List(size); |
| 70 } |
| 71 var future = _openedFile.readList(_data, 0, _data.length); |
| 72 future.then((read) { |
| 73 _filePosition += read; |
| 74 if (read != _data.length) { |
| 75 _data.removeRange(read, _data.length - read); |
| 76 } |
| 77 _position = 0; |
| 78 |
| 79 if (_fileLength == _filePosition) { |
| 80 _closeFile(); |
| 81 } |
| 33 _checkScheduleCallbacks(); | 82 _checkScheduleCallbacks(); |
| 34 return openedFile; | |
| 35 }); | |
| 36 } | |
| 37 | |
| 38 Future<RandomAccessFile> _readDataFromFile(RandomAccessFile openedFile) { | |
| 39 return openedFile.length().chain((length) { | |
| 40 var contents = new Uint8List(length); | |
| 41 if (length != 0) { | |
| 42 return openedFile.readList(contents, 0, length).chain((read) { | |
| 43 if (read != length) { | |
| 44 throw new FileIOException( | |
| 45 'Failed reading file contents in FileInputStream'); | |
| 46 } else { | |
| 47 _data = contents; | |
| 48 } | |
| 49 return _closeAfterRead(openedFile); | |
| 50 }); | |
| 51 } else { | |
| 52 return _closeAfterRead(openedFile); | |
| 53 } | |
| 54 }); | 83 }); |
| 55 } | 84 } |
| 56 | 85 |
| 57 int available() { | 86 int available() { |
| 58 return _closed ? 0 : _data.length - _position; | 87 return closed ? 0 : _data.length - _position; |
| 59 } | 88 } |
| 60 | 89 |
| 61 void pipe(OutputStream output, [bool close = true]) { | 90 void pipe(OutputStream output, [bool close = true]) { |
| 62 _pipe(this, output, close: close); | 91 _pipe(this, output, close: close); |
| 63 } | 92 } |
| 64 | 93 |
| 94 void _finishRead() { |
| 95 if (_position == _data.length && !_streamMarkedClosed) { |
| 96 _fillBuffer(); |
| 97 } else { |
| 98 _checkScheduleCallbacks(); |
| 99 } |
| 100 } |
| 101 |
| 65 List<int> _read(int bytesToRead) { | 102 List<int> _read(int bytesToRead) { |
| 66 List<int> result = new Uint8List(bytesToRead); | 103 List<int> result; |
| 67 result.setRange(0, bytesToRead, _data, _position); | 104 if (_position == 0 && bytesToRead == _data.length) { |
| 68 _position += bytesToRead; | 105 result = _data; |
| 69 _checkScheduleCallbacks(); | 106 _data = []; |
| 107 } else { |
| 108 result = new Uint8List(bytesToRead); |
| 109 result.setRange(0, bytesToRead, _data, _position); |
| 110 _position += bytesToRead; |
| 111 } |
| 112 _finishRead(); |
| 70 return result; | 113 return result; |
| 71 } | 114 } |
| 72 | 115 |
| 73 int _readInto(List<int> buffer, int offset, int len) { | 116 int _readInto(List<int> buffer, int offset, int len) { |
| 74 buffer.setRange(offset, len, _data, _position); | 117 buffer.setRange(offset, len, _data, _position); |
| 75 _position += len; | 118 _position += len; |
| 76 _checkScheduleCallbacks(); | 119 _finishRead(); |
| 77 return len; | 120 return len; |
| 78 } | 121 } |
| 79 | 122 |
| 80 void _close() { | 123 void _close() { |
| 81 if (_closed) return; | 124 _data = []; |
| 82 _closed = true; | 125 _position = 0; |
| 126 _filePosition = 0; |
| 127 _fileLength = 0; |
| 128 _closeFile(); |
| 83 } | 129 } |
| 84 | 130 |
| 131 static final int _bufferLength = 64 * 1024; |
| 132 |
| 133 RandomAccessFile _openedFile; |
| 85 List<int> _data; | 134 List<int> _data; |
| 86 int _position; | 135 int _position; |
| 87 bool _closed = false; | 136 int _filePosition; |
| 137 int _fileLength; |
| 88 } | 138 } |
| 89 | 139 |
| 90 | 140 |
| 91 class _PendingOperation { | 141 class _PendingOperation { |
| 92 const _PendingOperation(this._id); | 142 const _PendingOperation(this._id); |
| 93 static final _PendingOperation CLOSE = const _PendingOperation(0); | 143 static final _PendingOperation CLOSE = const _PendingOperation(0); |
| 94 static final _PendingOperation FLUSH = const _PendingOperation(1); | 144 static final _PendingOperation FLUSH = const _PendingOperation(1); |
| 95 final int _id; | 145 final int _id; |
| 96 } | 146 } |
| 97 | 147 |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 | 755 |
| 706 SendPort _fileService; | 756 SendPort _fileService; |
| 707 } | 757 } |
| 708 | 758 |
| 709 | 759 |
| 710 class _RandomAccessFile extends _FileBase implements RandomAccessFile { | 760 class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
| 711 _RandomAccessFile(int this._id, String this._name); | 761 _RandomAccessFile(int this._id, String this._name); |
| 712 | 762 |
| 713 Future<RandomAccessFile> close() { | 763 Future<RandomAccessFile> close() { |
| 714 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 764 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
| 715 if (_isClosed) return _completeWithClosedException(completer); | 765 if (closed) return _completeWithClosedException(completer); |
| 716 _ensureFileService(); | 766 _ensureFileService(); |
| 717 List request = new List(2); | 767 List request = new List(2); |
| 718 request[0] = _FileUtils.CLOSE_REQUEST; | 768 request[0] = _FileUtils.CLOSE_REQUEST; |
| 719 request[1] = _id; | 769 request[1] = _id; |
| 720 // Set the id_ to 0 (NULL) to ensure the no more async requests | 770 // Set the id_ to 0 (NULL) to ensure the no more async requests |
| 721 // can be issues for this file. | 771 // can be issued for this file. |
| 722 _id = 0; | 772 _id = 0; |
| 723 return _fileService.call(request).transform((result) { | 773 return _fileService.call(request).transform((result) { |
| 724 if (result != -1) { | 774 if (result != -1) { |
| 725 _id = result; | 775 _id = result; |
| 726 return this; | 776 return this; |
| 727 } else { | 777 } else { |
| 728 throw new FileIOException("Cannot close file '$_name'"); | 778 throw new FileIOException("Cannot close file '$_name'"); |
| 729 } | 779 } |
| 730 }); | 780 }); |
| 731 } | 781 } |
| 732 | 782 |
| 733 void closeSync() { | 783 void closeSync() { |
| 734 _checkNotClosed(); | 784 _checkNotClosed(); |
| 735 var id = _FileUtils.close(_id); | 785 var id = _FileUtils.close(_id); |
| 736 if (id == -1) { | 786 if (id == -1) { |
| 737 throw new FileIOException("Cannot close file '$_name'"); | 787 throw new FileIOException("Cannot close file '$_name'"); |
| 738 } | 788 } |
| 739 _id = id; | 789 _id = id; |
| 740 } | 790 } |
| 741 | 791 |
| 742 Future<int> readByte() { | 792 Future<int> readByte() { |
| 743 _ensureFileService(); | 793 _ensureFileService(); |
| 744 Completer<int> completer = new Completer<int>(); | 794 Completer<int> completer = new Completer<int>(); |
| 745 if (_isClosed) return _completeWithClosedException(completer); | 795 if (closed) return _completeWithClosedException(completer); |
| 746 List request = new List(2); | 796 List request = new List(2); |
| 747 request[0] = _FileUtils.READ_BYTE_REQUEST; | 797 request[0] = _FileUtils.READ_BYTE_REQUEST; |
| 748 request[1] = _id; | 798 request[1] = _id; |
| 749 return _fileService.call(request).transform((response) { | 799 return _fileService.call(request).transform((response) { |
| 750 if (_isErrorResponse(response)) { | 800 if (_isErrorResponse(response)) { |
| 751 throw _exceptionFromResponse(response, | 801 throw _exceptionFromResponse(response, |
| 752 "readByte failed for file '$_name'"); | 802 "readByte failed for file '$_name'"); |
| 753 } | 803 } |
| 754 return response; | 804 return response; |
| 755 }); | 805 }); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 770 if (buffer is !List || offset is !int || bytes is !int) { | 820 if (buffer is !List || offset is !int || bytes is !int) { |
| 771 // Complete asynchronously so the user has a chance to setup | 821 // Complete asynchronously so the user has a chance to setup |
| 772 // handlers without getting exceptions when registering the | 822 // handlers without getting exceptions when registering the |
| 773 // then handler. | 823 // then handler. |
| 774 new Timer(0, (t) { | 824 new Timer(0, (t) { |
| 775 completer.completeException(new FileIOException( | 825 completer.completeException(new FileIOException( |
| 776 "Invalid arguments to readList for file '$_name'")); | 826 "Invalid arguments to readList for file '$_name'")); |
| 777 }); | 827 }); |
| 778 return completer.future; | 828 return completer.future; |
| 779 }; | 829 }; |
| 780 if (_isClosed) return _completeWithClosedException(completer); | 830 if (closed) return _completeWithClosedException(completer); |
| 781 List request = new List(3); | 831 List request = new List(3); |
| 782 request[0] = _FileUtils.READ_LIST_REQUEST; | 832 request[0] = _FileUtils.READ_LIST_REQUEST; |
| 783 request[1] = _id; | 833 request[1] = _id; |
| 784 request[2] = bytes; | 834 request[2] = bytes; |
| 785 return _fileService.call(request).transform((response) { | 835 return _fileService.call(request).transform((response) { |
| 786 if (_isErrorResponse(response)) { | 836 if (_isErrorResponse(response)) { |
| 787 throw _exceptionFromResponse(response, | 837 throw _exceptionFromResponse(response, |
| 788 "readList failed for file '$_name'"); | 838 "readList failed for file '$_name'"); |
| 789 } | 839 } |
| 790 var read = response[1]; | 840 var read = response[1]; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 820 if (value is !int) { | 870 if (value is !int) { |
| 821 // Complete asynchronously so the user has a chance to setup | 871 // Complete asynchronously so the user has a chance to setup |
| 822 // handlers without getting exceptions when registering the | 872 // handlers without getting exceptions when registering the |
| 823 // then handler. | 873 // then handler. |
| 824 new Timer(0, (t) { | 874 new Timer(0, (t) { |
| 825 completer.completeException(new FileIOException( | 875 completer.completeException(new FileIOException( |
| 826 "Invalid argument to writeByte for file '$_name'")); | 876 "Invalid argument to writeByte for file '$_name'")); |
| 827 }); | 877 }); |
| 828 return completer.future; | 878 return completer.future; |
| 829 } | 879 } |
| 830 if (_isClosed) return _completeWithClosedException(completer); | 880 if (closed) return _completeWithClosedException(completer); |
| 831 List request = new List(3); | 881 List request = new List(3); |
| 832 request[0] = _FileUtils.WRITE_BYTE_REQUEST; | 882 request[0] = _FileUtils.WRITE_BYTE_REQUEST; |
| 833 request[1] = _id; | 883 request[1] = _id; |
| 834 request[2] = value; | 884 request[2] = value; |
| 835 return _fileService.call(request).transform((response) { | 885 return _fileService.call(request).transform((response) { |
| 836 if (_isErrorResponse(response)) { | 886 if (_isErrorResponse(response)) { |
| 837 throw _exceptionFromResponse(response, | 887 throw _exceptionFromResponse(response, |
| 838 "writeByte failed for file '$_name'"); | 888 "writeByte failed for file '$_name'"); |
| 839 } | 889 } |
| 840 return this; | 890 return this; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 861 if (buffer is !List || offset is !int || bytes is !int) { | 911 if (buffer is !List || offset is !int || bytes is !int) { |
| 862 // Complete asynchronously so the user has a chance to setup | 912 // Complete asynchronously so the user has a chance to setup |
| 863 // handlers without getting exceptions when registering the | 913 // handlers without getting exceptions when registering the |
| 864 // then handler. | 914 // then handler. |
| 865 new Timer(0, (t) { | 915 new Timer(0, (t) { |
| 866 completer.completeException(new FileIOException( | 916 completer.completeException(new FileIOException( |
| 867 "Invalid arguments to writeList for file '$_name'")); | 917 "Invalid arguments to writeList for file '$_name'")); |
| 868 }); | 918 }); |
| 869 return completer.future; | 919 return completer.future; |
| 870 } | 920 } |
| 871 if (_isClosed) return _completeWithClosedException(completer); | 921 if (closed) return _completeWithClosedException(completer); |
| 872 | 922 |
| 873 List result; | 923 List result; |
| 874 try { | 924 try { |
| 875 result = | 925 result = |
| 876 _FileUtils.ensureFastAndSerializableBuffer(buffer, offset, bytes); | 926 _FileUtils.ensureFastAndSerializableBuffer(buffer, offset, bytes); |
| 877 } catch (var e) { | 927 } catch (var e) { |
| 878 // Complete asynchronously so the user has a chance to setup | 928 // Complete asynchronously so the user has a chance to setup |
| 879 // handlers without getting exceptions when registering the | 929 // handlers without getting exceptions when registering the |
| 880 // then handler. | 930 // then handler. |
| 881 new Timer(0, (t) => completer.completeException(e)); | 931 new Timer(0, (t) => completer.completeException(e)); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 915 if (result is OSError) { | 965 if (result is OSError) { |
| 916 throw new FileIOException("writeList failed for file '$_name'", result); | 966 throw new FileIOException("writeList failed for file '$_name'", result); |
| 917 } | 967 } |
| 918 return result; | 968 return result; |
| 919 } | 969 } |
| 920 | 970 |
| 921 Future<RandomAccessFile> writeString(String string, | 971 Future<RandomAccessFile> writeString(String string, |
| 922 [Encoding encoding = Encoding.UTF_8]) { | 972 [Encoding encoding = Encoding.UTF_8]) { |
| 923 _ensureFileService(); | 973 _ensureFileService(); |
| 924 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 974 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
| 925 if (_isClosed) return _completeWithClosedException(completer); | 975 if (closed) return _completeWithClosedException(completer); |
| 926 List request = new List(3); | 976 List request = new List(3); |
| 927 request[0] = _FileUtils.WRITE_STRING_REQUEST; | 977 request[0] = _FileUtils.WRITE_STRING_REQUEST; |
| 928 request[1] = _id; | 978 request[1] = _id; |
| 929 request[2] = string; | 979 request[2] = string; |
| 930 return _fileService.call(request).transform((response) { | 980 return _fileService.call(request).transform((response) { |
| 931 if (_isErrorResponse(response)) { | 981 if (_isErrorResponse(response)) { |
| 932 throw _exceptionFromResponse(response, | 982 throw _exceptionFromResponse(response, |
| 933 "writeString failed for file '$_name'"); | 983 "writeString failed for file '$_name'"); |
| 934 } | 984 } |
| 935 return this; | 985 return this; |
| 936 }); | 986 }); |
| 937 } | 987 } |
| 938 | 988 |
| 939 int writeStringSync(String string, [Encoding encoding = Encoding.UTF_8]) { | 989 int writeStringSync(String string, [Encoding encoding = Encoding.UTF_8]) { |
| 940 _checkNotClosed(); | 990 _checkNotClosed(); |
| 941 var result = _FileUtils.checkedWriteString(_id, string); | 991 var result = _FileUtils.checkedWriteString(_id, string); |
| 942 if (result is OSError) { | 992 if (result is OSError) { |
| 943 throw new FileIOException("writeString failed for file '$_name'"); | 993 throw new FileIOException("writeString failed for file '$_name'"); |
| 944 } | 994 } |
| 945 return result; | 995 return result; |
| 946 } | 996 } |
| 947 | 997 |
| 948 Future<int> position() { | 998 Future<int> position() { |
| 949 _ensureFileService(); | 999 _ensureFileService(); |
| 950 Completer<int> completer = new Completer<int>(); | 1000 Completer<int> completer = new Completer<int>(); |
| 951 if (_isClosed) return _completeWithClosedException(completer); | 1001 if (closed) return _completeWithClosedException(completer); |
| 952 List request = new List(2); | 1002 List request = new List(2); |
| 953 request[0] = _FileUtils.POSITION_REQUEST; | 1003 request[0] = _FileUtils.POSITION_REQUEST; |
| 954 request[1] = _id; | 1004 request[1] = _id; |
| 955 return _fileService.call(request).transform((response) { | 1005 return _fileService.call(request).transform((response) { |
| 956 if (_isErrorResponse(response)) { | 1006 if (_isErrorResponse(response)) { |
| 957 throw _exceptionFromResponse(response, | 1007 throw _exceptionFromResponse(response, |
| 958 "position failed for file '$_name'"); | 1008 "position failed for file '$_name'"); |
| 959 } | 1009 } |
| 960 return response; | 1010 return response; |
| 961 }); | 1011 }); |
| 962 } | 1012 } |
| 963 | 1013 |
| 964 int positionSync() { | 1014 int positionSync() { |
| 965 _checkNotClosed(); | 1015 _checkNotClosed(); |
| 966 var result = _FileUtils.position(_id); | 1016 var result = _FileUtils.position(_id); |
| 967 if (result is OSError) { | 1017 if (result is OSError) { |
| 968 throw new FileIOException("position failed for file '$_name'", result); | 1018 throw new FileIOException("position failed for file '$_name'", result); |
| 969 } | 1019 } |
| 970 return result; | 1020 return result; |
| 971 } | 1021 } |
| 972 | 1022 |
| 973 Future<RandomAccessFile> setPosition(int position) { | 1023 Future<RandomAccessFile> setPosition(int position) { |
| 974 _ensureFileService(); | 1024 _ensureFileService(); |
| 975 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 1025 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
| 976 if (_isClosed) return _completeWithClosedException(completer); | 1026 if (closed) return _completeWithClosedException(completer); |
| 977 List request = new List(3); | 1027 List request = new List(3); |
| 978 request[0] = _FileUtils.SET_POSITION_REQUEST; | 1028 request[0] = _FileUtils.SET_POSITION_REQUEST; |
| 979 request[1] = _id; | 1029 request[1] = _id; |
| 980 request[2] = position; | 1030 request[2] = position; |
| 981 return _fileService.call(request).transform((response) { | 1031 return _fileService.call(request).transform((response) { |
| 982 if (_isErrorResponse(response)) { | 1032 if (_isErrorResponse(response)) { |
| 983 throw _exceptionFromResponse(response, | 1033 throw _exceptionFromResponse(response, |
| 984 "setPosition failed for file '$_name'"); | 1034 "setPosition failed for file '$_name'"); |
| 985 } | 1035 } |
| 986 return this; | 1036 return this; |
| 987 }); | 1037 }); |
| 988 } | 1038 } |
| 989 | 1039 |
| 990 void setPositionSync(int position) { | 1040 void setPositionSync(int position) { |
| 991 _checkNotClosed(); | 1041 _checkNotClosed(); |
| 992 var result = _FileUtils.setPosition(_id, position); | 1042 var result = _FileUtils.setPosition(_id, position); |
| 993 if (result is OSError) { | 1043 if (result is OSError) { |
| 994 throw new FileIOException("setPosition failed for file '$_name'", result); | 1044 throw new FileIOException("setPosition failed for file '$_name'", result); |
| 995 } | 1045 } |
| 996 } | 1046 } |
| 997 | 1047 |
| 998 Future<RandomAccessFile> truncate(int length) { | 1048 Future<RandomAccessFile> truncate(int length) { |
| 999 _ensureFileService(); | 1049 _ensureFileService(); |
| 1000 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 1050 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
| 1001 if (_isClosed) return _completeWithClosedException(completer); | 1051 if (closed) return _completeWithClosedException(completer); |
| 1002 List request = new List(3); | 1052 List request = new List(3); |
| 1003 request[0] = _FileUtils.TRUNCATE_REQUEST; | 1053 request[0] = _FileUtils.TRUNCATE_REQUEST; |
| 1004 request[1] = _id; | 1054 request[1] = _id; |
| 1005 request[2] = length; | 1055 request[2] = length; |
| 1006 return _fileService.call(request).transform((response) { | 1056 return _fileService.call(request).transform((response) { |
| 1007 if (_isErrorResponse(response)) { | 1057 if (_isErrorResponse(response)) { |
| 1008 throw _exceptionFromResponse(response, | 1058 throw _exceptionFromResponse(response, |
| 1009 "truncate failed for file '$_name'"); | 1059 "truncate failed for file '$_name'"); |
| 1010 } | 1060 } |
| 1011 return this; | 1061 return this; |
| 1012 }); | 1062 }); |
| 1013 } | 1063 } |
| 1014 | 1064 |
| 1015 void truncateSync(int length) { | 1065 void truncateSync(int length) { |
| 1016 _checkNotClosed(); | 1066 _checkNotClosed(); |
| 1017 var result = _FileUtils.truncate(_id, length); | 1067 var result = _FileUtils.truncate(_id, length); |
| 1018 if (result is OSError) { | 1068 if (result is OSError) { |
| 1019 throw new FileIOException("truncate failed for file '$_name'", result); | 1069 throw new FileIOException("truncate failed for file '$_name'", result); |
| 1020 } | 1070 } |
| 1021 } | 1071 } |
| 1022 | 1072 |
| 1023 Future<int> length() { | 1073 Future<int> length() { |
| 1024 _ensureFileService(); | 1074 _ensureFileService(); |
| 1025 Completer<int> completer = new Completer<int>(); | 1075 Completer<int> completer = new Completer<int>(); |
| 1026 if (_isClosed) return _completeWithClosedException(completer); | 1076 if (closed) return _completeWithClosedException(completer); |
| 1027 List request = new List(2); | 1077 List request = new List(2); |
| 1028 request[0] = _FileUtils.LENGTH_REQUEST; | 1078 request[0] = _FileUtils.LENGTH_REQUEST; |
| 1029 request[1] = _id; | 1079 request[1] = _id; |
| 1030 return _fileService.call(request).transform((response) { | 1080 return _fileService.call(request).transform((response) { |
| 1031 if (_isErrorResponse(response)) { | 1081 if (_isErrorResponse(response)) { |
| 1032 throw _exceptionFromResponse(response, | 1082 throw _exceptionFromResponse(response, |
| 1033 "length failed for file '$_name'"); | 1083 "length failed for file '$_name'"); |
| 1034 } | 1084 } |
| 1035 return response; | 1085 return response; |
| 1036 }); | 1086 }); |
| 1037 } | 1087 } |
| 1038 | 1088 |
| 1039 int lengthSync() { | 1089 int lengthSync() { |
| 1040 _checkNotClosed(); | 1090 _checkNotClosed(); |
| 1041 var result = _FileUtils.length(_id); | 1091 var result = _FileUtils.length(_id); |
| 1042 if (result is OSError) { | 1092 if (result is OSError) { |
| 1043 throw new FileIOException("length failed for file '$_name'", result); | 1093 throw new FileIOException("length failed for file '$_name'", result); |
| 1044 } | 1094 } |
| 1045 return result; | 1095 return result; |
| 1046 } | 1096 } |
| 1047 | 1097 |
| 1048 Future<RandomAccessFile> flush() { | 1098 Future<RandomAccessFile> flush() { |
| 1049 _ensureFileService(); | 1099 _ensureFileService(); |
| 1050 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 1100 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
| 1051 if (_isClosed) return _completeWithClosedException(completer); | 1101 if (closed) return _completeWithClosedException(completer); |
| 1052 List request = new List(2); | 1102 List request = new List(2); |
| 1053 request[0] = _FileUtils.FLUSH_REQUEST; | 1103 request[0] = _FileUtils.FLUSH_REQUEST; |
| 1054 request[1] = _id; | 1104 request[1] = _id; |
| 1055 return _fileService.call(request).transform((response) { | 1105 return _fileService.call(request).transform((response) { |
| 1056 if (_isErrorResponse(response)) { | 1106 if (_isErrorResponse(response)) { |
| 1057 throw _exceptionFromResponse(response, | 1107 throw _exceptionFromResponse(response, |
| 1058 "flush failed for file '$_name'"); | 1108 "flush failed for file '$_name'"); |
| 1059 } | 1109 } |
| 1060 return this; | 1110 return this; |
| 1061 }); | 1111 }); |
| 1062 } | 1112 } |
| 1063 | 1113 |
| 1064 void flushSync() { | 1114 void flushSync() { |
| 1065 _checkNotClosed(); | 1115 _checkNotClosed(); |
| 1066 var result = _FileUtils.flush(_id); | 1116 var result = _FileUtils.flush(_id); |
| 1067 if (result is OSError) { | 1117 if (result is OSError) { |
| 1068 throw new FileIOException("flush failed for file '$_name'", result); | 1118 throw new FileIOException("flush failed for file '$_name'", result); |
| 1069 } | 1119 } |
| 1070 } | 1120 } |
| 1071 | 1121 |
| 1072 String get name() => _name; | 1122 String get name() => _name; |
| 1073 | 1123 |
| 1074 void _ensureFileService() { | 1124 void _ensureFileService() { |
| 1075 if (_fileService == null) { | 1125 if (_fileService == null) { |
| 1076 _fileService = _FileUtils.newServicePort(); | 1126 _fileService = _FileUtils.newServicePort(); |
| 1077 } | 1127 } |
| 1078 } | 1128 } |
| 1079 | 1129 |
| 1080 bool get _isClosed() => _id == 0; | 1130 bool get closed() => _id == 0; |
| 1081 | 1131 |
| 1082 void _checkNotClosed() { | 1132 void _checkNotClosed() { |
| 1083 if (_isClosed) { | 1133 if (closed) { |
| 1084 throw new FileIOException("File closed '$_name'"); | 1134 throw new FileIOException("File closed '$_name'"); |
| 1085 } | 1135 } |
| 1086 } | 1136 } |
| 1087 | 1137 |
| 1088 Future _completeWithClosedException(Completer completer) { | 1138 Future _completeWithClosedException(Completer completer) { |
| 1089 new Timer(0, (t) { | 1139 new Timer(0, (t) { |
| 1090 completer.completeException( | 1140 completer.completeException( |
| 1091 new FileIOException("File closed '$_name'")); | 1141 new FileIOException("File closed '$_name'")); |
| 1092 }); | 1142 }); |
| 1093 return completer.future; | 1143 return completer.future; |
| 1094 } | 1144 } |
| 1095 | 1145 |
| 1096 final String _name; | 1146 final String _name; |
| 1097 int _id; | 1147 int _id; |
| 1098 | 1148 |
| 1099 SendPort _fileService; | 1149 SendPort _fileService; |
| 1100 } | 1150 } |
| OLD | NEW |