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 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 external static _directory(String path); | 331 external static _directory(String path); |
332 | 332 |
333 Directory directorySync() { | 333 Directory directorySync() { |
334 var result = _directory(path); | 334 var result = _directory(path); |
335 throwIfError(result, "Cannot retrieve directory for file '$_path'"); | 335 throwIfError(result, "Cannot retrieve directory for file '$_path'"); |
336 return new Directory(result); | 336 return new Directory(result); |
337 } | 337 } |
338 | 338 |
339 Future<RandomAccessFile> open({FileMode mode: FileMode.READ}) { | 339 Future<RandomAccessFile> open({FileMode mode: FileMode.READ}) { |
340 _ensureFileService(); | 340 _ensureFileService(); |
341 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | |
342 if (mode != FileMode.READ && | 341 if (mode != FileMode.READ && |
343 mode != FileMode.WRITE && | 342 mode != FileMode.WRITE && |
344 mode != FileMode.APPEND) { | 343 mode != FileMode.APPEND) { |
345 Timer.run(() { | 344 return new Future.error(new ArgumentError()); |
346 completer.completeError(new ArgumentError()); | |
347 }); | |
348 return completer.future; | |
349 } | 345 } |
350 List request = new List(3); | 346 List request = new List(3); |
351 request[0] = _OPEN_REQUEST; | 347 request[0] = _OPEN_REQUEST; |
352 request[1] = _path; | 348 request[1] = _path; |
353 request[2] = mode._mode; // Direct int value for serialization. | 349 request[2] = mode._mode; // Direct int value for serialization. |
354 return _fileService.call(request).then((response) { | 350 return _fileService.call(request).then((response) { |
355 if (_isErrorResponse(response)) { | 351 if (_isErrorResponse(response)) { |
356 throw _exceptionFromResponse(response, "Cannot open file '$_path'"); | 352 throw _exceptionFromResponse(response, "Cannot open file '$_path'"); |
357 } | 353 } |
358 return new _RandomAccessFile(response, _path); | 354 return new _RandomAccessFile(response, _path); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 .transform(new StringDecoder(encoding)) | 512 .transform(new StringDecoder(encoding)) |
517 .transform(new LineTransformer()) | 513 .transform(new LineTransformer()) |
518 .listen((line) => list.add(line)); | 514 .listen((line) => list.add(line)); |
519 controller.add(bytes); | 515 controller.add(bytes); |
520 controller.close(); | 516 controller.close(); |
521 return list; | 517 return list; |
522 } | 518 } |
523 | 519 |
524 Future<List<String>> readAsLines({Encoding encoding: Encoding.UTF_8}) { | 520 Future<List<String>> readAsLines({Encoding encoding: Encoding.UTF_8}) { |
525 _ensureFileService(); | 521 _ensureFileService(); |
526 Completer<List<String>> completer = new Completer<List<String>>(); | |
527 return readAsBytes().then((bytes) { | 522 return readAsBytes().then((bytes) { |
528 return _decodeLines(bytes, encoding); | 523 return _decodeLines(bytes, encoding); |
529 }); | 524 }); |
530 } | 525 } |
531 | 526 |
532 List<String> readAsLinesSync({Encoding encoding: Encoding.UTF_8}) { | 527 List<String> readAsLinesSync({Encoding encoding: Encoding.UTF_8}) { |
533 return _decodeLines(readAsBytesSync(), encoding); | 528 return _decodeLines(readAsBytesSync(), encoding); |
534 } | 529 } |
535 | 530 |
536 Future<File> writeAsBytes(List<int> bytes, | 531 Future<File> writeAsBytes(List<int> bytes, |
(...skipping 13 matching lines...) Expand all Loading... |
550 opened.writeFromSync(bytes, 0, bytes.length); | 545 opened.writeFromSync(bytes, 0, bytes.length); |
551 opened.closeSync(); | 546 opened.closeSync(); |
552 } | 547 } |
553 | 548 |
554 Future<File> writeAsString(String contents, | 549 Future<File> writeAsString(String contents, |
555 {FileMode mode: FileMode.WRITE, | 550 {FileMode mode: FileMode.WRITE, |
556 Encoding encoding: Encoding.UTF_8}) { | 551 Encoding encoding: Encoding.UTF_8}) { |
557 try { | 552 try { |
558 return writeAsBytes(_encodeString(contents, encoding), mode: mode); | 553 return writeAsBytes(_encodeString(contents, encoding), mode: mode); |
559 } catch (e) { | 554 } catch (e) { |
560 var completer = new Completer(); | 555 return new Future.error(e); |
561 Timer.run(() => completer.completeError(e)); | |
562 return completer.future; | |
563 } | 556 } |
564 } | 557 } |
565 | 558 |
566 void writeAsStringSync(String contents, | 559 void writeAsStringSync(String contents, |
567 {FileMode mode: FileMode.WRITE, | 560 {FileMode mode: FileMode.WRITE, |
568 Encoding encoding: Encoding.UTF_8}) { | 561 Encoding encoding: Encoding.UTF_8}) { |
569 writeAsBytesSync(_encodeString(contents, encoding), mode: mode); | 562 writeAsBytesSync(_encodeString(contents, encoding), mode: mode); |
570 } | 563 } |
571 | 564 |
572 String get path => _path; | 565 String get path => _path; |
(...skipping 15 matching lines...) Expand all Loading... |
588 final String _path; | 581 final String _path; |
589 | 582 |
590 SendPort _fileService; | 583 SendPort _fileService; |
591 } | 584 } |
592 | 585 |
593 | 586 |
594 class _RandomAccessFile implements RandomAccessFile { | 587 class _RandomAccessFile implements RandomAccessFile { |
595 _RandomAccessFile(int this._id, String this._path); | 588 _RandomAccessFile(int this._id, String this._path); |
596 | 589 |
597 Future<RandomAccessFile> close() { | 590 Future<RandomAccessFile> close() { |
598 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 591 if (closed) return _closedException(); |
599 if (closed) return _completeWithClosedException(completer); | |
600 _ensureFileService(); | 592 _ensureFileService(); |
601 List request = new List(2); | 593 List request = new List(2); |
602 request[0] = _CLOSE_REQUEST; | 594 request[0] = _CLOSE_REQUEST; |
603 request[1] = _id; | 595 request[1] = _id; |
604 // Set the id_ to 0 (NULL) to ensure the no more async requests | 596 // Set the id_ to 0 (NULL) to ensure the no more async requests |
605 // can be issued for this file. | 597 // can be issued for this file. |
606 _id = 0; | 598 _id = 0; |
607 return _fileService.call(request).then((result) { | 599 return _fileService.call(request).then((result) { |
608 if (result != -1) { | 600 if (result != -1) { |
609 _id = result; | 601 _id = result; |
(...skipping 10 matching lines...) Expand all Loading... |
620 _checkNotClosed(); | 612 _checkNotClosed(); |
621 var id = _close(_id); | 613 var id = _close(_id); |
622 if (id == -1) { | 614 if (id == -1) { |
623 throw new FileIOException("Cannot close file '$_path'"); | 615 throw new FileIOException("Cannot close file '$_path'"); |
624 } | 616 } |
625 _id = id; | 617 _id = id; |
626 } | 618 } |
627 | 619 |
628 Future<int> readByte() { | 620 Future<int> readByte() { |
629 _ensureFileService(); | 621 _ensureFileService(); |
630 Completer<int> completer = new Completer<int>(); | 622 if (closed) return _closedException(); |
631 if (closed) return _completeWithClosedException(completer); | |
632 List request = new List(2); | 623 List request = new List(2); |
633 request[0] = _READ_BYTE_REQUEST; | 624 request[0] = _READ_BYTE_REQUEST; |
634 request[1] = _id; | 625 request[1] = _id; |
635 return _fileService.call(request).then((response) { | 626 return _fileService.call(request).then((response) { |
636 if (_isErrorResponse(response)) { | 627 if (_isErrorResponse(response)) { |
637 throw _exceptionFromResponse(response, | 628 throw _exceptionFromResponse(response, |
638 "readByte failed for file '$_path'"); | 629 "readByte failed for file '$_path'"); |
639 } | 630 } |
640 return response; | 631 return response; |
641 }); | 632 }); |
642 } | 633 } |
643 | 634 |
644 external static _readByte(int id); | 635 external static _readByte(int id); |
645 | 636 |
646 int readByteSync() { | 637 int readByteSync() { |
647 _checkNotClosed(); | 638 _checkNotClosed(); |
648 var result = _readByte(_id); | 639 var result = _readByte(_id); |
649 if (result is OSError) { | 640 if (result is OSError) { |
650 throw new FileIOException("readByte failed for file '$_path'", result); | 641 throw new FileIOException("readByte failed for file '$_path'", result); |
651 } | 642 } |
652 return result; | 643 return result; |
653 } | 644 } |
654 | 645 |
655 Future<List<int>> read(int bytes) { | 646 Future<List<int>> read(int bytes) { |
656 _ensureFileService(); | 647 _ensureFileService(); |
657 Completer<List<int>> completer = new Completer<List<int>>(); | |
658 if (bytes is !int) { | 648 if (bytes is !int) { |
659 // Complete asynchronously so the user has a chance to setup | 649 return new Future.error(new FileIOException( |
660 // handlers without getting exceptions when registering the | 650 "Invalid arguments to read for file '$_path'")); |
661 // then handler. | 651 } |
662 Timer.run(() { | 652 if (closed) return _closedException(); |
663 completer.completeError(new FileIOException( | |
664 "Invalid arguments to read for file '$_path'")); | |
665 }); | |
666 return completer.future; | |
667 }; | |
668 if (closed) return _completeWithClosedException(completer); | |
669 List request = new List(3); | 653 List request = new List(3); |
670 request[0] = _READ_REQUEST; | 654 request[0] = _READ_REQUEST; |
671 request[1] = _id; | 655 request[1] = _id; |
672 request[2] = bytes; | 656 request[2] = bytes; |
673 return _fileService.call(request).then((response) { | 657 return _fileService.call(request).then((response) { |
674 if (_isErrorResponse(response)) { | 658 if (_isErrorResponse(response)) { |
675 throw _exceptionFromResponse(response, | 659 throw _exceptionFromResponse(response, |
676 "read failed for file '$_path'"); | 660 "read failed for file '$_path'"); |
677 } | 661 } |
678 return response[1]; | 662 return response[1]; |
(...skipping 17 matching lines...) Expand all Loading... |
696 } | 680 } |
697 | 681 |
698 Future<int> readInto(List<int> buffer, [int start, int end]) { | 682 Future<int> readInto(List<int> buffer, [int start, int end]) { |
699 _ensureFileService(); | 683 _ensureFileService(); |
700 if (buffer is !List || | 684 if (buffer is !List || |
701 (start != null && start is !int) || | 685 (start != null && start is !int) || |
702 (end != null && end is !int)) { | 686 (end != null && end is !int)) { |
703 return new Future.error(new FileIOException( | 687 return new Future.error(new FileIOException( |
704 "Invalid arguments to readInto for file '$_path'")); | 688 "Invalid arguments to readInto for file '$_path'")); |
705 }; | 689 }; |
706 Completer<int> completer = new Completer<int>(); | 690 if (closed) return _closedException(); |
707 if (closed) return _completeWithClosedException(completer); | |
708 List request = new List(3); | 691 List request = new List(3); |
709 if (start == null) start = 0; | 692 if (start == null) start = 0; |
710 if (end == null) end = buffer.length; | 693 if (end == null) end = buffer.length; |
711 request[0] = _READ_LIST_REQUEST; | 694 request[0] = _READ_LIST_REQUEST; |
712 request[1] = _id; | 695 request[1] = _id; |
713 request[2] = end - start; | 696 request[2] = end - start; |
714 return _fileService.call(request).then((response) { | 697 return _fileService.call(request).then((response) { |
715 if (_isErrorResponse(response)) { | 698 if (_isErrorResponse(response)) { |
716 throw _exceptionFromResponse(response, | 699 throw _exceptionFromResponse(response, |
717 "readInto failed for file '$_path'"); | 700 "readInto failed for file '$_path'"); |
(...skipping 30 matching lines...) Expand all Loading... |
748 var result = _readInto(_id, buffer, start, end); | 731 var result = _readInto(_id, buffer, start, end); |
749 if (result is OSError) { | 732 if (result is OSError) { |
750 throw new FileIOException("readInto failed for file '$_path'", | 733 throw new FileIOException("readInto failed for file '$_path'", |
751 result); | 734 result); |
752 } | 735 } |
753 return result; | 736 return result; |
754 } | 737 } |
755 | 738 |
756 Future<RandomAccessFile> writeByte(int value) { | 739 Future<RandomAccessFile> writeByte(int value) { |
757 _ensureFileService(); | 740 _ensureFileService(); |
758 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | |
759 if (value is !int) { | 741 if (value is !int) { |
760 // Complete asynchronously so the user has a chance to setup | 742 return new Future.error(new FileIOException( |
761 // handlers without getting exceptions when registering the | 743 "Invalid argument to writeByte for file '$_path'")); |
762 // then handler. | |
763 Timer.run(() { | |
764 completer.completeError(new FileIOException( | |
765 "Invalid argument to writeByte for file '$_path'")); | |
766 }); | |
767 return completer.future; | |
768 } | 744 } |
769 if (closed) return _completeWithClosedException(completer); | 745 if (closed) return _closedException(); |
770 List request = new List(3); | 746 List request = new List(3); |
771 request[0] = _WRITE_BYTE_REQUEST; | 747 request[0] = _WRITE_BYTE_REQUEST; |
772 request[1] = _id; | 748 request[1] = _id; |
773 request[2] = value; | 749 request[2] = value; |
774 return _fileService.call(request).then((response) { | 750 return _fileService.call(request).then((response) { |
775 if (_isErrorResponse(response)) { | 751 if (_isErrorResponse(response)) { |
776 throw _exceptionFromResponse(response, | 752 throw _exceptionFromResponse(response, |
777 "writeByte failed for file '$_path'"); | 753 "writeByte failed for file '$_path'"); |
778 } | 754 } |
779 return this; | 755 return this; |
(...skipping 17 matching lines...) Expand all Loading... |
797 } | 773 } |
798 | 774 |
799 Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]) { | 775 Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]) { |
800 _ensureFileService(); | 776 _ensureFileService(); |
801 if ((buffer is !List && buffer is !ByteData) || | 777 if ((buffer is !List && buffer is !ByteData) || |
802 (start != null && start is !int) || | 778 (start != null && start is !int) || |
803 (end != null && end is !int)) { | 779 (end != null && end is !int)) { |
804 return new Future.error(new FileIOException( | 780 return new Future.error(new FileIOException( |
805 "Invalid arguments to writeFrom for file '$_path'")); | 781 "Invalid arguments to writeFrom for file '$_path'")); |
806 } | 782 } |
807 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | |
808 | 783 |
809 if (closed) return _completeWithClosedException(completer); | 784 if (closed) return _closedException(); |
810 | 785 |
811 _BufferAndStart result; | 786 _BufferAndStart result; |
812 try { | 787 try { |
813 result = _ensureFastAndSerializableBuffer(buffer, start, end); | 788 result = _ensureFastAndSerializableBuffer(buffer, start, end); |
814 } catch (e) { | 789 } catch (e) { |
815 return new Future.error(e); | 790 return new Future.error(e); |
816 } | 791 } |
817 | 792 |
818 List request = new List(5); | 793 List request = new List(5); |
819 request[0] = _WRITE_LIST_REQUEST; | 794 request[0] = _WRITE_LIST_REQUEST; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 bufferAndStart.start, | 826 bufferAndStart.start, |
852 end - (start - bufferAndStart.start)); | 827 end - (start - bufferAndStart.start)); |
853 if (result is OSError) { | 828 if (result is OSError) { |
854 throw new FileIOException("writeFrom failed for file '$_path'", result); | 829 throw new FileIOException("writeFrom failed for file '$_path'", result); |
855 } | 830 } |
856 } | 831 } |
857 | 832 |
858 Future<RandomAccessFile> writeString(String string, | 833 Future<RandomAccessFile> writeString(String string, |
859 {Encoding encoding: Encoding.UTF_8}) { | 834 {Encoding encoding: Encoding.UTF_8}) { |
860 if (encoding is! Encoding) { | 835 if (encoding is! Encoding) { |
861 var completer = new Completer(); | 836 return new Future.error(new FileIOException( |
862 Timer.run(() { | 837 "Invalid encoding in writeString: $encoding")); |
863 completer.completeError(new FileIOException( | |
864 "Invalid encoding in writeString: $encoding")); | |
865 }); | |
866 return completer.future; | |
867 } | 838 } |
868 var data = _encodeString(string, encoding); | 839 var data = _encodeString(string, encoding); |
869 return writeFrom(data, 0, data.length); | 840 return writeFrom(data, 0, data.length); |
870 } | 841 } |
871 | 842 |
872 void writeStringSync(String string, {Encoding encoding: Encoding.UTF_8}) { | 843 void writeStringSync(String string, {Encoding encoding: Encoding.UTF_8}) { |
873 if (encoding is! Encoding) { | 844 if (encoding is! Encoding) { |
874 throw new FileIOException( | 845 throw new FileIOException( |
875 "Invalid encoding in writeStringSync: $encoding"); | 846 "Invalid encoding in writeStringSync: $encoding"); |
876 } | 847 } |
877 var data = _encodeString(string, encoding); | 848 var data = _encodeString(string, encoding); |
878 writeFromSync(data, 0, data.length); | 849 writeFromSync(data, 0, data.length); |
879 } | 850 } |
880 | 851 |
881 Future<int> position() { | 852 Future<int> position() { |
882 _ensureFileService(); | 853 _ensureFileService(); |
883 Completer<int> completer = new Completer<int>(); | 854 if (closed) return _closedException(); |
884 if (closed) return _completeWithClosedException(completer); | |
885 List request = new List(2); | 855 List request = new List(2); |
886 request[0] = _POSITION_REQUEST; | 856 request[0] = _POSITION_REQUEST; |
887 request[1] = _id; | 857 request[1] = _id; |
888 return _fileService.call(request).then((response) { | 858 return _fileService.call(request).then((response) { |
889 if (_isErrorResponse(response)) { | 859 if (_isErrorResponse(response)) { |
890 throw _exceptionFromResponse(response, | 860 throw _exceptionFromResponse(response, |
891 "position failed for file '$_path'"); | 861 "position failed for file '$_path'"); |
892 } | 862 } |
893 return response; | 863 return response; |
894 }); | 864 }); |
895 } | 865 } |
896 | 866 |
897 external static _position(int id); | 867 external static _position(int id); |
898 | 868 |
899 int positionSync() { | 869 int positionSync() { |
900 _checkNotClosed(); | 870 _checkNotClosed(); |
901 var result = _position(_id); | 871 var result = _position(_id); |
902 if (result is OSError) { | 872 if (result is OSError) { |
903 throw new FileIOException("position failed for file '$_path'", result); | 873 throw new FileIOException("position failed for file '$_path'", result); |
904 } | 874 } |
905 return result; | 875 return result; |
906 } | 876 } |
907 | 877 |
908 Future<RandomAccessFile> setPosition(int position) { | 878 Future<RandomAccessFile> setPosition(int position) { |
909 _ensureFileService(); | 879 _ensureFileService(); |
910 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 880 if (closed) return _closedException(); |
911 if (closed) return _completeWithClosedException(completer); | |
912 List request = new List(3); | 881 List request = new List(3); |
913 request[0] = _SET_POSITION_REQUEST; | 882 request[0] = _SET_POSITION_REQUEST; |
914 request[1] = _id; | 883 request[1] = _id; |
915 request[2] = position; | 884 request[2] = position; |
916 return _fileService.call(request).then((response) { | 885 return _fileService.call(request).then((response) { |
917 if (_isErrorResponse(response)) { | 886 if (_isErrorResponse(response)) { |
918 throw _exceptionFromResponse(response, | 887 throw _exceptionFromResponse(response, |
919 "setPosition failed for file '$_path'"); | 888 "setPosition failed for file '$_path'"); |
920 } | 889 } |
921 return this; | 890 return this; |
922 }); | 891 }); |
923 } | 892 } |
924 | 893 |
925 external static _setPosition(int id, int position); | 894 external static _setPosition(int id, int position); |
926 | 895 |
927 void setPositionSync(int position) { | 896 void setPositionSync(int position) { |
928 _checkNotClosed(); | 897 _checkNotClosed(); |
929 var result = _setPosition(_id, position); | 898 var result = _setPosition(_id, position); |
930 if (result is OSError) { | 899 if (result is OSError) { |
931 throw new FileIOException("setPosition failed for file '$_path'", result); | 900 throw new FileIOException("setPosition failed for file '$_path'", result); |
932 } | 901 } |
933 } | 902 } |
934 | 903 |
935 Future<RandomAccessFile> truncate(int length) { | 904 Future<RandomAccessFile> truncate(int length) { |
936 _ensureFileService(); | 905 _ensureFileService(); |
937 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 906 if (closed) return _closedException(); |
938 if (closed) return _completeWithClosedException(completer); | |
939 List request = new List(3); | 907 List request = new List(3); |
940 request[0] = _TRUNCATE_REQUEST; | 908 request[0] = _TRUNCATE_REQUEST; |
941 request[1] = _id; | 909 request[1] = _id; |
942 request[2] = length; | 910 request[2] = length; |
943 return _fileService.call(request).then((response) { | 911 return _fileService.call(request).then((response) { |
944 if (_isErrorResponse(response)) { | 912 if (_isErrorResponse(response)) { |
945 throw _exceptionFromResponse(response, | 913 throw _exceptionFromResponse(response, |
946 "truncate failed for file '$_path'"); | 914 "truncate failed for file '$_path'"); |
947 } | 915 } |
948 return this; | 916 return this; |
949 }); | 917 }); |
950 } | 918 } |
951 | 919 |
952 external static _truncate(int id, int length); | 920 external static _truncate(int id, int length); |
953 | 921 |
954 void truncateSync(int length) { | 922 void truncateSync(int length) { |
955 _checkNotClosed(); | 923 _checkNotClosed(); |
956 var result = _truncate(_id, length); | 924 var result = _truncate(_id, length); |
957 if (result is OSError) { | 925 if (result is OSError) { |
958 throw new FileIOException("truncate failed for file '$_path'", result); | 926 throw new FileIOException("truncate failed for file '$_path'", result); |
959 } | 927 } |
960 } | 928 } |
961 | 929 |
962 Future<int> length() { | 930 Future<int> length() { |
963 _ensureFileService(); | 931 _ensureFileService(); |
964 Completer<int> completer = new Completer<int>(); | 932 if (closed) return _closedException(); |
965 if (closed) return _completeWithClosedException(completer); | |
966 List request = new List(2); | 933 List request = new List(2); |
967 request[0] = _LENGTH_REQUEST; | 934 request[0] = _LENGTH_REQUEST; |
968 request[1] = _id; | 935 request[1] = _id; |
969 return _fileService.call(request).then((response) { | 936 return _fileService.call(request).then((response) { |
970 if (_isErrorResponse(response)) { | 937 if (_isErrorResponse(response)) { |
971 throw _exceptionFromResponse(response, | 938 throw _exceptionFromResponse(response, |
972 "length failed for file '$_path'"); | 939 "length failed for file '$_path'"); |
973 } | 940 } |
974 return response; | 941 return response; |
975 }); | 942 }); |
976 } | 943 } |
977 | 944 |
978 external static _length(int id); | 945 external static _length(int id); |
979 | 946 |
980 int lengthSync() { | 947 int lengthSync() { |
981 _checkNotClosed(); | 948 _checkNotClosed(); |
982 var result = _length(_id); | 949 var result = _length(_id); |
983 if (result is OSError) { | 950 if (result is OSError) { |
984 throw new FileIOException("length failed for file '$_path'", result); | 951 throw new FileIOException("length failed for file '$_path'", result); |
985 } | 952 } |
986 return result; | 953 return result; |
987 } | 954 } |
988 | 955 |
989 Future<RandomAccessFile> flush() { | 956 Future<RandomAccessFile> flush() { |
990 _ensureFileService(); | 957 _ensureFileService(); |
991 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 958 if (closed) return _closedException(); |
992 if (closed) return _completeWithClosedException(completer); | |
993 List request = new List(2); | 959 List request = new List(2); |
994 request[0] = _FLUSH_REQUEST; | 960 request[0] = _FLUSH_REQUEST; |
995 request[1] = _id; | 961 request[1] = _id; |
996 return _fileService.call(request).then((response) { | 962 return _fileService.call(request).then((response) { |
997 if (_isErrorResponse(response)) { | 963 if (_isErrorResponse(response)) { |
998 throw _exceptionFromResponse(response, | 964 throw _exceptionFromResponse(response, |
999 "flush failed for file '$_path'"); | 965 "flush failed for file '$_path'"); |
1000 } | 966 } |
1001 return this; | 967 return this; |
1002 }); | 968 }); |
(...skipping 18 matching lines...) Expand all Loading... |
1021 } | 987 } |
1022 | 988 |
1023 bool get closed => _id == 0; | 989 bool get closed => _id == 0; |
1024 | 990 |
1025 void _checkNotClosed() { | 991 void _checkNotClosed() { |
1026 if (closed) { | 992 if (closed) { |
1027 throw new FileIOException("File closed '$_path'"); | 993 throw new FileIOException("File closed '$_path'"); |
1028 } | 994 } |
1029 } | 995 } |
1030 | 996 |
1031 Future _completeWithClosedException(Completer completer) { | 997 Future _closedException() { |
1032 Timer.run(() { | 998 return new Future.error(new FileIOException("File closed '$_path'")); |
1033 completer.completeError( | |
1034 new FileIOException("File closed '$_path'")); | |
1035 }); | |
1036 return completer.future; | |
1037 } | 999 } |
1038 | 1000 |
1039 final String _path; | 1001 final String _path; |
1040 int _id; | 1002 int _id; |
1041 | 1003 |
1042 SendPort _fileService; | 1004 SendPort _fileService; |
1043 } | 1005 } |
OLD | NEW |