| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/fileapi/obfuscated_file_util.h" | 5 #include "webkit/fileapi/obfuscated_file_util.h" |
| 6 | 6 |
| 7 #include <queue> | 7 #include <queue> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 return base::PLATFORM_FILE_ERROR_NO_SPACE; | 565 return base::PLATFORM_FILE_ERROR_NO_SPACE; |
| 566 error = NativeFileUtil::Truncate(local_path, length); | 566 error = NativeFileUtil::Truncate(local_path, length); |
| 567 if (error == base::PLATFORM_FILE_OK) { | 567 if (error == base::PLATFORM_FILE_OK) { |
| 568 UpdateUsage(context, url, growth); | 568 UpdateUsage(context, url, growth); |
| 569 context->change_observers()->Notify( | 569 context->change_observers()->Notify( |
| 570 &FileChangeObserver::OnModifyFile, MakeTuple(url)); | 570 &FileChangeObserver::OnModifyFile, MakeTuple(url)); |
| 571 } | 571 } |
| 572 return error; | 572 return error; |
| 573 } | 573 } |
| 574 | 574 |
| 575 bool ObfuscatedFileUtil::IsDirectoryEmpty( | |
| 576 FileSystemOperationContext* context, | |
| 577 const FileSystemURL& url) { | |
| 578 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | |
| 579 url.origin(), url.type(), false); | |
| 580 if (!db) | |
| 581 return true; // Not a great answer, but it's what others do. | |
| 582 FileId file_id; | |
| 583 if (!db->GetFileWithPath(url.path(), &file_id)) | |
| 584 return true; // Ditto. | |
| 585 FileInfo file_info; | |
| 586 if (!db->GetFileInfo(file_id, &file_info)) { | |
| 587 DCHECK(!file_id); | |
| 588 // It's the root directory and the database hasn't been initialized yet. | |
| 589 return true; | |
| 590 } | |
| 591 if (!file_info.is_directory()) | |
| 592 return true; | |
| 593 std::vector<FileId> children; | |
| 594 // TODO(ericu): This could easily be made faster with help from the database. | |
| 595 if (!db->ListChildren(file_id, &children)) | |
| 596 return true; | |
| 597 return children.empty(); | |
| 598 } | |
| 599 | |
| 600 PlatformFileError ObfuscatedFileUtil::CopyOrMoveFile( | 575 PlatformFileError ObfuscatedFileUtil::CopyOrMoveFile( |
| 601 FileSystemOperationContext* context, | 576 FileSystemOperationContext* context, |
| 602 const FileSystemURL& src_url, | 577 const FileSystemURL& src_url, |
| 603 const FileSystemURL& dest_url, | 578 const FileSystemURL& dest_url, |
| 604 bool copy) { | 579 bool copy) { |
| 605 // Cross-filesystem copies and moves should be handled via CopyInForeignFile. | 580 // Cross-filesystem copies and moves should be handled via CopyInForeignFile. |
| 606 DCHECK(src_url.origin() == dest_url.origin()); | 581 DCHECK(src_url.origin() == dest_url.origin()); |
| 607 DCHECK(src_url.type() == dest_url.type()); | 582 DCHECK(src_url.type() == dest_url.type()); |
| 608 | 583 |
| 609 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | 584 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 621 | 596 |
| 622 FileInfo src_file_info; | 597 FileInfo src_file_info; |
| 623 base::PlatformFileInfo src_platform_file_info; | 598 base::PlatformFileInfo src_platform_file_info; |
| 624 FilePath src_local_path; | 599 FilePath src_local_path; |
| 625 base::PlatformFileError error = GetFileInfoInternal( | 600 base::PlatformFileError error = GetFileInfoInternal( |
| 626 db, context, src_url.origin(), src_url.type(), src_file_id, | 601 db, context, src_url.origin(), src_url.type(), src_file_id, |
| 627 &src_file_info, &src_platform_file_info, &src_local_path); | 602 &src_file_info, &src_platform_file_info, &src_local_path); |
| 628 if (error != base::PLATFORM_FILE_OK) | 603 if (error != base::PLATFORM_FILE_OK) |
| 629 return error; | 604 return error; |
| 630 if (src_file_info.is_directory()) | 605 if (src_file_info.is_directory()) |
| 631 return base::PLATFORM_FILE_ERROR_FAILED; | 606 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; |
| 632 | 607 |
| 633 FileInfo dest_file_info; | 608 FileInfo dest_file_info; |
| 634 base::PlatformFileInfo dest_platform_file_info; // overwrite case only | 609 base::PlatformFileInfo dest_platform_file_info; // overwrite case only |
| 635 FilePath dest_local_path; // overwrite case only | 610 FilePath dest_local_path; // overwrite case only |
| 636 if (overwrite) { | 611 if (overwrite) { |
| 637 base::PlatformFileError error = GetFileInfoInternal( | 612 base::PlatformFileError error = GetFileInfoInternal( |
| 638 db, context, dest_url.origin(), dest_url.type(), dest_file_id, | 613 db, context, dest_url.origin(), dest_url.type(), dest_file_id, |
| 639 &dest_file_info, &dest_platform_file_info, &dest_local_path); | 614 &dest_file_info, &dest_platform_file_info, &dest_local_path); |
| 640 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) | 615 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) |
| 641 overwrite = false; // fallback to non-overwrite case | 616 overwrite = false; // fallback to non-overwrite case |
| 642 else if (error != base::PLATFORM_FILE_OK) | 617 else if (error != base::PLATFORM_FILE_OK) |
| 643 return error; | 618 return error; |
| 644 else if (dest_file_info.is_directory()) | 619 else if (dest_file_info.is_directory()) |
| 645 return base::PLATFORM_FILE_ERROR_FAILED; | 620 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
| 646 } | 621 } |
| 647 if (!overwrite) { | 622 if (!overwrite) { |
| 648 FileId dest_parent_id; | 623 FileId dest_parent_id; |
| 649 if (!db->GetFileWithPath(dest_url.path().DirName(), | 624 if (!db->GetFileWithPath(dest_url.path().DirName(), |
| 650 &dest_parent_id)) { | 625 &dest_parent_id)) { |
| 651 NOTREACHED(); // We shouldn't be called in this case. | |
| 652 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 626 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 653 } | 627 } |
| 654 | 628 |
| 655 dest_file_info = src_file_info; | 629 dest_file_info = src_file_info; |
| 656 dest_file_info.parent_id = dest_parent_id; | 630 dest_file_info.parent_id = dest_parent_id; |
| 657 dest_file_info.name = | 631 dest_file_info.name = |
| 658 VirtualPath::BaseName(dest_url.path()).value(); | 632 VirtualPath::BaseName(dest_url.path()).value(); |
| 659 } | 633 } |
| 660 | 634 |
| 661 int64 growth = 0; | 635 int64 growth = 0; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 if (overwrite) { | 735 if (overwrite) { |
| 762 FilePath dest_local_path; | 736 FilePath dest_local_path; |
| 763 base::PlatformFileError error = GetFileInfoInternal( | 737 base::PlatformFileError error = GetFileInfoInternal( |
| 764 db, context, dest_url.origin(), dest_url.type(), dest_file_id, | 738 db, context, dest_url.origin(), dest_url.type(), dest_file_id, |
| 765 &dest_file_info, &dest_platform_file_info, &dest_local_path); | 739 &dest_file_info, &dest_platform_file_info, &dest_local_path); |
| 766 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) | 740 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) |
| 767 overwrite = false; // fallback to non-overwrite case | 741 overwrite = false; // fallback to non-overwrite case |
| 768 else if (error != base::PLATFORM_FILE_OK) | 742 else if (error != base::PLATFORM_FILE_OK) |
| 769 return error; | 743 return error; |
| 770 else if (dest_file_info.is_directory()) | 744 else if (dest_file_info.is_directory()) |
| 771 return base::PLATFORM_FILE_ERROR_FAILED; | 745 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
| 772 } | 746 } |
| 773 if (!overwrite) { | 747 if (!overwrite) { |
| 774 FileId dest_parent_id; | 748 FileId dest_parent_id; |
| 775 if (!db->GetFileWithPath(dest_url.path().DirName(), | 749 if (!db->GetFileWithPath(dest_url.path().DirName(), |
| 776 &dest_parent_id) || | 750 &dest_parent_id)) { |
| 777 !dest_file_info.is_directory()) { | |
| 778 NOTREACHED(); | |
| 779 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 751 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 780 } | 752 } |
| 753 if (!dest_file_info.is_directory()) |
| 754 return base::PLATFORM_FILE_ERROR_FAILED; |
| 781 InitFileInfo(&dest_file_info, dest_parent_id, | 755 InitFileInfo(&dest_file_info, dest_parent_id, |
| 782 VirtualPath::BaseName(dest_url.path()).value()); | 756 VirtualPath::BaseName(dest_url.path()).value()); |
| 783 } | 757 } |
| 784 | 758 |
| 785 int64 growth = src_platform_file_info.size; | 759 int64 growth = src_platform_file_info.size; |
| 786 if (overwrite) | 760 if (overwrite) |
| 787 growth -= dest_platform_file_info.size; | 761 growth -= dest_platform_file_info.size; |
| 788 else | 762 else |
| 789 growth += UsageForPath(dest_file_info.name.size()); | 763 growth += UsageForPath(dest_file_info.name.size()); |
| 790 if (!AllocateQuota(context, growth)) | 764 if (!AllocateQuota(context, growth)) |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 | 832 |
| 859 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) | 833 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) |
| 860 return base::PLATFORM_FILE_OK; | 834 return base::PLATFORM_FILE_OK; |
| 861 | 835 |
| 862 error = NativeFileUtil::DeleteFile(local_path); | 836 error = NativeFileUtil::DeleteFile(local_path); |
| 863 if (base::PLATFORM_FILE_OK != error) | 837 if (base::PLATFORM_FILE_OK != error) |
| 864 LOG(WARNING) << "Leaked a backing file."; | 838 LOG(WARNING) << "Leaked a backing file."; |
| 865 return base::PLATFORM_FILE_OK; | 839 return base::PLATFORM_FILE_OK; |
| 866 } | 840 } |
| 867 | 841 |
| 868 PlatformFileError ObfuscatedFileUtil::DeleteSingleDirectory( | 842 PlatformFileError ObfuscatedFileUtil::DeleteDirectory( |
| 869 FileSystemOperationContext* context, | 843 FileSystemOperationContext* context, |
| 870 const FileSystemURL& url) { | 844 const FileSystemURL& url) { |
| 871 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | 845 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
| 872 url.origin(), url.type(), true); | 846 url.origin(), url.type(), true); |
| 873 if (!db) | 847 if (!db) |
| 874 return base::PLATFORM_FILE_ERROR_FAILED; | 848 return base::PLATFORM_FILE_ERROR_FAILED; |
| 875 | 849 |
| 876 FileId file_id; | 850 FileId file_id; |
| 877 if (!db->GetFileWithPath(url.path(), &file_id)) | 851 if (!db->GetFileWithPath(url.path(), &file_id)) |
| 878 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 852 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 879 FileInfo file_info; | 853 FileInfo file_info; |
| 880 if (!db->GetFileInfo(file_id, &file_info) || !file_info.is_directory()) { | 854 if (!db->GetFileInfo(file_id, &file_info)) { |
| 881 NOTREACHED(); | 855 NOTREACHED(); |
| 882 return base::PLATFORM_FILE_ERROR_FAILED; | 856 return base::PLATFORM_FILE_ERROR_FAILED; |
| 883 } | 857 } |
| 858 if (!file_info.is_directory()) |
| 859 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
| 884 if (!db->RemoveFileInfo(file_id)) | 860 if (!db->RemoveFileInfo(file_id)) |
| 885 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; | 861 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; |
| 886 int64 growth = -UsageForPath(file_info.name.size()); | 862 int64 growth = -UsageForPath(file_info.name.size()); |
| 887 AllocateQuota(context, growth); | 863 AllocateQuota(context, growth); |
| 888 UpdateUsage(context, url, growth); | 864 UpdateUsage(context, url, growth); |
| 889 TouchDirectory(db, file_info.parent_id); | 865 TouchDirectory(db, file_info.parent_id); |
| 890 context->change_observers()->Notify( | 866 context->change_observers()->Notify( |
| 891 &FileChangeObserver::OnRemoveDirectory, MakeTuple(url)); | 867 &FileChangeObserver::OnRemoveDirectory, MakeTuple(url)); |
| 892 return base::PLATFORM_FILE_OK; | 868 return base::PLATFORM_FILE_OK; |
| 893 } | 869 } |
| 894 | 870 |
| 895 base::PlatformFileError ObfuscatedFileUtil::CreateSnapshotFile( | 871 base::PlatformFileError ObfuscatedFileUtil::CreateSnapshotFile( |
| 896 FileSystemOperationContext* context, | 872 FileSystemOperationContext* context, |
| 897 const FileSystemURL& url, | 873 const FileSystemURL& url, |
| 898 base::PlatformFileInfo* file_info, | 874 base::PlatformFileInfo* file_info, |
| 899 FilePath* platform_path, | 875 FilePath* platform_path, |
| 900 SnapshotFilePolicy* policy) { | 876 SnapshotFilePolicy* policy) { |
| 901 DCHECK(policy); | 877 DCHECK(policy); |
| 902 // We're just returning the local file information. | 878 // We're just returning the local file information. |
| 903 *policy = kSnapshotFileLocal; | 879 *policy = kSnapshotFileLocal; |
| 904 return GetFileInfo(context, url, file_info, platform_path); | 880 base::PlatformFileError error = GetFileInfo( |
| 881 context, url, file_info, platform_path); |
| 882 if (error == base::PLATFORM_FILE_OK && file_info->is_directory) |
| 883 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; |
| 884 return error; |
| 885 } |
| 886 |
| 887 bool ObfuscatedFileUtil::IsDirectoryEmpty( |
| 888 FileSystemOperationContext* context, |
| 889 const FileSystemURL& url) { |
| 890 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
| 891 url.origin(), url.type(), false); |
| 892 if (!db) |
| 893 return true; // Not a great answer, but it's what others do. |
| 894 FileId file_id; |
| 895 if (!db->GetFileWithPath(url.path(), &file_id)) |
| 896 return true; // Ditto. |
| 897 FileInfo file_info; |
| 898 if (!db->GetFileInfo(file_id, &file_info)) { |
| 899 DCHECK(!file_id); |
| 900 // It's the root directory and the database hasn't been initialized yet. |
| 901 return true; |
| 902 } |
| 903 if (!file_info.is_directory()) |
| 904 return true; |
| 905 std::vector<FileId> children; |
| 906 // TODO(ericu): This could easily be made faster with help from the database. |
| 907 if (!db->ListChildren(file_id, &children)) |
| 908 return true; |
| 909 return children.empty(); |
| 905 } | 910 } |
| 906 | 911 |
| 907 FilePath ObfuscatedFileUtil::GetDirectoryForOriginAndType( | 912 FilePath ObfuscatedFileUtil::GetDirectoryForOriginAndType( |
| 908 const GURL& origin, | 913 const GURL& origin, |
| 909 FileSystemType type, | 914 FileSystemType type, |
| 910 bool create, | 915 bool create, |
| 911 base::PlatformFileError* error_code) { | 916 base::PlatformFileError* error_code) { |
| 912 FilePath origin_dir = GetDirectoryForOrigin(origin, create, error_code); | 917 FilePath origin_dir = GetDirectoryForOrigin(origin, create, error_code); |
| 913 if (origin_dir.empty()) | 918 if (origin_dir.empty()) |
| 914 return FilePath(); | 919 return FilePath(); |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1323 error = NativeFileUtil::CreateDirectory( | 1328 error = NativeFileUtil::CreateDirectory( |
| 1324 new_local_path, false /* exclusive */, false /* recursive */); | 1329 new_local_path, false /* exclusive */, false /* recursive */); |
| 1325 if (error != base::PLATFORM_FILE_OK) | 1330 if (error != base::PLATFORM_FILE_OK) |
| 1326 return error; | 1331 return error; |
| 1327 | 1332 |
| 1328 *local_path = new_local_path.AppendASCII(StringPrintf("%08" PRId64, number)); | 1333 *local_path = new_local_path.AppendASCII(StringPrintf("%08" PRId64, number)); |
| 1329 return base::PLATFORM_FILE_OK; | 1334 return base::PLATFORM_FILE_OK; |
| 1330 } | 1335 } |
| 1331 | 1336 |
| 1332 } // namespace fileapi | 1337 } // namespace fileapi |
| OLD | NEW |