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 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 extends Object with _ServiceObject | 560 extends Object with _ServiceObject |
561 implements RandomAccessFile { | 561 implements RandomAccessFile { |
562 // Use default Map so we keep order. | 562 // Use default Map so we keep order. |
563 static Map<int, _RandomAccessFile> _files = new Map<int, _RandomAccessFile>(); | 563 static Map<int, _RandomAccessFile> _files = new Map<int, _RandomAccessFile>(); |
564 | 564 |
565 final String path; | 565 final String path; |
566 int _id; | 566 int _id; |
567 bool _asyncDispatched = false; | 567 bool _asyncDispatched = false; |
568 SendPort _fileService; | 568 SendPort _fileService; |
569 | 569 |
| 570 int _totalRead = 0; |
| 571 int _totalWritten = 0; |
| 572 int _readCount = 0; |
| 573 int _writeCount = 0; |
| 574 |
570 | 575 |
571 _RandomAccessFile(this._id, this.path) { | 576 _RandomAccessFile(this._id, this.path) { |
572 _files[_serviceId] = this; | 577 _files[_serviceId] = this; |
573 } | 578 } |
574 | 579 |
575 String get _serviceTypePath => 'io/file/randomaccessfiles'; | 580 String get _serviceTypePath => 'io/file/randomaccessfiles'; |
576 String get _serviceTypeName => 'RandomAccessFile'; | 581 String get _serviceTypeName => 'RandomAccessFile'; |
577 | 582 |
578 Map _toJSON(bool ref) { | 583 Map _toJSON(bool ref) { |
579 var r = { | 584 var r = { |
580 'id': _servicePath, | 585 'id': _servicePath, |
581 'type': _serviceType(ref), | 586 'type': _serviceType(ref), |
582 'name': '$path', | 587 'name': '$path', |
583 'user_name': '$path', | 588 'user_name': '$path', |
584 }; | 589 }; |
585 if (ref) { | 590 if (ref) { |
586 return r; | 591 return r; |
587 } | 592 } |
588 r['asyncDispatched'] = _asyncDispatched; | 593 r['asyncDispatched'] = _asyncDispatched; |
589 r['fd'] = _getFD(_id); | 594 r['fd'] = _getFD(_id); |
| 595 r['totalRead'] = _totalRead; |
| 596 r['totalWritten'] = _totalWritten; |
| 597 r['readCount'] = _totalWritten; |
| 598 r['writeCount'] = _writeCount; |
590 return r; | 599 return r; |
591 } | 600 } |
592 | 601 |
593 void _maybePerformCleanup() { | 602 void _maybePerformCleanup() { |
594 if (closed) { | 603 if (closed) { |
595 _files.remove(_serviceId); | 604 _files.remove(_serviceId); |
596 } | 605 } |
597 } | 606 } |
598 | 607 |
599 external static int _getFD(int id); | 608 external static int _getFD(int id); |
(...skipping 20 matching lines...) Expand all Loading... |
620 } | 629 } |
621 _id = id; | 630 _id = id; |
622 _maybePerformCleanup(); | 631 _maybePerformCleanup(); |
623 } | 632 } |
624 | 633 |
625 Future<int> readByte() { | 634 Future<int> readByte() { |
626 return _dispatch(_FILE_READ_BYTE, [_id]).then((response) { | 635 return _dispatch(_FILE_READ_BYTE, [_id]).then((response) { |
627 if (_isErrorResponse(response)) { | 636 if (_isErrorResponse(response)) { |
628 throw _exceptionFromResponse(response, "readByte failed", path); | 637 throw _exceptionFromResponse(response, "readByte failed", path); |
629 } | 638 } |
| 639 _readCount++; |
| 640 _totalRead++; |
630 return response; | 641 return response; |
631 }); | 642 }); |
632 } | 643 } |
633 | 644 |
634 external static _readByte(int id); | 645 external static _readByte(int id); |
635 | 646 |
636 int readByteSync() { | 647 int readByteSync() { |
637 _checkAvailable(); | 648 _checkAvailable(); |
638 var result = _readByte(_id); | 649 var result = _readByte(_id); |
639 if (result is OSError) { | 650 if (result is OSError) { |
640 throw new FileSystemException("readByte failed", path, result); | 651 throw new FileSystemException("readByte failed", path, result); |
641 } | 652 } |
| 653 _readCount++; |
| 654 _totalRead++; |
642 return result; | 655 return result; |
643 } | 656 } |
644 | 657 |
645 Future<List<int>> read(int bytes) { | 658 Future<List<int>> read(int bytes) { |
646 if (bytes is !int) { | 659 if (bytes is !int) { |
647 throw new ArgumentError(bytes); | 660 throw new ArgumentError(bytes); |
648 } | 661 } |
649 return _dispatch(_FILE_READ, [_id, bytes]).then((response) { | 662 return _dispatch(_FILE_READ, [_id, bytes]).then((response) { |
650 if (_isErrorResponse(response)) { | 663 if (_isErrorResponse(response)) { |
651 throw _exceptionFromResponse(response, "read failed", path); | 664 throw _exceptionFromResponse(response, "read failed", path); |
652 } | 665 } |
| 666 _readCount++; |
| 667 _totalRead += response[1].length; |
653 return response[1]; | 668 return response[1]; |
654 }); | 669 }); |
655 } | 670 } |
656 | 671 |
657 external static _read(int id, int bytes); | 672 external static _read(int id, int bytes); |
658 | 673 |
659 List<int> readSync(int bytes) { | 674 List<int> readSync(int bytes) { |
660 _checkAvailable(); | 675 _checkAvailable(); |
661 if (bytes is !int) { | 676 if (bytes is !int) { |
662 throw new ArgumentError(bytes); | 677 throw new ArgumentError(bytes); |
663 } | 678 } |
664 var result = _read(_id, bytes); | 679 var result = _read(_id, bytes); |
665 if (result is OSError) { | 680 if (result is OSError) { |
666 throw new FileSystemException("readSync failed", path, result); | 681 throw new FileSystemException("readSync failed", path, result); |
667 } | 682 } |
| 683 _readCount++; |
| 684 _totalRead += result.length; |
668 return result; | 685 return result; |
669 } | 686 } |
670 | 687 |
671 Future<int> readInto(List<int> buffer, [int start, int end]) { | 688 Future<int> readInto(List<int> buffer, [int start, int end]) { |
672 if (buffer is !List || | 689 if (buffer is !List || |
673 (start != null && start is !int) || | 690 (start != null && start is !int) || |
674 (end != null && end is !int)) { | 691 (end != null && end is !int)) { |
675 throw new ArgumentError(); | 692 throw new ArgumentError(); |
676 } | 693 } |
677 if (start == null) start = 0; | 694 if (start == null) start = 0; |
678 if (end == null) end = buffer.length; | 695 if (end == null) end = buffer.length; |
679 int length = end - start; | 696 int length = end - start; |
680 return _dispatch(_FILE_READ_INTO, [_id, length]).then((response) { | 697 return _dispatch(_FILE_READ_INTO, [_id, length]).then((response) { |
681 if (_isErrorResponse(response)) { | 698 if (_isErrorResponse(response)) { |
682 throw _exceptionFromResponse(response, "readInto failed", path); | 699 throw _exceptionFromResponse(response, "readInto failed", path); |
683 } | 700 } |
684 var read = response[1]; | 701 var read = response[1]; |
685 var data = response[2]; | 702 var data = response[2]; |
686 buffer.setRange(start, start + read, data); | 703 buffer.setRange(start, start + read, data); |
| 704 _readCount++; |
| 705 _totalRead += read; |
687 return read; | 706 return read; |
688 }); | 707 }); |
689 } | 708 } |
690 | 709 |
691 static void _checkReadWriteListArguments(int length, int start, int end) { | 710 static void _checkReadWriteListArguments(int length, int start, int end) { |
692 if (start < 0) throw new RangeError.value(start); | 711 if (start < 0) throw new RangeError.value(start); |
693 if (end < start) throw new RangeError.value(end); | 712 if (end < start) throw new RangeError.value(end); |
694 if (end > length) { | 713 if (end > length) { |
695 throw new RangeError.value(end); | 714 throw new RangeError.value(end); |
696 } | 715 } |
697 } | 716 } |
698 | 717 |
699 external static _readInto(int id, List<int> buffer, int start, int end); | 718 external static _readInto(int id, List<int> buffer, int start, int end); |
700 | 719 |
701 int readIntoSync(List<int> buffer, [int start, int end]) { | 720 int readIntoSync(List<int> buffer, [int start, int end]) { |
702 _checkAvailable(); | 721 _checkAvailable(); |
703 if (buffer is !List || | 722 if (buffer is !List || |
704 (start != null && start is !int) || | 723 (start != null && start is !int) || |
705 (end != null && end is !int)) { | 724 (end != null && end is !int)) { |
706 throw new ArgumentError(); | 725 throw new ArgumentError(); |
707 } | 726 } |
708 if (start == null) start = 0; | 727 if (start == null) start = 0; |
709 if (end == null) end = buffer.length; | 728 if (end == null) end = buffer.length; |
710 if (end == start) return 0; | 729 if (end == start) return 0; |
711 _checkReadWriteListArguments(buffer.length, start, end); | 730 _checkReadWriteListArguments(buffer.length, start, end); |
712 var result = _readInto(_id, buffer, start, end); | 731 var result = _readInto(_id, buffer, start, end); |
713 if (result is OSError) { | 732 if (result is OSError) { |
714 throw new FileSystemException("readInto failed", path, result); | 733 throw new FileSystemException("readInto failed", path, result); |
715 } | 734 } |
| 735 _readCount++; |
| 736 _totalRead += result; |
716 return result; | 737 return result; |
717 } | 738 } |
718 | 739 |
719 Future<RandomAccessFile> writeByte(int value) { | 740 Future<RandomAccessFile> writeByte(int value) { |
720 if (value is !int) { | 741 if (value is !int) { |
721 throw new ArgumentError(value); | 742 throw new ArgumentError(value); |
722 } | 743 } |
723 return _dispatch(_FILE_WRITE_BYTE, [_id, value]).then((response) { | 744 return _dispatch(_FILE_WRITE_BYTE, [_id, value]).then((response) { |
724 if (_isErrorResponse(response)) { | 745 if (_isErrorResponse(response)) { |
725 throw _exceptionFromResponse(response, "writeByte failed", path); | 746 throw _exceptionFromResponse(response, "writeByte failed", path); |
726 } | 747 } |
| 748 _writeCount++; |
| 749 _totalWritten++; |
727 return this; | 750 return this; |
728 }); | 751 }); |
729 } | 752 } |
730 | 753 |
731 external static _writeByte(int id, int value); | 754 external static _writeByte(int id, int value); |
732 | 755 |
733 int writeByteSync(int value) { | 756 int writeByteSync(int value) { |
734 _checkAvailable(); | 757 _checkAvailable(); |
735 if (value is !int) { | 758 if (value is !int) { |
736 throw new ArgumentError(value); | 759 throw new ArgumentError(value); |
737 } | 760 } |
738 var result = _writeByte(_id, value); | 761 var result = _writeByte(_id, value); |
739 if (result is OSError) { | 762 if (result is OSError) { |
740 throw new FileSystemException("writeByte failed", path, result); | 763 throw new FileSystemException("writeByte failed", path, result); |
741 } | 764 } |
| 765 _writeCount++; |
| 766 _totalWritten++; |
742 return result; | 767 return result; |
743 } | 768 } |
744 | 769 |
745 Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]) { | 770 Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]) { |
746 if ((buffer is !List && buffer is !ByteData) || | 771 if ((buffer is !List && buffer is !ByteData) || |
747 (start != null && start is !int) || | 772 (start != null && start is !int) || |
748 (end != null && end is !int)) { | 773 (end != null && end is !int)) { |
749 throw new ArgumentError("Invalid arguments to writeFrom"); | 774 throw new ArgumentError("Invalid arguments to writeFrom"); |
750 } | 775 } |
751 | 776 |
752 _BufferAndStart result; | 777 _BufferAndStart result; |
753 try { | 778 try { |
754 result = _ensureFastAndSerializableByteData(buffer, start, end); | 779 result = _ensureFastAndSerializableByteData(buffer, start, end); |
755 } catch (e) { | 780 } catch (e) { |
756 return new Future.error(e); | 781 return new Future.error(e); |
757 } | 782 } |
758 | 783 |
759 List request = new List(4); | 784 List request = new List(4); |
760 request[0] = _id; | 785 request[0] = _id; |
761 request[1] = result.buffer; | 786 request[1] = result.buffer; |
762 request[2] = result.start; | 787 request[2] = result.start; |
763 request[3] = end - (start - result.start); | 788 request[3] = end - (start - result.start); |
764 return _dispatch(_FILE_WRITE_FROM, request).then((response) { | 789 return _dispatch(_FILE_WRITE_FROM, request).then((response) { |
765 if (_isErrorResponse(response)) { | 790 if (_isErrorResponse(response)) { |
766 throw _exceptionFromResponse(response, "writeFrom failed", path); | 791 throw _exceptionFromResponse(response, "writeFrom failed", path); |
767 } | 792 } |
| 793 _writeCount++; |
| 794 _totalWritten += end - (start - result.start); |
768 return this; | 795 return this; |
769 }); | 796 }); |
770 } | 797 } |
771 | 798 |
772 external static _writeFrom(int id, List<int> buffer, int start, int end); | 799 external static _writeFrom(int id, List<int> buffer, int start, int end); |
773 | 800 |
774 void writeFromSync(List<int> buffer, [int start, int end]) { | 801 void writeFromSync(List<int> buffer, [int start, int end]) { |
775 _checkAvailable(); | 802 _checkAvailable(); |
776 if (buffer is !List || | 803 if (buffer is !List || |
777 (start != null && start is !int) || | 804 (start != null && start is !int) || |
778 (end != null && end is !int)) { | 805 (end != null && end is !int)) { |
779 throw new ArgumentError("Invalid arguments to writeFromSync"); | 806 throw new ArgumentError("Invalid arguments to writeFromSync"); |
780 } | 807 } |
781 if (start == null) start = 0; | 808 if (start == null) start = 0; |
782 if (end == null) end = buffer.length; | 809 if (end == null) end = buffer.length; |
783 if (end == start) return; | 810 if (end == start) return; |
784 _checkReadWriteListArguments(buffer.length, start, end); | 811 _checkReadWriteListArguments(buffer.length, start, end); |
785 _BufferAndStart bufferAndStart = | 812 _BufferAndStart bufferAndStart = |
786 _ensureFastAndSerializableByteData(buffer, start, end); | 813 _ensureFastAndSerializableByteData(buffer, start, end); |
787 var result = _writeFrom(_id, | 814 var result = _writeFrom(_id, |
788 bufferAndStart.buffer, | 815 bufferAndStart.buffer, |
789 bufferAndStart.start, | 816 bufferAndStart.start, |
790 end - (start - bufferAndStart.start)); | 817 end - (start - bufferAndStart.start)); |
791 if (result is OSError) { | 818 if (result is OSError) { |
792 throw new FileSystemException("writeFrom failed", path, result); | 819 throw new FileSystemException("writeFrom failed", path, result); |
793 } | 820 } |
| 821 _writeCount++; |
| 822 _totalWritten += end - (start - bufferAndStart.start); |
794 } | 823 } |
795 | 824 |
796 Future<RandomAccessFile> writeString(String string, | 825 Future<RandomAccessFile> writeString(String string, |
797 {Encoding encoding: UTF8}) { | 826 {Encoding encoding: UTF8}) { |
798 if (encoding is! Encoding) { | 827 if (encoding is! Encoding) { |
799 throw new ArgumentError(encoding); | 828 throw new ArgumentError(encoding); |
800 } | 829 } |
801 var data = encoding.encode(string); | 830 var data = encoding.encode(string); |
802 return writeFrom(data, 0, data.length); | 831 return writeFrom(data, 0, data.length); |
803 } | 832 } |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 void _checkAvailable() { | 964 void _checkAvailable() { |
936 if (_asyncDispatched) { | 965 if (_asyncDispatched) { |
937 throw new FileSystemException("An async operation is currently pending", | 966 throw new FileSystemException("An async operation is currently pending", |
938 path); | 967 path); |
939 } | 968 } |
940 if (closed) { | 969 if (closed) { |
941 throw new FileSystemException("File closed", path); | 970 throw new FileSystemException("File closed", path); |
942 } | 971 } |
943 } | 972 } |
944 } | 973 } |
OLD | NEW |