| 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 #include "bin/file.h" | 5 #include "bin/file.h" |
| 6 | 6 |
| 7 #include "bin/builtin.h" | 7 #include "bin/builtin.h" |
| 8 #include "bin/dartutils.h" | 8 #include "bin/dartutils.h" |
| 9 #include "bin/io_buffer.h" | 9 #include "bin/io_buffer.h" |
| 10 #include "bin/thread.h" | 10 #include "bin/thread.h" |
| 11 #include "bin/utils.h" | 11 #include "bin/utils.h" |
| 12 | 12 |
| 13 #include "include/dart_api.h" | 13 #include "include/dart_api.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 namespace bin { | 16 namespace bin { |
| 17 | 17 |
| 18 static const int kMSPerSecond = 1000; | 18 static const int kMSPerSecond = 1000; |
| 19 | 19 |
| 20 // Forward declaration. | |
| 21 static void FileService(Dart_Port, Dart_Port, Dart_CObject*); | |
| 22 | |
| 23 NativeService File::file_service_("FileService", FileService, 16); | |
| 24 | |
| 25 | 20 |
| 26 // The file pointer has been passed into Dart as an intptr_t and it is safe | 21 // The file pointer has been passed into Dart as an intptr_t and it is safe |
| 27 // to pull it out of Dart as a 64-bit integer, cast it to an intptr_t and | 22 // to pull it out of Dart as a 64-bit integer, cast it to an intptr_t and |
| 28 // from there to a File pointer. | 23 // from there to a File pointer. |
| 29 static File* GetFilePointer(Dart_Handle handle) { | 24 static File* GetFilePointer(Dart_Handle handle) { |
| 30 intptr_t value = DartUtils::GetIntptrValue(handle); | 25 intptr_t value = DartUtils::GetIntptrValue(handle); |
| 31 return reinterpret_cast<File*>(value); | 26 return reinterpret_cast<File*>(value); |
| 32 } | 27 } |
| 33 | 28 |
| 34 | 29 |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 return result; | 626 return result; |
| 632 } | 627 } |
| 633 | 628 |
| 634 | 629 |
| 635 File* CObjectToFilePointer(CObject* cobject) { | 630 File* CObjectToFilePointer(CObject* cobject) { |
| 636 CObjectIntptr value(cobject); | 631 CObjectIntptr value(cobject); |
| 637 return reinterpret_cast<File*>(value.Value()); | 632 return reinterpret_cast<File*>(value.Value()); |
| 638 } | 633 } |
| 639 | 634 |
| 640 | 635 |
| 641 static CObject* FileExistsRequest(const CObjectArray& request) { | 636 CObject* File::ExistsRequest(const CObjectArray& request) { |
| 642 if (request.Length() == 2 && request[1]->IsString()) { | 637 if (request.Length() == 1 && request[0]->IsString()) { |
| 643 CObjectString filename(request[1]); | 638 CObjectString filename(request[0]); |
| 644 bool result = File::Exists(filename.CString()); | 639 bool result = File::Exists(filename.CString()); |
| 645 return CObject::Bool(result); | 640 return CObject::Bool(result); |
| 646 } | 641 } |
| 647 return CObject::IllegalArgumentError(); | 642 return CObject::IllegalArgumentError(); |
| 648 } | 643 } |
| 649 | 644 |
| 650 | 645 |
| 651 static CObject* FileCreateRequest(const CObjectArray& request) { | 646 CObject* File::CreateRequest(const CObjectArray& request) { |
| 652 if (request.Length() == 2 && request[1]->IsString()) { | 647 if (request.Length() == 1 && request[0]->IsString()) { |
| 653 CObjectString filename(request[1]); | 648 CObjectString filename(request[0]); |
| 654 bool result = File::Create(filename.CString()); | 649 bool result = File::Create(filename.CString()); |
| 655 if (result) { | 650 if (result) { |
| 656 return CObject::True(); | 651 return CObject::True(); |
| 657 } else { | 652 } else { |
| 658 return CObject::NewOSError(); | 653 return CObject::NewOSError(); |
| 659 } | 654 } |
| 660 } | 655 } |
| 661 return CObject::IllegalArgumentError(); | 656 return CObject::IllegalArgumentError(); |
| 662 } | 657 } |
| 663 | 658 |
| 664 static CObject* FileOpenRequest(const CObjectArray& request) { | 659 CObject* File::OpenRequest(const CObjectArray& request) { |
| 665 File* file = NULL; | 660 File* file = NULL; |
| 666 if (request.Length() == 3 && | 661 if (request.Length() == 2 && |
| 667 request[1]->IsString() && | 662 request[0]->IsString() && |
| 668 request[2]->IsInt32()) { | 663 request[1]->IsInt32()) { |
| 669 CObjectString filename(request[1]); | 664 CObjectString filename(request[0]); |
| 670 CObjectInt32 mode(request[2]); | 665 CObjectInt32 mode(request[1]); |
| 671 File::DartFileOpenMode dart_file_mode = | 666 File::DartFileOpenMode dart_file_mode = |
| 672 static_cast<File::DartFileOpenMode>(mode.Value()); | 667 static_cast<File::DartFileOpenMode>(mode.Value()); |
| 673 File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode); | 668 File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode); |
| 674 file = File::Open(filename.CString(), file_mode); | 669 file = File::Open(filename.CString(), file_mode); |
| 675 if (file != NULL) { | 670 if (file != NULL) { |
| 676 return new CObjectIntptr( | 671 return new CObjectIntptr( |
| 677 CObject::NewIntptr(reinterpret_cast<intptr_t>(file))); | 672 CObject::NewIntptr(reinterpret_cast<intptr_t>(file))); |
| 678 } else { | 673 } else { |
| 679 return CObject::NewOSError(); | 674 return CObject::NewOSError(); |
| 680 } | 675 } |
| 681 } | 676 } |
| 682 return CObject::IllegalArgumentError(); | 677 return CObject::IllegalArgumentError(); |
| 683 } | 678 } |
| 684 | 679 |
| 685 | 680 |
| 686 static CObject* FileDeleteRequest(const CObjectArray& request) { | 681 CObject* File::DeleteRequest(const CObjectArray& request) { |
| 687 if (request.Length() == 2 && request[1]->IsString()) { | 682 if (request.Length() == 1 && request[0]->IsString()) { |
| 688 CObjectString filename(request[1]); | 683 CObjectString filename(request[0]); |
| 689 bool result = File::Delete(filename.CString()); | 684 bool result = File::Delete(filename.CString()); |
| 690 if (result) { | 685 if (result) { |
| 691 return CObject::True(); | 686 return CObject::True(); |
| 692 } else { | 687 } else { |
| 693 return CObject::NewOSError(); | 688 return CObject::NewOSError(); |
| 694 } | 689 } |
| 695 } | 690 } |
| 696 return CObject::False(); | 691 return CObject::False(); |
| 697 } | 692 } |
| 698 | 693 |
| 699 | 694 |
| 700 static CObject* FileRenameRequest(const CObjectArray& request) { | 695 CObject* File::RenameRequest(const CObjectArray& request) { |
| 701 if (request.Length() == 3 && | 696 if (request.Length() == 2 && |
| 702 request[1]->IsString() && | 697 request[0]->IsString() && |
| 703 request[2]->IsString()) { | 698 request[1]->IsString()) { |
| 704 CObjectString old_path(request[1]); | 699 CObjectString old_path(request[0]); |
| 705 CObjectString new_path(request[2]); | 700 CObjectString new_path(request[1]); |
| 706 bool completed = File::Rename(old_path.CString(), new_path.CString()); | 701 bool completed = File::Rename(old_path.CString(), new_path.CString()); |
| 707 if (completed) return CObject::True(); | 702 if (completed) return CObject::True(); |
| 708 return CObject::NewOSError(); | 703 return CObject::NewOSError(); |
| 709 } | 704 } |
| 710 return CObject::IllegalArgumentError(); | 705 return CObject::IllegalArgumentError(); |
| 711 } | 706 } |
| 712 | 707 |
| 713 | 708 |
| 714 static CObject* FileResolveSymbolicLinksRequest(const CObjectArray& request) { | 709 CObject* File::ResolveSymbolicLinksRequest(const CObjectArray& request) { |
| 715 if (request.Length() == 2 && request[1]->IsString()) { | 710 if (request.Length() == 1 && request[0]->IsString()) { |
| 716 CObjectString filename(request[1]); | 711 CObjectString filename(request[0]); |
| 717 char* result = File::GetCanonicalPath(filename.CString()); | 712 char* result = File::GetCanonicalPath(filename.CString()); |
| 718 if (result != NULL) { | 713 if (result != NULL) { |
| 719 CObject* path = new CObjectString(CObject::NewString(result)); | 714 CObject* path = new CObjectString(CObject::NewString(result)); |
| 720 free(result); | 715 free(result); |
| 721 return path; | 716 return path; |
| 722 } else { | 717 } else { |
| 723 return CObject::NewOSError(); | 718 return CObject::NewOSError(); |
| 724 } | 719 } |
| 725 } | 720 } |
| 726 return CObject::IllegalArgumentError(); | 721 return CObject::IllegalArgumentError(); |
| 727 } | 722 } |
| 728 | 723 |
| 729 | 724 |
| 730 static CObject* FileCloseRequest(const CObjectArray& request) { | 725 CObject* File::CloseRequest(const CObjectArray& request) { |
| 731 intptr_t return_value = -1; | 726 intptr_t return_value = -1; |
| 732 if (request.Length() == 2 && request[1]->IsIntptr()) { | 727 if (request.Length() == 1 && request[0]->IsIntptr()) { |
| 733 File* file = CObjectToFilePointer(request[1]); | 728 File* file = CObjectToFilePointer(request[0]); |
| 734 ASSERT(file != NULL); | 729 ASSERT(file != NULL); |
| 735 delete file; | 730 delete file; |
| 736 return_value = 0; | 731 return_value = 0; |
| 737 } | 732 } |
| 738 return new CObjectIntptr(CObject::NewIntptr(return_value)); | 733 return new CObjectIntptr(CObject::NewIntptr(return_value)); |
| 739 } | 734 } |
| 740 | 735 |
| 741 | 736 |
| 742 static CObject* FilePositionRequest(const CObjectArray& request) { | 737 CObject* File::PositionRequest(const CObjectArray& request) { |
| 743 if (request.Length() == 2 && request[1]->IsIntptr()) { | 738 if (request.Length() == 1 && request[0]->IsIntptr()) { |
| 744 File* file = CObjectToFilePointer(request[1]); | 739 File* file = CObjectToFilePointer(request[0]); |
| 745 ASSERT(file != NULL); | 740 ASSERT(file != NULL); |
| 746 if (!file->IsClosed()) { | 741 if (!file->IsClosed()) { |
| 747 intptr_t return_value = file->Position(); | 742 intptr_t return_value = file->Position(); |
| 748 if (return_value >= 0) { | 743 if (return_value >= 0) { |
| 749 return new CObjectIntptr(CObject::NewIntptr(return_value)); | 744 return new CObjectIntptr(CObject::NewIntptr(return_value)); |
| 750 } else { | 745 } else { |
| 751 return CObject::NewOSError(); | 746 return CObject::NewOSError(); |
| 752 } | 747 } |
| 753 } else { | 748 } else { |
| 754 return CObject::FileClosedError(); | 749 return CObject::FileClosedError(); |
| 755 } | 750 } |
| 756 } | 751 } |
| 757 return CObject::IllegalArgumentError(); | 752 return CObject::IllegalArgumentError(); |
| 758 } | 753 } |
| 759 | 754 |
| 760 | 755 |
| 761 static CObject* FileSetPositionRequest(const CObjectArray& request) { | 756 CObject* File::SetPositionRequest(const CObjectArray& request) { |
| 762 if (request.Length() == 3 && | 757 if (request.Length() == 2 && |
| 763 request[1]->IsIntptr() && | 758 request[0]->IsIntptr() && |
| 764 request[2]->IsInt32OrInt64()) { | 759 request[1]->IsInt32OrInt64()) { |
| 765 File* file = CObjectToFilePointer(request[1]); | 760 File* file = CObjectToFilePointer(request[0]); |
| 766 ASSERT(file != NULL); | 761 ASSERT(file != NULL); |
| 767 if (!file->IsClosed()) { | 762 if (!file->IsClosed()) { |
| 768 int64_t position = CObjectInt32OrInt64ToInt64(request[2]); | 763 int64_t position = CObjectInt32OrInt64ToInt64(request[1]); |
| 769 if (file->SetPosition(position)) { | 764 if (file->SetPosition(position)) { |
| 770 return CObject::True(); | 765 return CObject::True(); |
| 771 } else { | 766 } else { |
| 772 return CObject::NewOSError(); | 767 return CObject::NewOSError(); |
| 773 } | 768 } |
| 774 } else { | 769 } else { |
| 775 return CObject::FileClosedError(); | 770 return CObject::FileClosedError(); |
| 776 } | 771 } |
| 777 } | 772 } |
| 778 return CObject::IllegalArgumentError(); | 773 return CObject::IllegalArgumentError(); |
| 779 } | 774 } |
| 780 | 775 |
| 781 | 776 |
| 782 static CObject* FileTruncateRequest(const CObjectArray& request) { | 777 CObject* File::TruncateRequest(const CObjectArray& request) { |
| 783 if (request.Length() == 3 && | 778 if (request.Length() == 2 && |
| 784 request[1]->IsIntptr() && | 779 request[0]->IsIntptr() && |
| 785 request[2]->IsInt32OrInt64()) { | 780 request[1]->IsInt32OrInt64()) { |
| 786 File* file = CObjectToFilePointer(request[1]); | 781 File* file = CObjectToFilePointer(request[0]); |
| 787 ASSERT(file != NULL); | 782 ASSERT(file != NULL); |
| 788 if (!file->IsClosed()) { | 783 if (!file->IsClosed()) { |
| 789 int64_t length = CObjectInt32OrInt64ToInt64(request[2]); | 784 int64_t length = CObjectInt32OrInt64ToInt64(request[1]); |
| 790 if (file->Truncate(length)) { | 785 if (file->Truncate(length)) { |
| 791 return CObject::True(); | 786 return CObject::True(); |
| 792 } else { | 787 } else { |
| 793 return CObject::NewOSError(); | 788 return CObject::NewOSError(); |
| 794 } | 789 } |
| 795 } else { | 790 } else { |
| 796 return CObject::FileClosedError(); | 791 return CObject::FileClosedError(); |
| 797 } | 792 } |
| 798 } | 793 } |
| 799 return CObject::IllegalArgumentError(); | 794 return CObject::IllegalArgumentError(); |
| 800 } | 795 } |
| 801 | 796 |
| 802 | 797 |
| 803 static CObject* FileLengthRequest(const CObjectArray& request) { | 798 CObject* File::LengthRequest(const CObjectArray& request) { |
| 804 if (request.Length() == 2 && request[1]->IsIntptr()) { | 799 if (request.Length() == 1 && request[0]->IsIntptr()) { |
| 805 File* file = CObjectToFilePointer(request[1]); | 800 File* file = CObjectToFilePointer(request[0]); |
| 806 ASSERT(file != NULL); | 801 ASSERT(file != NULL); |
| 807 if (!file->IsClosed()) { | 802 if (!file->IsClosed()) { |
| 808 intptr_t return_value = file->Length(); | 803 off_t return_value = file->Length(); |
| 809 if (return_value >= 0) { | 804 if (return_value >= 0) { |
| 810 return new CObjectIntptr(CObject::NewIntptr(return_value)); | 805 return new CObjectInt64(CObject::NewInt64(return_value)); |
| 811 } else { | 806 } else { |
| 812 return CObject::NewOSError(); | 807 return CObject::NewOSError(); |
| 813 } | 808 } |
| 814 } else { | 809 } else { |
| 815 return CObject::FileClosedError(); | 810 return CObject::FileClosedError(); |
| 816 } | 811 } |
| 817 } | 812 } |
| 818 return CObject::IllegalArgumentError(); | 813 return CObject::IllegalArgumentError(); |
| 819 } | 814 } |
| 820 | 815 |
| 821 | 816 |
| 822 static CObject* FileLengthFromPathRequest(const CObjectArray& request) { | 817 CObject* File::LengthFromPathRequest(const CObjectArray& request) { |
| 823 if (request.Length() == 2 && request[1]->IsString()) { | 818 if (request.Length() == 1 && request[0]->IsString()) { |
| 824 CObjectString filepath(request[1]); | 819 CObjectString filepath(request[0]); |
| 825 intptr_t return_value = File::LengthFromPath(filepath.CString()); | 820 off_t return_value = File::LengthFromPath(filepath.CString()); |
| 826 if (return_value >= 0) { | 821 if (return_value >= 0) { |
| 827 return new CObjectIntptr(CObject::NewIntptr(return_value)); | 822 return new CObjectInt64(CObject::NewInt64(return_value)); |
| 828 } else { | 823 } else { |
| 829 return CObject::NewOSError(); | 824 return CObject::NewOSError(); |
| 830 } | 825 } |
| 831 } | 826 } |
| 832 return CObject::IllegalArgumentError(); | 827 return CObject::IllegalArgumentError(); |
| 833 } | 828 } |
| 834 | 829 |
| 835 | 830 |
| 836 static CObject* FileLastModifiedRequest(const CObjectArray& request) { | 831 CObject* File::LastModifiedRequest(const CObjectArray& request) { |
| 837 if (request.Length() == 2 && request[1]->IsString()) { | 832 if (request.Length() == 1 && request[0]->IsString()) { |
| 838 CObjectString filepath(request[1]); | 833 CObjectString filepath(request[0]); |
| 839 int64_t return_value = File::LastModified(filepath.CString()); | 834 int64_t return_value = File::LastModified(filepath.CString()); |
| 840 if (return_value >= 0) { | 835 if (return_value >= 0) { |
| 841 return new CObjectIntptr(CObject::NewInt64(return_value * kMSPerSecond)); | 836 return new CObjectIntptr(CObject::NewInt64(return_value * kMSPerSecond)); |
| 842 } else { | 837 } else { |
| 843 return CObject::NewOSError(); | 838 return CObject::NewOSError(); |
| 844 } | 839 } |
| 845 } | 840 } |
| 846 return CObject::IllegalArgumentError(); | 841 return CObject::IllegalArgumentError(); |
| 847 } | 842 } |
| 848 | 843 |
| 849 | 844 |
| 850 static CObject* FileFlushRequest(const CObjectArray& request) { | 845 CObject* File::FlushRequest(const CObjectArray& request) { |
| 851 if (request.Length() == 2 && request[1]->IsIntptr()) { | 846 if (request.Length() == 1 && request[0]->IsIntptr()) { |
| 852 File* file = CObjectToFilePointer(request[1]); | 847 File* file = CObjectToFilePointer(request[0]); |
| 853 ASSERT(file != NULL); | 848 ASSERT(file != NULL); |
| 854 if (!file->IsClosed()) { | 849 if (!file->IsClosed()) { |
| 855 if (file->Flush()) { | 850 if (file->Flush()) { |
| 856 return CObject::True(); | 851 return CObject::True(); |
| 857 } else { | 852 } else { |
| 858 return CObject::NewOSError(); | 853 return CObject::NewOSError(); |
| 859 } | 854 } |
| 860 } else { | 855 } else { |
| 861 return CObject::FileClosedError(); | 856 return CObject::FileClosedError(); |
| 862 } | 857 } |
| 863 } | 858 } |
| 864 return CObject::IllegalArgumentError(); | 859 return CObject::IllegalArgumentError(); |
| 865 } | 860 } |
| 866 | 861 |
| 867 | 862 |
| 868 static CObject* FileReadByteRequest(const CObjectArray& request) { | 863 CObject* File::ReadByteRequest(const CObjectArray& request) { |
| 869 if (request.Length() == 2 && request[1]->IsIntptr()) { | 864 if (request.Length() == 1 && request[0]->IsIntptr()) { |
| 870 File* file = CObjectToFilePointer(request[1]); | 865 File* file = CObjectToFilePointer(request[0]); |
| 871 ASSERT(file != NULL); | 866 ASSERT(file != NULL); |
| 872 if (!file->IsClosed()) { | 867 if (!file->IsClosed()) { |
| 873 uint8_t buffer; | 868 uint8_t buffer; |
| 874 int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1); | 869 int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1); |
| 875 if (bytes_read > 0) { | 870 if (bytes_read > 0) { |
| 876 return new CObjectIntptr(CObject::NewIntptr(buffer)); | 871 return new CObjectIntptr(CObject::NewIntptr(buffer)); |
| 877 } else if (bytes_read == 0) { | 872 } else if (bytes_read == 0) { |
| 878 return new CObjectIntptr(CObject::NewIntptr(-1)); | 873 return new CObjectIntptr(CObject::NewIntptr(-1)); |
| 879 } else { | 874 } else { |
| 880 return CObject::NewOSError(); | 875 return CObject::NewOSError(); |
| 881 } | 876 } |
| 882 } else { | 877 } else { |
| 883 return CObject::FileClosedError(); | 878 return CObject::FileClosedError(); |
| 884 } | 879 } |
| 885 } | 880 } |
| 886 return CObject::IllegalArgumentError(); | 881 return CObject::IllegalArgumentError(); |
| 887 } | 882 } |
| 888 | 883 |
| 889 | 884 |
| 890 static CObject* FileWriteByteRequest(const CObjectArray& request) { | 885 CObject* File::WriteByteRequest(const CObjectArray& request) { |
| 891 if (request.Length() == 3 && | 886 if (request.Length() == 2 && |
| 892 request[1]->IsIntptr() && | 887 request[0]->IsIntptr() && |
| 893 request[2]->IsInt32OrInt64()) { | 888 request[1]->IsInt32OrInt64()) { |
| 894 File* file = CObjectToFilePointer(request[1]); | 889 File* file = CObjectToFilePointer(request[0]); |
| 895 ASSERT(file != NULL); | 890 ASSERT(file != NULL); |
| 896 if (!file->IsClosed()) { | 891 if (!file->IsClosed()) { |
| 897 int64_t byte = CObjectInt32OrInt64ToInt64(request[2]); | 892 int64_t byte = CObjectInt32OrInt64ToInt64(request[1]); |
| 898 uint8_t buffer = static_cast<uint8_t>(byte & 0xff); | 893 uint8_t buffer = static_cast<uint8_t>(byte & 0xff); |
| 899 int64_t bytes_written = file->Write(reinterpret_cast<void*>(&buffer), 1); | 894 int64_t bytes_written = file->Write(reinterpret_cast<void*>(&buffer), 1); |
| 900 if (bytes_written > 0) { | 895 if (bytes_written > 0) { |
| 901 return new CObjectInt64(CObject::NewInt64(bytes_written)); | 896 return new CObjectInt64(CObject::NewInt64(bytes_written)); |
| 902 } else { | 897 } else { |
| 903 return CObject::NewOSError(); | 898 return CObject::NewOSError(); |
| 904 } | 899 } |
| 905 } else { | 900 } else { |
| 906 return CObject::FileClosedError(); | 901 return CObject::FileClosedError(); |
| 907 } | 902 } |
| 908 } | 903 } |
| 909 return CObject::IllegalArgumentError(); | 904 return CObject::IllegalArgumentError(); |
| 910 } | 905 } |
| 911 | 906 |
| 912 | 907 |
| 913 static CObject* FileReadRequest(const CObjectArray& request) { | 908 CObject* File::ReadRequest(const CObjectArray& request) { |
| 914 if (request.Length() == 3 && | 909 if (request.Length() == 2 && |
| 915 request[1]->IsIntptr() && | 910 request[0]->IsIntptr() && |
| 916 request[2]->IsInt32OrInt64()) { | 911 request[1]->IsInt32OrInt64()) { |
| 917 File* file = CObjectToFilePointer(request[1]); | 912 File* file = CObjectToFilePointer(request[0]); |
| 918 ASSERT(file != NULL); | 913 ASSERT(file != NULL); |
| 919 if (!file->IsClosed()) { | 914 if (!file->IsClosed()) { |
| 920 int64_t length = CObjectInt32OrInt64ToInt64(request[2]); | 915 int64_t length = CObjectInt32OrInt64ToInt64(request[1]); |
| 921 Dart_CObject* io_buffer = CObject::NewIOBuffer(length); | 916 Dart_CObject* io_buffer = CObject::NewIOBuffer(length); |
| 922 ASSERT(io_buffer != NULL); | 917 ASSERT(io_buffer != NULL); |
| 923 uint8_t* data = io_buffer->value.as_external_typed_data.data; | 918 uint8_t* data = io_buffer->value.as_external_typed_data.data; |
| 924 int64_t bytes_read = file->Read(data, length); | 919 int64_t bytes_read = file->Read(data, length); |
| 925 if (bytes_read >= 0) { | 920 if (bytes_read >= 0) { |
| 926 CObjectExternalUint8Array* external_array = | 921 CObjectExternalUint8Array* external_array = |
| 927 new CObjectExternalUint8Array(io_buffer); | 922 new CObjectExternalUint8Array(io_buffer); |
| 928 external_array->SetLength(bytes_read); | 923 external_array->SetLength(bytes_read); |
| 929 CObjectArray* result = new CObjectArray(CObject::NewArray(2)); | 924 CObjectArray* result = new CObjectArray(CObject::NewArray(2)); |
| 930 result->SetAt(0, new CObjectIntptr(CObject::NewInt32(0))); | 925 result->SetAt(0, new CObjectIntptr(CObject::NewInt32(0))); |
| 931 result->SetAt(1, external_array); | 926 result->SetAt(1, external_array); |
| 932 return result; | 927 return result; |
| 933 } else { | 928 } else { |
| 934 CObject::FreeIOBufferData(io_buffer); | 929 CObject::FreeIOBufferData(io_buffer); |
| 935 return CObject::NewOSError(); | 930 return CObject::NewOSError(); |
| 936 } | 931 } |
| 937 } else { | 932 } else { |
| 938 return CObject::FileClosedError(); | 933 return CObject::FileClosedError(); |
| 939 } | 934 } |
| 940 } | 935 } |
| 941 return CObject::IllegalArgumentError(); | 936 return CObject::IllegalArgumentError(); |
| 942 } | 937 } |
| 943 | 938 |
| 944 | 939 |
| 945 static CObject* FileReadIntoRequest(const CObjectArray& request) { | 940 CObject* File::ReadIntoRequest(const CObjectArray& request) { |
| 946 if (request.Length() == 3 && | 941 if (request.Length() == 2 && |
| 947 request[1]->IsIntptr() && | 942 request[0]->IsIntptr() && |
| 948 request[2]->IsInt32OrInt64()) { | 943 request[1]->IsInt32OrInt64()) { |
| 949 File* file = CObjectToFilePointer(request[1]); | 944 File* file = CObjectToFilePointer(request[0]); |
| 950 ASSERT(file != NULL); | 945 ASSERT(file != NULL); |
| 951 if (!file->IsClosed()) { | 946 if (!file->IsClosed()) { |
| 952 int64_t length = CObjectInt32OrInt64ToInt64(request[2]); | 947 int64_t length = CObjectInt32OrInt64ToInt64(request[1]); |
| 953 Dart_CObject* io_buffer = CObject::NewIOBuffer(length); | 948 Dart_CObject* io_buffer = CObject::NewIOBuffer(length); |
| 954 ASSERT(io_buffer != NULL); | 949 ASSERT(io_buffer != NULL); |
| 955 uint8_t* data = io_buffer->value.as_external_typed_data.data; | 950 uint8_t* data = io_buffer->value.as_external_typed_data.data; |
| 956 int64_t bytes_read = file->Read(data, length); | 951 int64_t bytes_read = file->Read(data, length); |
| 957 if (bytes_read >= 0) { | 952 if (bytes_read >= 0) { |
| 958 CObjectExternalUint8Array* external_array = | 953 CObjectExternalUint8Array* external_array = |
| 959 new CObjectExternalUint8Array(io_buffer); | 954 new CObjectExternalUint8Array(io_buffer); |
| 960 external_array->SetLength(bytes_read); | 955 external_array->SetLength(bytes_read); |
| 961 CObjectArray* result = new CObjectArray(CObject::NewArray(3)); | 956 CObjectArray* result = new CObjectArray(CObject::NewArray(3)); |
| 962 result->SetAt(0, new CObjectIntptr(CObject::NewInt32(0))); | 957 result->SetAt(0, new CObjectIntptr(CObject::NewInt32(0))); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 993 case Dart_TypedData_kFloat64: | 988 case Dart_TypedData_kFloat64: |
| 994 return 8; | 989 return 8; |
| 995 default: | 990 default: |
| 996 break; | 991 break; |
| 997 } | 992 } |
| 998 UNREACHABLE(); | 993 UNREACHABLE(); |
| 999 return -1; | 994 return -1; |
| 1000 } | 995 } |
| 1001 | 996 |
| 1002 | 997 |
| 1003 static CObject* FileWriteFromRequest(const CObjectArray& request) { | 998 CObject* File::WriteFromRequest(const CObjectArray& request) { |
| 1004 if (request.Length() == 5 && | 999 if (request.Length() == 4 && |
| 1005 request[1]->IsIntptr() && | 1000 request[0]->IsIntptr() && |
| 1006 (request[2]->IsTypedData() || request[2]->IsArray()) && | 1001 (request[1]->IsTypedData() || request[1]->IsArray()) && |
| 1007 request[3]->IsInt32OrInt64() && | 1002 request[2]->IsInt32OrInt64() && |
| 1008 request[4]->IsInt32OrInt64()) { | 1003 request[3]->IsInt32OrInt64()) { |
| 1009 File* file = CObjectToFilePointer(request[1]); | 1004 File* file = CObjectToFilePointer(request[0]); |
| 1010 ASSERT(file != NULL); | 1005 ASSERT(file != NULL); |
| 1011 if (!file->IsClosed()) { | 1006 if (!file->IsClosed()) { |
| 1012 int64_t start = CObjectInt32OrInt64ToInt64(request[3]); | 1007 int64_t start = CObjectInt32OrInt64ToInt64(request[2]); |
| 1013 int64_t end = CObjectInt32OrInt64ToInt64(request[4]); | 1008 int64_t end = CObjectInt32OrInt64ToInt64(request[3]); |
| 1014 int64_t length = end - start; | 1009 int64_t length = end - start; |
| 1015 uint8_t* buffer_start; | 1010 uint8_t* buffer_start; |
| 1016 if (request[2]->IsTypedData()) { | 1011 if (request[1]->IsTypedData()) { |
| 1017 CObjectTypedData typed_data(request[2]); | 1012 CObjectTypedData typed_data(request[1]); |
| 1018 start = start * SizeInBytes(typed_data.Type()); | 1013 start = start * SizeInBytes(typed_data.Type()); |
| 1019 length = length * SizeInBytes(typed_data.Type()); | 1014 length = length * SizeInBytes(typed_data.Type()); |
| 1020 buffer_start = typed_data.Buffer() + start; | 1015 buffer_start = typed_data.Buffer() + start; |
| 1021 } else { | 1016 } else { |
| 1022 CObjectArray array(request[2]); | 1017 CObjectArray array(request[1]); |
| 1023 buffer_start = new uint8_t[length]; | 1018 buffer_start = new uint8_t[length]; |
| 1024 for (int i = 0; i < length; i++) { | 1019 for (int i = 0; i < length; i++) { |
| 1025 if (array[i + start]->IsInt32OrInt64()) { | 1020 if (array[i + start]->IsInt32OrInt64()) { |
| 1026 int64_t value = CObjectInt32OrInt64ToInt64(array[i + start]); | 1021 int64_t value = CObjectInt32OrInt64ToInt64(array[i + start]); |
| 1027 buffer_start[i] = static_cast<uint8_t>(value & 0xFF); | 1022 buffer_start[i] = static_cast<uint8_t>(value & 0xFF); |
| 1028 } else { | 1023 } else { |
| 1029 // Unsupported type. | 1024 // Unsupported type. |
| 1030 delete[] buffer_start; | 1025 delete[] buffer_start; |
| 1031 return CObject::IllegalArgumentError(); | 1026 return CObject::IllegalArgumentError(); |
| 1032 } | 1027 } |
| 1033 } | 1028 } |
| 1034 start = 0; | 1029 start = 0; |
| 1035 } | 1030 } |
| 1036 int64_t bytes_written = | 1031 int64_t bytes_written = |
| 1037 file->Write(reinterpret_cast<void*>(buffer_start), length); | 1032 file->Write(reinterpret_cast<void*>(buffer_start), length); |
| 1038 if (!request[2]->IsTypedData()) { | 1033 if (!request[1]->IsTypedData()) { |
| 1039 delete[] buffer_start; | 1034 delete[] buffer_start; |
| 1040 } | 1035 } |
| 1041 if (bytes_written >= 0) { | 1036 if (bytes_written >= 0) { |
| 1042 return new CObjectInt64(CObject::NewInt64(bytes_written)); | 1037 return new CObjectInt64(CObject::NewInt64(bytes_written)); |
| 1043 } else { | 1038 } else { |
| 1044 return CObject::NewOSError(); | 1039 return CObject::NewOSError(); |
| 1045 } | 1040 } |
| 1046 } else { | 1041 } else { |
| 1047 return CObject::FileClosedError(); | 1042 return CObject::FileClosedError(); |
| 1048 } | 1043 } |
| 1049 } | 1044 } |
| 1050 return CObject::IllegalArgumentError(); | 1045 return CObject::IllegalArgumentError(); |
| 1051 } | 1046 } |
| 1052 | 1047 |
| 1053 | 1048 |
| 1054 static CObject* FileCreateLinkRequest(const CObjectArray& request) { | 1049 CObject* File::CreateLinkRequest(const CObjectArray& request) { |
| 1055 if (request.Length() != 3 || | 1050 if (request.Length() != 2 || |
| 1056 !request[1]->IsString() || | 1051 !request[0]->IsString() || |
| 1057 !request[2]->IsString()) { | 1052 !request[1]->IsString()) { |
| 1058 return CObject::IllegalArgumentError(); | 1053 return CObject::IllegalArgumentError(); |
| 1059 } | 1054 } |
| 1060 CObjectString link_name(request[1]); | 1055 CObjectString link_name(request[0]); |
| 1061 CObjectString target_name(request[2]); | 1056 CObjectString target_name(request[1]); |
| 1062 if (File::CreateLink(link_name.CString(), target_name.CString())) { | 1057 if (File::CreateLink(link_name.CString(), target_name.CString())) { |
| 1063 return CObject::True(); | 1058 return CObject::True(); |
| 1064 } else { | 1059 } else { |
| 1065 return CObject::NewOSError(); | 1060 return CObject::NewOSError(); |
| 1066 } | 1061 } |
| 1067 } | 1062 } |
| 1068 | 1063 |
| 1069 | 1064 |
| 1070 static CObject* FileDeleteLinkRequest(const CObjectArray& request) { | 1065 CObject* File::DeleteLinkRequest(const CObjectArray& request) { |
| 1071 if (request.Length() == 2 && request[1]->IsString()) { | 1066 if (request.Length() == 1 && request[0]->IsString()) { |
| 1072 CObjectString link_path(request[1]); | 1067 CObjectString link_path(request[0]); |
| 1073 bool result = File::DeleteLink(link_path.CString()); | 1068 bool result = File::DeleteLink(link_path.CString()); |
| 1074 if (result) { | 1069 if (result) { |
| 1075 return CObject::True(); | 1070 return CObject::True(); |
| 1076 } else { | 1071 } else { |
| 1077 return CObject::NewOSError(); | 1072 return CObject::NewOSError(); |
| 1078 } | 1073 } |
| 1079 } | 1074 } |
| 1080 return CObject::IllegalArgumentError(); | 1075 return CObject::IllegalArgumentError(); |
| 1081 } | 1076 } |
| 1082 | 1077 |
| 1083 | 1078 |
| 1084 static CObject* FileRenameLinkRequest(const CObjectArray& request) { | 1079 CObject* File::RenameLinkRequest(const CObjectArray& request) { |
| 1085 if (request.Length() == 3 && | 1080 if (request.Length() == 2 && |
| 1086 request[1]->IsString() && | 1081 request[0]->IsString() && |
| 1087 request[2]->IsString()) { | 1082 request[1]->IsString()) { |
| 1088 CObjectString old_path(request[1]); | 1083 CObjectString old_path(request[0]); |
| 1089 CObjectString new_path(request[2]); | 1084 CObjectString new_path(request[1]); |
| 1090 bool completed = File::RenameLink(old_path.CString(), new_path.CString()); | 1085 bool completed = File::RenameLink(old_path.CString(), new_path.CString()); |
| 1091 if (completed) return CObject::True(); | 1086 if (completed) return CObject::True(); |
| 1092 return CObject::NewOSError(); | 1087 return CObject::NewOSError(); |
| 1093 } | 1088 } |
| 1094 return CObject::IllegalArgumentError(); | 1089 return CObject::IllegalArgumentError(); |
| 1095 } | 1090 } |
| 1096 | 1091 |
| 1097 | 1092 |
| 1098 static CObject* FileLinkTargetRequest(const CObjectArray& request) { | 1093 CObject* File::LinkTargetRequest(const CObjectArray& request) { |
| 1099 if (request.Length() == 2 && request[1]->IsString()) { | 1094 if (request.Length() == 1 && request[0]->IsString()) { |
| 1100 CObjectString link_path(request[1]); | 1095 CObjectString link_path(request[0]); |
| 1101 char* target = File::LinkTarget(link_path.CString()); | 1096 char* target = File::LinkTarget(link_path.CString()); |
| 1102 if (target != NULL) { | 1097 if (target != NULL) { |
| 1103 CObject* result = new CObjectString(CObject::NewString(target)); | 1098 CObject* result = new CObjectString(CObject::NewString(target)); |
| 1104 free(target); | 1099 free(target); |
| 1105 return result; | 1100 return result; |
| 1106 } else { | 1101 } else { |
| 1107 return CObject::NewOSError(); | 1102 return CObject::NewOSError(); |
| 1108 } | 1103 } |
| 1109 } | 1104 } |
| 1110 return CObject::IllegalArgumentError(); | 1105 return CObject::IllegalArgumentError(); |
| 1111 } | 1106 } |
| 1112 | 1107 |
| 1113 | 1108 |
| 1114 static CObject* FileTypeRequest(const CObjectArray& request) { | 1109 CObject* File::TypeRequest(const CObjectArray& request) { |
| 1115 if (request.Length() == 3 && | 1110 if (request.Length() == 2 && |
| 1116 request[1]->IsString() && | 1111 request[0]->IsString() && |
| 1117 request[2]->IsBool()) { | 1112 request[1]->IsBool()) { |
| 1118 CObjectString path(request[1]); | 1113 CObjectString path(request[0]); |
| 1119 CObjectBool follow_links(request[2]); | 1114 CObjectBool follow_links(request[1]); |
| 1120 File::Type type = File::GetType(path.CString(), follow_links.Value()); | 1115 File::Type type = File::GetType(path.CString(), follow_links.Value()); |
| 1121 return new CObjectInt32(CObject::NewInt32(type)); | 1116 return new CObjectInt32(CObject::NewInt32(type)); |
| 1122 } | 1117 } |
| 1123 return CObject::IllegalArgumentError(); | 1118 return CObject::IllegalArgumentError(); |
| 1124 } | 1119 } |
| 1125 | 1120 |
| 1126 | 1121 |
| 1127 static CObject* FileIdenticalRequest(const CObjectArray& request) { | 1122 CObject* File::IdenticalRequest(const CObjectArray& request) { |
| 1128 if (request.Length() == 3 && | 1123 if (request.Length() == 2 && |
| 1129 request[1]->IsString() && | 1124 request[0]->IsString() && |
| 1130 request[2]->IsString()) { | 1125 request[1]->IsString()) { |
| 1131 CObjectString path1(request[1]); | 1126 CObjectString path1(request[0]); |
| 1132 CObjectString path2(request[2]); | 1127 CObjectString path2(request[1]); |
| 1133 File::Identical result = File::AreIdentical(path1.CString(), | 1128 File::Identical result = File::AreIdentical(path1.CString(), |
| 1134 path2.CString()); | 1129 path2.CString()); |
| 1135 if (result == File::kError) { | 1130 if (result == File::kError) { |
| 1136 return CObject::NewOSError(); | 1131 return CObject::NewOSError(); |
| 1137 } else if (result == File::kIdentical) { | 1132 } else if (result == File::kIdentical) { |
| 1138 return CObject::True(); | 1133 return CObject::True(); |
| 1139 } else { | 1134 } else { |
| 1140 return CObject::False(); | 1135 return CObject::False(); |
| 1141 } | 1136 } |
| 1142 } | 1137 } |
| 1143 return CObject::IllegalArgumentError(); | 1138 return CObject::IllegalArgumentError(); |
| 1144 } | 1139 } |
| 1145 | 1140 |
| 1146 | 1141 |
| 1147 static CObject* FileStatRequest(const CObjectArray& request) { | 1142 CObject* File::StatRequest(const CObjectArray& request) { |
| 1148 if (request.Length() == 2 && | 1143 if (request.Length() == 1 && |
| 1149 request[1]->IsString()) { | 1144 request[0]->IsString()) { |
| 1150 int64_t data[File::kStatSize]; | 1145 int64_t data[File::kStatSize]; |
| 1151 CObjectString path(request[1]); | 1146 CObjectString path(request[0]); |
| 1152 File::Stat(path.CString(), data); | 1147 File::Stat(path.CString(), data); |
| 1153 if (data[File::kType] == File::kDoesNotExist) { | 1148 if (data[File::kType] == File::kDoesNotExist) { |
| 1154 return CObject::NewOSError(); | 1149 return CObject::NewOSError(); |
| 1155 } | 1150 } |
| 1156 CObjectArray* result = | 1151 CObjectArray* result = |
| 1157 new CObjectArray(CObject::NewArray(File::kStatSize)); | 1152 new CObjectArray(CObject::NewArray(File::kStatSize)); |
| 1158 for (int i = 0; i < File::kStatSize; ++i) { | 1153 for (int i = 0; i < File::kStatSize; ++i) { |
| 1159 result->SetAt(i, new CObjectInt64(CObject::NewInt64(data[i]))); | 1154 result->SetAt(i, new CObjectInt64(CObject::NewInt64(data[i]))); |
| 1160 } | 1155 } |
| 1161 CObjectArray* wrapper = new CObjectArray(CObject::NewArray(2)); | 1156 CObjectArray* wrapper = new CObjectArray(CObject::NewArray(2)); |
| 1162 wrapper->SetAt(0, new CObjectInt32(CObject::NewInt32(CObject::kSuccess))); | 1157 wrapper->SetAt(0, new CObjectInt32(CObject::NewInt32(CObject::kSuccess))); |
| 1163 wrapper->SetAt(1, result); | 1158 wrapper->SetAt(1, result); |
| 1164 return wrapper; | 1159 return wrapper; |
| 1165 } | 1160 } |
| 1166 return CObject::IllegalArgumentError(); | 1161 return CObject::IllegalArgumentError(); |
| 1167 } | 1162 } |
| 1168 | 1163 |
| 1169 | |
| 1170 static void FileService(Dart_Port dest_port_id, | |
| 1171 Dart_Port reply_port_id, | |
| 1172 Dart_CObject* message) { | |
| 1173 CObject* response = CObject::IllegalArgumentError(); | |
| 1174 CObjectArray request(message); | |
| 1175 if (message->type == Dart_CObject_kArray) { | |
| 1176 if (request.Length() > 1 && request[0]->IsInt32()) { | |
| 1177 CObjectInt32 requestType(request[0]); | |
| 1178 switch (requestType.Value()) { | |
| 1179 case File::kExistsRequest: | |
| 1180 response = FileExistsRequest(request); | |
| 1181 break; | |
| 1182 case File::kCreateRequest: | |
| 1183 response = FileCreateRequest(request); | |
| 1184 break; | |
| 1185 case File::kOpenRequest: | |
| 1186 response = FileOpenRequest(request); | |
| 1187 break; | |
| 1188 case File::kDeleteRequest: | |
| 1189 response = FileDeleteRequest(request); | |
| 1190 break; | |
| 1191 case File::kRenameRequest: | |
| 1192 response = FileRenameRequest(request); | |
| 1193 break; | |
| 1194 case File::kResolveSymbolicLinksRequest: | |
| 1195 response = FileResolveSymbolicLinksRequest(request); | |
| 1196 break; | |
| 1197 case File::kCloseRequest: | |
| 1198 response = FileCloseRequest(request); | |
| 1199 break; | |
| 1200 case File::kPositionRequest: | |
| 1201 response = FilePositionRequest(request); | |
| 1202 break; | |
| 1203 case File::kSetPositionRequest: | |
| 1204 response = FileSetPositionRequest(request); | |
| 1205 break; | |
| 1206 case File::kTruncateRequest: | |
| 1207 response = FileTruncateRequest(request); | |
| 1208 break; | |
| 1209 case File::kLengthRequest: | |
| 1210 response = FileLengthRequest(request); | |
| 1211 break; | |
| 1212 case File::kLengthFromPathRequest: | |
| 1213 response = FileLengthFromPathRequest(request); | |
| 1214 break; | |
| 1215 case File::kLastModifiedRequest: | |
| 1216 response = FileLastModifiedRequest(request); | |
| 1217 break; | |
| 1218 case File::kFlushRequest: | |
| 1219 response = FileFlushRequest(request); | |
| 1220 break; | |
| 1221 case File::kReadByteRequest: | |
| 1222 response = FileReadByteRequest(request); | |
| 1223 break; | |
| 1224 case File::kWriteByteRequest: | |
| 1225 response = FileWriteByteRequest(request); | |
| 1226 break; | |
| 1227 case File::kReadRequest: | |
| 1228 response = FileReadRequest(request); | |
| 1229 break; | |
| 1230 case File::kReadIntoRequest: | |
| 1231 response = FileReadIntoRequest(request); | |
| 1232 break; | |
| 1233 case File::kWriteFromRequest: | |
| 1234 response = FileWriteFromRequest(request); | |
| 1235 break; | |
| 1236 case File::kDeleteLinkRequest: | |
| 1237 response = FileDeleteLinkRequest(request); | |
| 1238 break; | |
| 1239 case File::kRenameLinkRequest: | |
| 1240 response = FileRenameLinkRequest(request); | |
| 1241 break; | |
| 1242 case File::kCreateLinkRequest: | |
| 1243 response = FileCreateLinkRequest(request); | |
| 1244 break; | |
| 1245 case File::kLinkTargetRequest: | |
| 1246 response = FileLinkTargetRequest(request); | |
| 1247 break; | |
| 1248 case File::kTypeRequest: | |
| 1249 response = FileTypeRequest(request); | |
| 1250 break; | |
| 1251 case File::kIdenticalRequest: | |
| 1252 response = FileIdenticalRequest(request); | |
| 1253 break; | |
| 1254 case File::kStatRequest: | |
| 1255 response = FileStatRequest(request); | |
| 1256 break; | |
| 1257 default: | |
| 1258 UNREACHABLE(); | |
| 1259 } | |
| 1260 } | |
| 1261 } | |
| 1262 | |
| 1263 Dart_PostCObject(reply_port_id, response->AsApiCObject()); | |
| 1264 } | |
| 1265 | |
| 1266 | |
| 1267 Dart_Port File::GetServicePort() { | |
| 1268 return file_service_.GetServicePort(); | |
| 1269 } | |
| 1270 | |
| 1271 | |
| 1272 void FUNCTION_NAME(File_NewServicePort)(Dart_NativeArguments args) { | |
| 1273 Dart_SetReturnValue(args, Dart_Null()); | |
| 1274 Dart_Port service_port = File::GetServicePort(); | |
| 1275 if (service_port != ILLEGAL_PORT) { | |
| 1276 // Return a send port for the service port. | |
| 1277 Dart_Handle send_port = Dart_NewSendPort(service_port); | |
| 1278 Dart_SetReturnValue(args, send_port); | |
| 1279 } | |
| 1280 } | |
| 1281 | |
| 1282 } // namespace bin | 1164 } // namespace bin |
| 1283 } // namespace dart | 1165 } // namespace dart |
| OLD | NEW |