Chromium Code Reviews| 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 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 559 | 559 |
| 560 static throwIfError(Object result, String msg, String path) { | 560 static throwIfError(Object result, String msg, String path) { |
| 561 if (result is OSError) { | 561 if (result is OSError) { |
| 562 throw new FileSystemException(msg, path, result); | 562 throw new FileSystemException(msg, path, result); |
| 563 } | 563 } |
| 564 } | 564 } |
| 565 } | 565 } |
| 566 | 566 |
| 567 | 567 |
| 568 class _RandomAccessFile | 568 class _RandomAccessFile |
| 569 extends Object with _ServiceObject | |
| 570 implements RandomAccessFile { | 569 implements RandomAccessFile { |
| 571 // Use default Map so we keep order. | 570 static bool _connectedResourceHandler = false; |
| 572 static Map<int, _RandomAccessFile> _files = new Map<int, _RandomAccessFile>(); | |
| 573 | 571 |
| 574 final String path; | 572 final String path; |
| 575 int _id; | 573 int _id; |
| 576 bool _asyncDispatched = false; | 574 bool _asyncDispatched = false; |
| 577 SendPort _fileService; | 575 SendPort _fileService; |
| 578 | 576 |
| 579 int _totalRead = 0; | 577 _FileResourceInfo _resourceInfo; |
| 580 int _totalWritten = 0; | |
| 581 int _readCount = 0; | |
| 582 int _writeCount = 0; | |
| 583 | |
| 584 | 578 |
| 585 _RandomAccessFile(this._id, this.path) { | 579 _RandomAccessFile(this._id, this.path) { |
| 586 _files[_serviceId] = this; | 580 _resourceInfo = new _FileResourceInfo(this); |
| 587 } | 581 _maybeConnectHandler(); |
| 588 | |
| 589 String get _serviceTypePath => 'io/file/randomaccessfiles'; | |
| 590 String get _serviceTypeName => 'RandomAccessFile'; | |
| 591 | |
| 592 Map _toJSON(bool ref) { | |
| 593 var r = { | |
| 594 'id': _servicePath, | |
| 595 'type': _serviceType(ref), | |
| 596 'name': '$path', | |
| 597 'user_name': '$path', | |
| 598 }; | |
| 599 if (ref) { | |
| 600 return r; | |
| 601 } | |
| 602 r['asyncDispatched'] = _asyncDispatched; | |
| 603 r['fd'] = _getFD(_id); | |
| 604 r['totalRead'] = _totalRead; | |
| 605 r['totalWritten'] = _totalWritten; | |
| 606 r['readCount'] = _totalWritten; | |
| 607 r['writeCount'] = _writeCount; | |
| 608 return r; | |
| 609 } | 582 } |
| 610 | 583 |
| 611 void _maybePerformCleanup() { | 584 void _maybePerformCleanup() { |
| 612 if (closed) { | 585 if (closed) { |
| 613 _files.remove(_serviceId); | 586 _FileResourceInfo.FileClosed(_resourceInfo); |
| 614 } | 587 } |
| 615 } | 588 } |
| 616 | 589 |
| 617 external static int _getFD(int id); | 590 external static int _getFD(int id); |
| 618 | 591 |
| 592 _maybeConnectHandler() { | |
| 593 if (!_connectedResourceHandler) { | |
| 594 // TODO(ricow): we probably need set these in some initialization code. | |
| 595 // We need to make sure that these are always awailable from the | |
| 596 // observatory even if no files (or sockets for the socket ones) are | |
| 597 // open. | |
|
Ivan Posva
2015/09/08 18:06:36
Correct, this should be done with the overall init
Cutch
2015/09/10 14:42:44
We probably also need to do this automatically for
| |
| 598 registerExtension('__getOpenFiles', | |
| 599 _FileResourceInfo.getOpenFiles); | |
| 600 registerExtension('__getFileByID', | |
| 601 _FileResourceInfo.getFileInfoMapByID); | |
| 602 _connectedResourceHandler = true; | |
| 603 } | |
| 604 } | |
| 605 | |
| 619 Future<RandomAccessFile> close() { | 606 Future<RandomAccessFile> close() { |
| 620 return _dispatch(_FILE_CLOSE, [_id], markClosed: true).then((result) { | 607 return _dispatch(_FILE_CLOSE, [_id], markClosed: true).then((result) { |
| 621 if (result != -1) { | 608 if (result != -1) { |
| 622 _id = result; | 609 _id = result; |
| 623 _maybePerformCleanup(); | 610 _maybePerformCleanup(); |
| 624 return this; | 611 return this; |
| 625 } else { | 612 } else { |
| 626 throw new FileSystemException("Cannot close file", path); | 613 throw new FileSystemException("Cannot close file", path); |
| 627 } | 614 } |
| 628 }); | 615 }); |
| 629 } | 616 } |
| 630 | 617 |
| 631 external static int _close(int id); | 618 external static int _close(int id); |
| 632 | 619 |
| 633 void closeSync() { | 620 void closeSync() { |
| 634 _checkAvailable(); | 621 _checkAvailable(); |
| 635 var id = _close(_id); | 622 var id = _close(_id); |
| 636 if (id == -1) { | 623 if (id == -1) { |
| 637 throw new FileSystemException("Cannot close file", path); | 624 throw new FileSystemException("Cannot close file", path); |
| 638 } | 625 } |
| 639 _id = id; | 626 _id = id; |
| 640 _maybePerformCleanup(); | 627 _maybePerformCleanup(); |
| 641 } | 628 } |
| 642 | 629 |
| 643 Future<int> readByte() { | 630 Future<int> readByte() { |
| 644 return _dispatch(_FILE_READ_BYTE, [_id]).then((response) { | 631 return _dispatch(_FILE_READ_BYTE, [_id]).then((response) { |
| 645 if (_isErrorResponse(response)) { | 632 if (_isErrorResponse(response)) { |
| 646 throw _exceptionFromResponse(response, "readByte failed", path); | 633 throw _exceptionFromResponse(response, "readByte failed", path); |
| 647 } | 634 } |
| 648 _readCount++; | 635 _resourceInfo.readCount++; |
| 649 _totalRead++; | 636 _resourceInfo.totalRead++; |
| 650 return response; | 637 return response; |
| 651 }); | 638 }); |
| 652 } | 639 } |
| 653 | 640 |
| 654 external static _readByte(int id); | 641 external static _readByte(int id); |
| 655 | 642 |
| 656 int readByteSync() { | 643 int readByteSync() { |
| 657 _checkAvailable(); | 644 _checkAvailable(); |
| 658 var result = _readByte(_id); | 645 var result = _readByte(_id); |
| 659 if (result is OSError) { | 646 if (result is OSError) { |
| 660 throw new FileSystemException("readByte failed", path, result); | 647 throw new FileSystemException("readByte failed", path, result); |
| 661 } | 648 } |
| 662 _readCount++; | 649 _resourceInfo.readCount++; |
| 663 _totalRead++; | 650 _resourceInfo.totalRead++; |
| 664 return result; | 651 return result; |
| 665 } | 652 } |
| 666 | 653 |
| 667 Future<List<int>> read(int bytes) { | 654 Future<List<int>> read(int bytes) { |
| 668 if (bytes is !int) { | 655 if (bytes is !int) { |
| 669 throw new ArgumentError(bytes); | 656 throw new ArgumentError(bytes); |
| 670 } | 657 } |
| 671 return _dispatch(_FILE_READ, [_id, bytes]).then((response) { | 658 return _dispatch(_FILE_READ, [_id, bytes]).then((response) { |
| 672 if (_isErrorResponse(response)) { | 659 if (_isErrorResponse(response)) { |
| 673 throw _exceptionFromResponse(response, "read failed", path); | 660 throw _exceptionFromResponse(response, "read failed", path); |
| 674 } | 661 } |
| 675 _readCount++; | 662 _resourceInfo.readCount++; |
| 676 _totalRead += response[1].length; | 663 _resourceInfo.totalRead += response[1].length; |
| 677 return response[1]; | 664 return response[1]; |
| 678 }); | 665 }); |
| 679 } | 666 } |
| 680 | 667 |
| 681 external static _read(int id, int bytes); | 668 external static _read(int id, int bytes); |
| 682 | 669 |
| 683 List<int> readSync(int bytes) { | 670 List<int> readSync(int bytes) { |
| 684 _checkAvailable(); | 671 _checkAvailable(); |
| 685 if (bytes is !int) { | 672 if (bytes is !int) { |
| 686 throw new ArgumentError(bytes); | 673 throw new ArgumentError(bytes); |
| 687 } | 674 } |
| 688 var result = _read(_id, bytes); | 675 var result = _read(_id, bytes); |
| 689 if (result is OSError) { | 676 if (result is OSError) { |
| 690 throw new FileSystemException("readSync failed", path, result); | 677 throw new FileSystemException("readSync failed", path, result); |
| 691 } | 678 } |
| 692 _readCount++; | 679 _resourceInfo.readCount++; |
| 693 _totalRead += result.length; | 680 _resourceInfo.totalRead += result.length; |
| 694 return result; | 681 return result; |
| 695 } | 682 } |
| 696 | 683 |
| 697 Future<int> readInto(List<int> buffer, [int start = 0, int end]) { | 684 Future<int> readInto(List<int> buffer, [int start = 0, int end]) { |
| 698 if (buffer is !List || | 685 if (buffer is !List || |
| 699 (start != null && start is !int) || | 686 (start != null && start is !int) || |
| 700 (end != null && end is !int)) { | 687 (end != null && end is !int)) { |
| 701 throw new ArgumentError(); | 688 throw new ArgumentError(); |
| 702 } | 689 } |
| 703 end = RangeError.checkValidRange(start, end, buffer.length); | 690 end = RangeError.checkValidRange(start, end, buffer.length); |
| 704 if (end == start) return new Future.value(0); | 691 if (end == start) return new Future.value(0); |
| 705 int length = end - start; | 692 int length = end - start; |
| 706 return _dispatch(_FILE_READ_INTO, [_id, length]).then((response) { | 693 return _dispatch(_FILE_READ_INTO, [_id, length]).then((response) { |
| 707 if (_isErrorResponse(response)) { | 694 if (_isErrorResponse(response)) { |
| 708 throw _exceptionFromResponse(response, "readInto failed", path); | 695 throw _exceptionFromResponse(response, "readInto failed", path); |
| 709 } | 696 } |
| 710 var read = response[1]; | 697 var read = response[1]; |
| 711 var data = response[2]; | 698 var data = response[2]; |
| 712 buffer.setRange(start, start + read, data); | 699 buffer.setRange(start, start + read, data); |
| 713 _readCount++; | 700 _resourceInfo.readCount++; |
| 714 _totalRead += read; | 701 _resourceInfo.totalRead += read; |
| 715 return read; | 702 return read; |
| 716 }); | 703 }); |
| 717 } | 704 } |
| 718 | 705 |
| 719 external static _readInto(int id, List<int> buffer, int start, int end); | 706 external static _readInto(int id, List<int> buffer, int start, int end); |
| 720 | 707 |
| 721 int readIntoSync(List<int> buffer, [int start = 0, int end]) { | 708 int readIntoSync(List<int> buffer, [int start = 0, int end]) { |
| 722 _checkAvailable(); | 709 _checkAvailable(); |
| 723 if (buffer is !List || | 710 if (buffer is !List || |
| 724 (start != null && start is !int) || | 711 (start != null && start is !int) || |
| 725 (end != null && end is !int)) { | 712 (end != null && end is !int)) { |
| 726 throw new ArgumentError(); | 713 throw new ArgumentError(); |
| 727 } | 714 } |
| 728 end = RangeError.checkValidRange(start, end, buffer.length); | 715 end = RangeError.checkValidRange(start, end, buffer.length); |
| 729 if (end == start) return 0; | 716 if (end == start) return 0; |
| 730 var result = _readInto(_id, buffer, start, end); | 717 var result = _readInto(_id, buffer, start, end); |
| 731 if (result is OSError) { | 718 if (result is OSError) { |
| 732 throw new FileSystemException("readInto failed", path, result); | 719 throw new FileSystemException("readInto failed", path, result); |
| 733 } | 720 } |
| 734 _readCount++; | 721 _resourceInfo.readCount++; |
| 735 _totalRead += result; | 722 _resourceInfo.totalRead += result; |
| 736 return result; | 723 return result; |
| 737 } | 724 } |
| 738 | 725 |
| 739 Future<RandomAccessFile> writeByte(int value) { | 726 Future<RandomAccessFile> writeByte(int value) { |
| 740 if (value is !int) { | 727 if (value is !int) { |
| 741 throw new ArgumentError(value); | 728 throw new ArgumentError(value); |
| 742 } | 729 } |
| 743 return _dispatch(_FILE_WRITE_BYTE, [_id, value]).then((response) { | 730 return _dispatch(_FILE_WRITE_BYTE, [_id, value]).then((response) { |
| 744 if (_isErrorResponse(response)) { | 731 if (_isErrorResponse(response)) { |
| 745 throw _exceptionFromResponse(response, "writeByte failed", path); | 732 throw _exceptionFromResponse(response, "writeByte failed", path); |
| 746 } | 733 } |
| 747 _writeCount++; | 734 _resourceInfo.writeCount++; |
| 748 _totalWritten++; | 735 _resourceInfo.totalWritten++; |
| 749 return this; | 736 return this; |
| 750 }); | 737 }); |
| 751 } | 738 } |
| 752 | 739 |
| 753 external static _writeByte(int id, int value); | 740 external static _writeByte(int id, int value); |
| 754 | 741 |
| 755 int writeByteSync(int value) { | 742 int writeByteSync(int value) { |
| 756 _checkAvailable(); | 743 _checkAvailable(); |
| 757 if (value is !int) { | 744 if (value is !int) { |
| 758 throw new ArgumentError(value); | 745 throw new ArgumentError(value); |
| 759 } | 746 } |
| 760 var result = _writeByte(_id, value); | 747 var result = _writeByte(_id, value); |
| 761 if (result is OSError) { | 748 if (result is OSError) { |
| 762 throw new FileSystemException("writeByte failed", path, result); | 749 throw new FileSystemException("writeByte failed", path, result); |
| 763 } | 750 } |
| 764 _writeCount++; | 751 _resourceInfo.writeCount++; |
| 765 _totalWritten++; | 752 _resourceInfo.totalWritten++; |
| 766 return result; | 753 return result; |
| 767 } | 754 } |
| 768 | 755 |
| 769 Future<RandomAccessFile> writeFrom( | 756 Future<RandomAccessFile> writeFrom( |
| 770 List<int> buffer, [int start = 0, int end]) { | 757 List<int> buffer, [int start = 0, int end]) { |
| 771 if ((buffer is !List) || | 758 if ((buffer is !List) || |
| 772 (start != null && start is !int) || | 759 (start != null && start is !int) || |
| 773 (end != null && end is !int)) { | 760 (end != null && end is !int)) { |
| 774 throw new ArgumentError("Invalid arguments to writeFrom"); | 761 throw new ArgumentError("Invalid arguments to writeFrom"); |
| 775 } | 762 } |
| 776 end = RangeError.checkValidRange(start, end, buffer.length); | 763 end = RangeError.checkValidRange(start, end, buffer.length); |
| 777 if (end == start) return new Future.value(this); | 764 if (end == start) return new Future.value(this); |
| 778 _BufferAndStart result; | 765 _BufferAndStart result; |
| 779 try { | 766 try { |
| 780 result = _ensureFastAndSerializableByteData(buffer, start, end); | 767 result = _ensureFastAndSerializableByteData(buffer, start, end); |
| 781 } catch (e) { | 768 } catch (e) { |
| 782 return new Future.error(e); | 769 return new Future.error(e); |
| 783 } | 770 } |
| 784 | 771 |
| 785 List request = new List(4); | 772 List request = new List(4); |
| 786 request[0] = _id; | 773 request[0] = _id; |
| 787 request[1] = result.buffer; | 774 request[1] = result.buffer; |
| 788 request[2] = result.start; | 775 request[2] = result.start; |
| 789 request[3] = end - (start - result.start); | 776 request[3] = end - (start - result.start); |
| 790 return _dispatch(_FILE_WRITE_FROM, request).then((response) { | 777 return _dispatch(_FILE_WRITE_FROM, request).then((response) { |
| 791 if (_isErrorResponse(response)) { | 778 if (_isErrorResponse(response)) { |
| 792 throw _exceptionFromResponse(response, "writeFrom failed", path); | 779 throw _exceptionFromResponse(response, "writeFrom failed", path); |
| 793 } | 780 } |
| 794 _writeCount++; | 781 _resourceInfo.writeCount++; |
| 795 _totalWritten += end - (start - result.start); | 782 _resourceInfo.totalWritten += end - (start - result.start); |
| 796 return this; | 783 return this; |
| 797 }); | 784 }); |
| 798 } | 785 } |
| 799 | 786 |
| 800 external static _writeFrom(int id, List<int> buffer, int start, int end); | 787 external static _writeFrom(int id, List<int> buffer, int start, int end); |
| 801 | 788 |
| 802 void writeFromSync(List<int> buffer, [int start = 0, int end]) { | 789 void writeFromSync(List<int> buffer, [int start = 0, int end]) { |
| 803 _checkAvailable(); | 790 _checkAvailable(); |
| 804 if (buffer is !List || | 791 if (buffer is !List || |
| 805 (start != null && start is !int) || | 792 (start != null && start is !int) || |
| 806 (end != null && end is !int)) { | 793 (end != null && end is !int)) { |
| 807 throw new ArgumentError("Invalid arguments to writeFromSync"); | 794 throw new ArgumentError("Invalid arguments to writeFromSync"); |
| 808 } | 795 } |
| 809 end = RangeError.checkValidRange(start, end, buffer.length); | 796 end = RangeError.checkValidRange(start, end, buffer.length); |
| 810 if (end == start) return; | 797 if (end == start) return; |
| 811 _BufferAndStart bufferAndStart = | 798 _BufferAndStart bufferAndStart = |
| 812 _ensureFastAndSerializableByteData(buffer, start, end); | 799 _ensureFastAndSerializableByteData(buffer, start, end); |
| 813 var result = _writeFrom(_id, | 800 var result = _writeFrom(_id, |
| 814 bufferAndStart.buffer, | 801 bufferAndStart.buffer, |
| 815 bufferAndStart.start, | 802 bufferAndStart.start, |
| 816 end - (start - bufferAndStart.start)); | 803 end - (start - bufferAndStart.start)); |
| 817 if (result is OSError) { | 804 if (result is OSError) { |
| 818 throw new FileSystemException("writeFrom failed", path, result); | 805 throw new FileSystemException("writeFrom failed", path, result); |
| 819 } | 806 } |
| 820 _writeCount++; | 807 _resourceInfo.writeCount++; |
| 821 _totalWritten += end - (start - bufferAndStart.start); | 808 _resourceInfo.totalWritten += end - (start - bufferAndStart.start); |
| 822 } | 809 } |
| 823 | 810 |
| 824 Future<RandomAccessFile> writeString(String string, | 811 Future<RandomAccessFile> writeString(String string, |
| 825 {Encoding encoding: UTF8}) { | 812 {Encoding encoding: UTF8}) { |
| 826 if (encoding is! Encoding) { | 813 if (encoding is! Encoding) { |
| 827 throw new ArgumentError(encoding); | 814 throw new ArgumentError(encoding); |
| 828 } | 815 } |
| 829 var data = encoding.encode(string); | 816 var data = encoding.encode(string); |
| 830 return writeFrom(data, 0, data.length); | 817 return writeFrom(data, 0, data.length); |
| 831 } | 818 } |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1042 void _checkAvailable() { | 1029 void _checkAvailable() { |
| 1043 if (_asyncDispatched) { | 1030 if (_asyncDispatched) { |
| 1044 throw new FileSystemException("An async operation is currently pending", | 1031 throw new FileSystemException("An async operation is currently pending", |
| 1045 path); | 1032 path); |
| 1046 } | 1033 } |
| 1047 if (closed) { | 1034 if (closed) { |
| 1048 throw new FileSystemException("File closed", path); | 1035 throw new FileSystemException("File closed", path); |
| 1049 } | 1036 } |
| 1050 } | 1037 } |
| 1051 } | 1038 } |
| OLD | NEW |