| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of dart.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 // Read the file in blocks of size 64k. | 7 // Read the file in blocks of size 64k. |
| 8 const int _BLOCK_SIZE = 64 * 1024; | 8 const int _BLOCK_SIZE = 64 * 1024; |
| 9 | 9 |
| 10 | 10 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 _openFuture = new Future.immediate(_File._openStdioSync(fd)); | 161 _openFuture = new Future.immediate(_File._openStdioSync(fd)); |
| 162 } | 162 } |
| 163 | 163 |
| 164 Future<File> addStream(Stream<List<int>> stream) { | 164 Future<File> addStream(Stream<List<int>> stream) { |
| 165 Completer<File> completer = new Completer<File>(); | 165 Completer<File> completer = new Completer<File>(); |
| 166 _openFuture | 166 _openFuture |
| 167 .then((openedFile) { | 167 .then((openedFile) { |
| 168 _subscription = stream.listen( | 168 _subscription = stream.listen( |
| 169 (d) { | 169 (d) { |
| 170 _subscription.pause(); | 170 _subscription.pause(); |
| 171 openedFile.writeList(d, 0, d.length) | 171 openedFile.writeFrom(d, 0, d.length) |
| 172 .then((_) => _subscription.resume()) | 172 .then((_) => _subscription.resume()) |
| 173 .catchError((e) { | 173 .catchError((e) { |
| 174 openedFile.close(); | 174 openedFile.close(); |
| 175 completer.completeError(e); | 175 completer.completeError(e); |
| 176 }); | 176 }); |
| 177 }, | 177 }, |
| 178 onDone: () { | 178 onDone: () { |
| 179 completer.complete(_file); | 179 completer.complete(_file); |
| 180 }, | 180 }, |
| 181 onError: (e) { | 181 onError: (e) { |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 sink.add(bytes); | 556 sink.add(bytes); |
| 557 sink.close(); | 557 sink.close(); |
| 558 return sink.done.then((_) => this);; | 558 return sink.done.then((_) => this);; |
| 559 } catch (e) { | 559 } catch (e) { |
| 560 return new Future.immediateError(e); | 560 return new Future.immediateError(e); |
| 561 } | 561 } |
| 562 } | 562 } |
| 563 | 563 |
| 564 void writeAsBytesSync(List<int> bytes, {FileMode mode: FileMode.WRITE}) { | 564 void writeAsBytesSync(List<int> bytes, {FileMode mode: FileMode.WRITE}) { |
| 565 RandomAccessFile opened = openSync(mode: mode); | 565 RandomAccessFile opened = openSync(mode: mode); |
| 566 opened.writeListSync(bytes, 0, bytes.length); | 566 opened.writeFromSync(bytes, 0, bytes.length); |
| 567 opened.closeSync(); | 567 opened.closeSync(); |
| 568 } | 568 } |
| 569 | 569 |
| 570 Future<File> writeAsString(String contents, | 570 Future<File> writeAsString(String contents, |
| 571 {FileMode mode: FileMode.WRITE, | 571 {FileMode mode: FileMode.WRITE, |
| 572 Encoding encoding: Encoding.UTF_8}) { | 572 Encoding encoding: Encoding.UTF_8}) { |
| 573 try { | 573 try { |
| 574 return writeAsBytes(_encodeString(contents, encoding), mode: mode); | 574 return writeAsBytes(_encodeString(contents, encoding), mode: mode); |
| 575 } catch (e) { | 575 } catch (e) { |
| 576 var completer = new Completer(); | 576 var completer = new Completer(); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 "Invalid arguments to readSync for file '$_path'"); | 704 "Invalid arguments to readSync for file '$_path'"); |
| 705 } | 705 } |
| 706 var result = _read(_id, bytes); | 706 var result = _read(_id, bytes); |
| 707 if (result is OSError) { | 707 if (result is OSError) { |
| 708 throw new FileIOException("readSync failed for file '$_path'", | 708 throw new FileIOException("readSync failed for file '$_path'", |
| 709 result); | 709 result); |
| 710 } | 710 } |
| 711 return result; | 711 return result; |
| 712 } | 712 } |
| 713 | 713 |
| 714 Future<int> readList(List<int> buffer, int offset, int bytes) { | 714 Future<int> readInto(List<int> buffer, [int start, int end]) { |
| 715 _ensureFileService(); | 715 _ensureFileService(); |
| 716 if (buffer is !List || |
| 717 (start != null && start is !int) || |
| 718 (end != null && end is !int)) { |
| 719 return new Future.immediateError(new FileIOException( |
| 720 "Invalid arguments to readInto for file '$_path'")); |
| 721 }; |
| 716 Completer<int> completer = new Completer<int>(); | 722 Completer<int> completer = new Completer<int>(); |
| 717 if (buffer is !List || offset is !int || bytes is !int) { | |
| 718 // Complete asynchronously so the user has a chance to setup | |
| 719 // handlers without getting exceptions when registering the | |
| 720 // then handler. | |
| 721 Timer.run(() { | |
| 722 completer.completeError(new FileIOException( | |
| 723 "Invalid arguments to readList for file '$_path'")); | |
| 724 }); | |
| 725 return completer.future; | |
| 726 }; | |
| 727 if (closed) return _completeWithClosedException(completer); | 723 if (closed) return _completeWithClosedException(completer); |
| 728 List request = new List(3); | 724 List request = new List(3); |
| 725 if (start == null) start = 0; |
| 726 if (end == null) end = buffer.length; |
| 729 request[0] = _READ_LIST_REQUEST; | 727 request[0] = _READ_LIST_REQUEST; |
| 730 request[1] = _id; | 728 request[1] = _id; |
| 731 request[2] = bytes; | 729 request[2] = end - start; |
| 732 return _fileService.call(request).then((response) { | 730 return _fileService.call(request).then((response) { |
| 733 if (_isErrorResponse(response)) { | 731 if (_isErrorResponse(response)) { |
| 734 throw _exceptionFromResponse(response, | 732 throw _exceptionFromResponse(response, |
| 735 "readList failed for file '$_path'"); | 733 "readInto failed for file '$_path'"); |
| 736 } | 734 } |
| 737 var read = response[1]; | 735 var read = response[1]; |
| 738 var data = response[2]; | 736 var data = response[2]; |
| 739 buffer.setRange(offset, offset + read, data); | 737 buffer.setRange(start, start + read, data); |
| 740 return read; | 738 return read; |
| 741 }); | 739 }); |
| 742 } | 740 } |
| 743 | 741 |
| 744 static void _checkReadWriteListArguments(int length, int offset, int bytes) { | 742 static void _checkReadWriteListArguments(int length, int start, int end) { |
| 745 if (offset < 0) throw new RangeError.value(offset); | 743 if (start < 0) throw new RangeError.value(start); |
| 746 if (bytes < 0) throw new RangeError.value(bytes); | 744 if (end < start) throw new RangeError.value(end); |
| 747 if ((offset + bytes) > length) { | 745 if (end > length) { |
| 748 throw new RangeError.value(offset + bytes); | 746 throw new RangeError.value(end); |
| 749 } | 747 } |
| 750 } | 748 } |
| 751 | 749 |
| 752 external static _readList(int id, List<int> buffer, int offset, int bytes); | 750 external static _readInto(int id, List<int> buffer, int start, int end); |
| 753 | 751 |
| 754 int readListSync(List<int> buffer, int offset, int bytes) { | 752 int readIntoSync(List<int> buffer, [int start, int end]) { |
| 755 _checkNotClosed(); | 753 _checkNotClosed(); |
| 756 if (buffer is !List || offset is !int || bytes is !int) { | 754 if (buffer is !List || |
| 755 (start != null && start is !int) || |
| 756 (end != null && end is !int)) { |
| 757 throw new FileIOException( | 757 throw new FileIOException( |
| 758 "Invalid arguments to readList for file '$_path'"); | 758 "Invalid arguments to readInto for file '$_path'"); |
| 759 } | 759 } |
| 760 if (bytes == 0) return 0; | 760 if (start == null) start = 0; |
| 761 _checkReadWriteListArguments(buffer.length, offset, bytes); | 761 if (end == null) end = buffer.length; |
| 762 var result = _readList(_id, buffer, offset, bytes); | 762 if (end == start) return 0; |
| 763 _checkReadWriteListArguments(buffer.length, start, end); |
| 764 var result = _readInto(_id, buffer, start, end); |
| 763 if (result is OSError) { | 765 if (result is OSError) { |
| 764 throw new FileIOException("readList failed for file '$_path'", | 766 throw new FileIOException("readInto failed for file '$_path'", |
| 765 result); | 767 result); |
| 766 } | 768 } |
| 767 return result; | 769 return result; |
| 768 } | 770 } |
| 769 | 771 |
| 770 Future<RandomAccessFile> writeByte(int value) { | 772 Future<RandomAccessFile> writeByte(int value) { |
| 771 _ensureFileService(); | 773 _ensureFileService(); |
| 772 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 774 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
| 773 if (value is !int) { | 775 if (value is !int) { |
| 774 // Complete asynchronously so the user has a chance to setup | 776 // Complete asynchronously so the user has a chance to setup |
| (...skipping 28 matching lines...) Expand all Loading... |
| 803 "Invalid argument to writeByte for file '$_path'"); | 805 "Invalid argument to writeByte for file '$_path'"); |
| 804 } | 806 } |
| 805 var result = _writeByte(_id, value); | 807 var result = _writeByte(_id, value); |
| 806 if (result is OSError) { | 808 if (result is OSError) { |
| 807 throw new FileIOException("writeByte failed for file '$_path'", | 809 throw new FileIOException("writeByte failed for file '$_path'", |
| 808 result); | 810 result); |
| 809 } | 811 } |
| 810 return result; | 812 return result; |
| 811 } | 813 } |
| 812 | 814 |
| 813 Future<RandomAccessFile> writeList(List<int> buffer, int offset, int bytes) { | 815 Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]) { |
| 814 _ensureFileService(); | 816 _ensureFileService(); |
| 817 if ((buffer is !List && buffer is !ByteData) || |
| 818 (start != null && start is !int) || |
| 819 (end != null && end is !int)) { |
| 820 return new Future.immediateError(new FileIOException( |
| 821 "Invalid arguments to writeFrom for file '$_path'")); |
| 822 } |
| 815 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 823 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
| 816 if ((buffer is !List && buffer is !ByteData) || | 824 |
| 817 offset is !int || | |
| 818 bytes is !int) { | |
| 819 // Complete asynchronously so the user has a chance to setup | |
| 820 // handlers without getting exceptions when registering the | |
| 821 // then handler. | |
| 822 Timer.run(() { | |
| 823 completer.completeError(new FileIOException( | |
| 824 "Invalid arguments to writeList for file '$_path'")); | |
| 825 }); | |
| 826 return completer.future; | |
| 827 } | |
| 828 if (closed) return _completeWithClosedException(completer); | 825 if (closed) return _completeWithClosedException(completer); |
| 829 | 826 |
| 830 _BufferAndOffset result; | 827 _BufferAndStart result; |
| 831 try { | 828 try { |
| 832 result = _ensureFastAndSerializableBuffer(buffer, offset, bytes); | 829 result = _ensureFastAndSerializableBuffer(buffer, start, end); |
| 833 } catch (e) { | 830 } catch (e) { |
| 834 // Complete asynchronously so the user has a chance to setup | 831 return new Future.immediateError(e); |
| 835 // handlers without getting exceptions when registering the | |
| 836 // then handler. | |
| 837 Timer.run(() => completer.completeError(e)); | |
| 838 return completer.future; | |
| 839 } | 832 } |
| 840 | 833 |
| 841 List request = new List(5); | 834 List request = new List(5); |
| 842 request[0] = _WRITE_LIST_REQUEST; | 835 request[0] = _WRITE_LIST_REQUEST; |
| 843 request[1] = _id; | 836 request[1] = _id; |
| 844 request[2] = result.buffer; | 837 request[2] = result.buffer; |
| 845 request[3] = result.offset; | 838 request[3] = result.start; |
| 846 request[4] = bytes; | 839 request[4] = end - (start - result.start); |
| 847 return _fileService.call(request).then((response) { | 840 return _fileService.call(request).then((response) { |
| 848 if (_isErrorResponse(response)) { | 841 if (_isErrorResponse(response)) { |
| 849 throw _exceptionFromResponse(response, | 842 throw _exceptionFromResponse(response, |
| 850 "writeList failed for file '$_path'"); | 843 "writeFrom failed for file '$_path'"); |
| 851 } | 844 } |
| 852 return this; | 845 return this; |
| 853 }); | 846 }); |
| 854 } | 847 } |
| 855 | 848 |
| 856 external static _writeList(int id, List<int> buffer, int offset, int bytes); | 849 external static _writeFrom(int id, List<int> buffer, int start, int end); |
| 857 | 850 |
| 858 int writeListSync(List<int> buffer, int offset, int bytes) { | 851 void writeFromSync(List<int> buffer, [int start, int end]) { |
| 859 _checkNotClosed(); | 852 _checkNotClosed(); |
| 860 if (buffer is !List || offset is !int || bytes is !int) { | 853 if (buffer is !List || |
| 854 (start != null && start is !int) || |
| 855 (end != null && end is !int)) { |
| 861 throw new FileIOException( | 856 throw new FileIOException( |
| 862 "Invalid arguments to writeList for file '$_path'"); | 857 "Invalid arguments to writeFrom for file '$_path'"); |
| 863 } | 858 } |
| 864 if (bytes == 0) return 0; | 859 if (start == null) start = 0; |
| 865 _checkReadWriteListArguments(buffer.length, offset, bytes); | 860 if (end == null) end = buffer.length; |
| 866 _BufferAndOffset bufferAndOffset = | 861 if (end == start) return; |
| 867 _ensureFastAndSerializableBuffer(buffer, offset, bytes); | 862 _checkReadWriteListArguments(buffer.length, start, end); |
| 868 var result = | 863 _BufferAndStart bufferAndStart = |
| 869 _writeList(_id, bufferAndOffset.buffer, bufferAndOffset.offset, bytes); | 864 _ensureFastAndSerializableBuffer(buffer, start, end); |
| 865 var result = _writeFrom(_id, |
| 866 bufferAndStart.buffer, |
| 867 bufferAndStart.start, |
| 868 end - (start - bufferAndStart.start)); |
| 870 if (result is OSError) { | 869 if (result is OSError) { |
| 871 throw new FileIOException("writeList failed for file '$_path'", result); | 870 throw new FileIOException("writeFrom failed for file '$_path'", result); |
| 872 } | 871 } |
| 873 return result; | |
| 874 } | 872 } |
| 875 | 873 |
| 876 Future<RandomAccessFile> writeString(String string, | 874 Future<RandomAccessFile> writeString(String string, |
| 877 {Encoding encoding: Encoding.UTF_8}) { | 875 {Encoding encoding: Encoding.UTF_8}) { |
| 878 if (encoding is! Encoding) { | 876 if (encoding is! Encoding) { |
| 879 var completer = new Completer(); | 877 var completer = new Completer(); |
| 880 Timer.run(() { | 878 Timer.run(() { |
| 881 completer.completeError(new FileIOException( | 879 completer.completeError(new FileIOException( |
| 882 "Invalid encoding in writeString: $encoding")); | 880 "Invalid encoding in writeString: $encoding")); |
| 883 }); | 881 }); |
| 884 return completer.future; | 882 return completer.future; |
| 885 } | 883 } |
| 886 var data = _encodeString(string, encoding); | 884 var data = _encodeString(string, encoding); |
| 887 return writeList(data, 0, data.length); | 885 return writeFrom(data, 0, data.length); |
| 888 } | 886 } |
| 889 | 887 |
| 890 int writeStringSync(String string, {Encoding encoding: Encoding.UTF_8}) { | 888 void writeStringSync(String string, {Encoding encoding: Encoding.UTF_8}) { |
| 891 if (encoding is! Encoding) { | 889 if (encoding is! Encoding) { |
| 892 throw new FileIOException( | 890 throw new FileIOException( |
| 893 "Invalid encoding in writeStringSync: $encoding"); | 891 "Invalid encoding in writeStringSync: $encoding"); |
| 894 } | 892 } |
| 895 var data = _encodeString(string, encoding); | 893 var data = _encodeString(string, encoding); |
| 896 return writeListSync(data, 0, data.length); | 894 writeFromSync(data, 0, data.length); |
| 897 } | 895 } |
| 898 | 896 |
| 899 Future<int> position() { | 897 Future<int> position() { |
| 900 _ensureFileService(); | 898 _ensureFileService(); |
| 901 Completer<int> completer = new Completer<int>(); | 899 Completer<int> completer = new Completer<int>(); |
| 902 if (closed) return _completeWithClosedException(completer); | 900 if (closed) return _completeWithClosedException(completer); |
| 903 List request = new List(2); | 901 List request = new List(2); |
| 904 request[0] = _POSITION_REQUEST; | 902 request[0] = _POSITION_REQUEST; |
| 905 request[1] = _id; | 903 request[1] = _id; |
| 906 return _fileService.call(request).then((response) { | 904 return _fileService.call(request).then((response) { |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1052 new FileIOException("File closed '$_path'")); | 1050 new FileIOException("File closed '$_path'")); |
| 1053 }); | 1051 }); |
| 1054 return completer.future; | 1052 return completer.future; |
| 1055 } | 1053 } |
| 1056 | 1054 |
| 1057 final String _path; | 1055 final String _path; |
| 1058 int _id; | 1056 int _id; |
| 1059 | 1057 |
| 1060 SendPort _fileService; | 1058 SendPort _fileService; |
| 1061 } | 1059 } |
| OLD | NEW |