Index: webkit/fileapi/obfuscated_file_util.cc |
diff --git a/webkit/fileapi/obfuscated_file_system_file_util.cc b/webkit/fileapi/obfuscated_file_util.cc |
similarity index 91% |
rename from webkit/fileapi/obfuscated_file_system_file_util.cc |
rename to webkit/fileapi/obfuscated_file_util.cc |
index dc6b70e80461d2299a24a73e14a8aae02f51cbcc..68bf381e8a4bb80823f6db8eed9c95839e33450a 100644 |
--- a/webkit/fileapi/obfuscated_file_system_file_util.cc |
+++ b/webkit/fileapi/obfuscated_file_util.cc |
@@ -2,7 +2,7 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "webkit/fileapi/obfuscated_file_system_file_util.h" |
+#include "webkit/fileapi/obfuscated_file_util.h" |
#include <queue> |
#include <vector> |
@@ -103,18 +103,134 @@ namespace fileapi { |
using base::PlatformFile; |
using base::PlatformFileError; |
-ObfuscatedFileSystemFileUtil::ObfuscatedFileSystemFileUtil( |
+class ObfuscatedFileEnumerator |
+ : public FileSystemFileUtil::AbstractFileEnumerator { |
+ public: |
+ ObfuscatedFileEnumerator( |
+ FileSystemDirectoryDatabase* db, const FilePath& virtual_root_path) |
+ : db_(db) { |
+ FileId file_id; |
+ FileInfo file_info; |
+ if (!db_->GetFileWithPath(virtual_root_path, &file_id)) |
+ return; |
+ if (!db_->GetFileInfo(file_id, &file_info)) |
+ return; |
+ if (!file_info.is_directory()) |
+ return; |
+ FileRecord record = { file_id, file_info, virtual_root_path }; |
+ display_queue_.push(record); |
+ Next(); // Enumerators don't include the directory itself. |
+ } |
+ |
+ ~ObfuscatedFileEnumerator() {} |
+ |
+ virtual FilePath Next() { |
+ ProcessRecurseQueue(); |
+ if (display_queue_.empty()) |
+ return FilePath(); |
+ current_ = display_queue_.front(); |
+ display_queue_.pop(); |
+ if (current_.file_info.is_directory()) |
+ recurse_queue_.push(current_); |
+ return current_.file_path; |
+ } |
+ |
+ virtual bool IsDirectory() { |
+ return current_.file_info.is_directory(); |
+ } |
+ |
+ private: |
+ typedef FileSystemDirectoryDatabase::FileId FileId; |
+ typedef FileSystemDirectoryDatabase::FileInfo FileInfo; |
+ |
+ struct FileRecord { |
+ FileId file_id; |
+ FileInfo file_info; |
+ FilePath file_path; |
+ }; |
+ |
+ void ProcessRecurseQueue() { |
+ while (display_queue_.empty() && !recurse_queue_.empty()) { |
+ FileRecord directory = recurse_queue_.front(); |
+ std::vector<FileId> children; |
+ recurse_queue_.pop(); |
+ if (!db_->ListChildren(directory.file_id, &children)) |
+ return; |
+ std::vector<FileId>::iterator iter; |
+ for (iter = children.begin(); iter != children.end(); ++iter) { |
+ FileRecord child; |
+ child.file_id = *iter; |
+ if (!db_->GetFileInfo(child.file_id, &child.file_info)) |
+ return; |
+ child.file_path = directory.file_path.Append(child.file_info.name); |
+ display_queue_.push(child); |
+ } |
+ } |
+ } |
+ |
+ std::queue<FileRecord> display_queue_; |
+ std::queue<FileRecord> recurse_queue_; |
+ FileRecord current_; |
+ FileSystemDirectoryDatabase* db_; |
+}; |
+ |
+class ObfuscatedOriginEnumerator |
+ : public ObfuscatedFileUtil::AbstractOriginEnumerator { |
+ public: |
+ typedef FileSystemOriginDatabase::OriginRecord OriginRecord; |
+ ObfuscatedOriginEnumerator( |
+ FileSystemOriginDatabase* origin_database, |
+ const FilePath& base_path) |
+ : base_path_(base_path) { |
+ if (origin_database) |
+ origin_database->ListAllOrigins(&origins_); |
+ } |
+ |
+ ~ObfuscatedOriginEnumerator() {} |
+ |
+ // Returns the next origin. Returns empty if there are no more origins. |
+ virtual GURL Next() OVERRIDE { |
+ OriginRecord record; |
+ if (!origins_.empty()) { |
+ record = origins_.back(); |
+ origins_.pop_back(); |
+ } |
+ current_ = record; |
+ return GetOriginURLFromIdentifier(record.origin); |
+ } |
+ |
+ // Returns the current origin's information. |
+ virtual bool HasFileSystemType(FileSystemType type) const OVERRIDE { |
+ if (current_.path.empty()) |
+ return false; |
+ FilePath::StringType type_string = |
+ ObfuscatedFileUtil::GetDirectoryNameForType(type); |
+ if (type_string.empty()) { |
+ NOTREACHED(); |
+ return false; |
+ } |
+ FilePath path = base_path_.Append(current_.path).Append(type_string); |
+ return file_util::DirectoryExists(path); |
+ } |
+ |
+ private: |
+ std::vector<OriginRecord> origins_; |
+ OriginRecord current_; |
+ FilePath base_path_; |
+}; |
+ |
+ObfuscatedFileUtil::ObfuscatedFileUtil( |
const FilePath& file_system_directory, |
FileSystemFileUtil* underlying_file_util) |
- : file_system_directory_(file_system_directory), |
- underlying_file_util_(underlying_file_util) { |
+ : FileSystemFileUtil(underlying_file_util), |
+ file_system_directory_(file_system_directory) { |
} |
-ObfuscatedFileSystemFileUtil::~ObfuscatedFileSystemFileUtil() { |
+ObfuscatedFileUtil::~ObfuscatedFileUtil() { |
DropDatabases(); |
} |
-PlatformFileError ObfuscatedFileSystemFileUtil::CreateOrOpen( |
+PlatformFileError ObfuscatedFileUtil::CreateOrOpen( |
FileSystemOperationContext* context, |
const FilePath& virtual_path, int file_flags, |
PlatformFile* file_handle, bool* created) { |
@@ -157,11 +273,11 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CreateOrOpen( |
return base::PLATFORM_FILE_ERROR_NOT_A_FILE; |
FilePath data_path = DataPathToLocalPath(context->src_origin_url(), |
context->src_type(), file_info.data_path); |
- return underlying_file_util_->CreateOrOpen( |
+ return underlying_file_util()->CreateOrOpen( |
context, data_path, file_flags, file_handle, created); |
} |
-PlatformFileError ObfuscatedFileSystemFileUtil::EnsureFileExists( |
+PlatformFileError ObfuscatedFileUtil::EnsureFileExists( |
FileSystemOperationContext* context, |
const FilePath& virtual_path, |
bool* created) { |
@@ -197,21 +313,62 @@ PlatformFileError ObfuscatedFileSystemFileUtil::EnsureFileExists( |
return error; |
} |
-PlatformFileError ObfuscatedFileSystemFileUtil::GetLocalFilePath( |
+PlatformFileError ObfuscatedFileUtil::CreateDirectory( |
FileSystemOperationContext* context, |
const FilePath& virtual_path, |
- FilePath* local_path) { |
- FilePath path = |
- GetLocalPath(context->src_origin_url(), context->src_type(), |
- virtual_path); |
- if (path.empty()) |
- return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
+ bool exclusive, |
+ bool recursive) { |
+ FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
+ context->src_origin_url(), context->src_type(), true); |
+ if (!db) |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+ FileId file_id; |
+ if (db->GetFileWithPath(virtual_path, &file_id)) { |
+ FileInfo file_info; |
+ if (exclusive) |
+ return base::PLATFORM_FILE_ERROR_EXISTS; |
+ if (!db->GetFileInfo(file_id, &file_info)) { |
+ NOTREACHED(); |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+ } |
+ if (!file_info.is_directory()) |
+ return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
+ return base::PLATFORM_FILE_OK; |
+ } |
- *local_path = path; |
+ std::vector<FilePath::StringType> components; |
+ virtual_path.GetComponents(&components); |
+ FileId parent_id = 0; |
+ size_t index; |
+ for (index = 0; index < components.size(); ++index) { |
+ FilePath::StringType name = components[index]; |
+ if (name == FILE_PATH_LITERAL("/")) |
+ continue; |
+ if (!db->GetChildWithName(parent_id, name, &parent_id)) |
+ break; |
+ } |
+ if (!recursive && components.size() - index > 1) |
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
+ for (; index < components.size(); ++index) { |
+ FileInfo file_info; |
+ file_info.name = components[index]; |
+ if (file_info.name == FILE_PATH_LITERAL("/")) |
+ continue; |
+ file_info.modification_time = base::Time::Now(); |
+ file_info.parent_id = parent_id; |
+ if (!AllocateQuotaForPath(context, 1, file_info.name.size())) |
+ return base::PLATFORM_FILE_ERROR_NO_SPACE; |
+ if (!db->AddFileInfo(file_info, &parent_id)) { |
+ NOTREACHED(); |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+ } |
+ UpdatePathQuotaUsage(context, context->src_origin_url(), |
+ context->src_type(), 1, file_info.name.size()); |
+ } |
return base::PLATFORM_FILE_OK; |
} |
-PlatformFileError ObfuscatedFileSystemFileUtil::GetFileInfo( |
+PlatformFileError ObfuscatedFileUtil::GetFileInfo( |
FileSystemOperationContext* context, |
const FilePath& virtual_path, |
base::PlatformFileInfo* file_info, |
@@ -228,7 +385,7 @@ PlatformFileError ObfuscatedFileSystemFileUtil::GetFileInfo( |
&local_info, file_info, platform_file_path); |
} |
-PlatformFileError ObfuscatedFileSystemFileUtil::ReadDirectory( |
+PlatformFileError ObfuscatedFileUtil::ReadDirectory( |
FileSystemOperationContext* context, |
const FilePath& virtual_path, |
std::vector<base::FileUtilProxy::Entry>* entries) { |
@@ -281,11 +438,36 @@ PlatformFileError ObfuscatedFileSystemFileUtil::ReadDirectory( |
return base::PLATFORM_FILE_OK; |
} |
-PlatformFileError ObfuscatedFileSystemFileUtil::CreateDirectory( |
+FileSystemFileUtil::AbstractFileEnumerator* |
+ObfuscatedFileUtil::CreateFileEnumerator( |
+ FileSystemOperationContext* context, |
+ const FilePath& root_path) { |
+ FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
+ context->src_origin_url(), context->src_type(), false); |
+ if (!db) |
+ return new FileSystemFileUtil::EmptyFileEnumerator(); |
+ return new ObfuscatedFileEnumerator(db, root_path); |
+} |
+ |
+PlatformFileError ObfuscatedFileUtil::GetLocalFilePath( |
FileSystemOperationContext* context, |
const FilePath& virtual_path, |
- bool exclusive, |
- bool recursive) { |
+ FilePath* local_path) { |
+ FilePath path = |
+ GetLocalPath(context->src_origin_url(), context->src_type(), |
+ virtual_path); |
+ if (path.empty()) |
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
+ |
+ *local_path = path; |
+ return base::PLATFORM_FILE_OK; |
+} |
+ |
+PlatformFileError ObfuscatedFileUtil::Touch( |
+ FileSystemOperationContext* context, |
+ const FilePath& virtual_path, |
+ const base::Time& last_access_time, |
+ const base::Time& last_modified_time) { |
FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
context->src_origin_url(), context->src_type(), true); |
if (!db) |
@@ -293,57 +475,127 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CreateDirectory( |
FileId file_id; |
if (db->GetFileWithPath(virtual_path, &file_id)) { |
FileInfo file_info; |
- if (exclusive) |
- return base::PLATFORM_FILE_ERROR_EXISTS; |
if (!db->GetFileInfo(file_id, &file_info)) { |
NOTREACHED(); |
return base::PLATFORM_FILE_ERROR_FAILED; |
} |
- if (!file_info.is_directory()) |
- return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
- return base::PLATFORM_FILE_OK; |
- } |
- |
- std::vector<FilePath::StringType> components; |
- virtual_path.GetComponents(&components); |
- FileId parent_id = 0; |
- size_t index; |
- for (index = 0; index < components.size(); ++index) { |
- FilePath::StringType name = components[index]; |
- if (name == FILE_PATH_LITERAL("/")) |
- continue; |
- if (!db->GetChildWithName(parent_id, name, &parent_id)) |
- break; |
- } |
- if (!recursive && components.size() - index > 1) |
- return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
- for (; index < components.size(); ++index) { |
- FileInfo file_info; |
- file_info.name = components[index]; |
- if (file_info.name == FILE_PATH_LITERAL("/")) |
- continue; |
- file_info.modification_time = base::Time::Now(); |
- file_info.parent_id = parent_id; |
- if (!AllocateQuotaForPath(context, 1, file_info.name.size())) |
- return base::PLATFORM_FILE_ERROR_NO_SPACE; |
- if (!db->AddFileInfo(file_info, &parent_id)) { |
- NOTREACHED(); |
- return base::PLATFORM_FILE_ERROR_FAILED; |
+ if (file_info.is_directory()) { |
+ file_info.modification_time = last_modified_time; |
+ if (!db->UpdateFileInfo(file_id, file_info)) |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+ return base::PLATFORM_FILE_OK; |
} |
- UpdatePathQuotaUsage(context, context->src_origin_url(), |
- context->src_type(), 1, file_info.name.size()); |
+ FilePath data_path = DataPathToLocalPath(context->src_origin_url(), |
+ context->src_type(), file_info.data_path); |
+ return underlying_file_util()->Touch( |
+ context, data_path, last_access_time, last_modified_time); |
} |
- return base::PLATFORM_FILE_OK; |
+ FileId parent_id; |
+ if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) |
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
+ |
+ FileInfo file_info; |
+ InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value()); |
+ // In the event of a sporadic underlying failure, we might create a new file, |
+ // but fail to update its mtime + atime. |
+ if (!AllocateQuotaForPath(context, 1, file_info.name.size())) |
+ return base::PLATFORM_FILE_ERROR_NO_SPACE; |
+ PlatformFileError error = CreateFile(context, context->src_origin_url(), |
+ context->src_type(), FilePath(), &file_info, 0, NULL); |
+ if (base::PLATFORM_FILE_OK != error) |
+ return error; |
+ |
+ FilePath data_path = DataPathToLocalPath(context->src_origin_url(), |
+ context->src_type(), file_info.data_path); |
+ return underlying_file_util()->Touch(context, data_path, |
+ last_access_time, last_modified_time); |
} |
-PlatformFileError ObfuscatedFileSystemFileUtil::CopyOrMoveFile( |
+PlatformFileError ObfuscatedFileUtil::Truncate( |
FileSystemOperationContext* context, |
- const FilePath& src_file_path, |
- const FilePath& dest_file_path, |
- bool copy) { |
- // Cross-filesystem copies and moves should be handled via CopyInForeignFile. |
- DCHECK(context->src_origin_url() == context->dest_origin_url()); |
- DCHECK(context->src_type() == context->dest_type()); |
+ const FilePath& virtual_path, |
+ int64 length) { |
+ FilePath local_path = |
+ GetLocalPath(context->src_origin_url(), context->src_type(), |
+ virtual_path); |
+ if (local_path.empty()) |
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
+ return underlying_file_util()->Truncate( |
+ context, local_path, length); |
+} |
+ |
+bool ObfuscatedFileUtil::PathExists( |
+ FileSystemOperationContext* context, |
+ const FilePath& virtual_path) { |
+ FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
+ context->src_origin_url(), context->src_type(), false); |
+ if (!db) |
+ return false; |
+ FileId file_id; |
+ return db->GetFileWithPath(virtual_path, &file_id); |
+} |
+ |
+bool ObfuscatedFileUtil::DirectoryExists( |
+ FileSystemOperationContext* context, |
+ const FilePath& virtual_path) { |
+ if (IsRootDirectory(virtual_path)) { |
+ // It's questionable whether we should return true or false for the |
+ // root directory of nonexistent origin, but here we return true |
+ // as the current implementation of ReadDirectory always returns an empty |
+ // array (rather than erroring out with NOT_FOUND_ERR even) for |
+ // nonexistent origins. |
+ // Note: if you're going to change this behavior please also consider |
+ // changiing the ReadDirectory's behavior! |
+ return true; |
+ } |
+ FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
+ context->src_origin_url(), context->src_type(), false); |
+ if (!db) |
+ return false; |
+ FileId file_id; |
+ if (!db->GetFileWithPath(virtual_path, &file_id)) |
+ return false; |
+ FileInfo file_info; |
+ if (!db->GetFileInfo(file_id, &file_info)) { |
+ NOTREACHED(); |
+ return false; |
+ } |
+ return file_info.is_directory(); |
+} |
+ |
+bool ObfuscatedFileUtil::IsDirectoryEmpty( |
+ FileSystemOperationContext* context, |
+ const FilePath& virtual_path) { |
+ FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
+ context->src_origin_url(), context->src_type(), false); |
+ if (!db) |
+ return true; // Not a great answer, but it's what others do. |
+ FileId file_id; |
+ if (!db->GetFileWithPath(virtual_path, &file_id)) |
+ return true; // Ditto. |
+ FileInfo file_info; |
+ if (!db->GetFileInfo(file_id, &file_info)) { |
+ DCHECK(!file_id); |
+ // It's the root directory and the database hasn't been initialized yet. |
+ return true; |
+ } |
+ if (!file_info.is_directory()) |
+ return true; |
+ std::vector<FileId> children; |
+ // TODO(ericu): This could easily be made faster with help from the database. |
+ if (!db->ListChildren(file_id, &children)) |
+ return true; |
+ return children.empty(); |
+} |
+ |
+PlatformFileError ObfuscatedFileUtil::CopyOrMoveFile( |
+ FileSystemOperationContext* context, |
+ const FilePath& src_file_path, |
+ const FilePath& dest_file_path, |
+ bool copy) { |
+ // Cross-filesystem copies and moves should be handled via CopyInForeignFile. |
+ DCHECK(context->src_origin_url() == context->dest_origin_url()); |
+ DCHECK(context->src_type() == context->dest_type()); |
FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
context->src_origin_url(), context->src_type(), true); |
@@ -388,7 +640,7 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CopyOrMoveFile( |
if (overwrite) { |
FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(), |
context->src_type(), dest_file_info.data_path); |
- return underlying_file_util_->CopyOrMoveFile(context, |
+ return underlying_file_util()->CopyOrMoveFile(context, |
src_data_path, dest_data_path, copy); |
} else { |
FileId dest_parent_id; |
@@ -413,7 +665,7 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CopyOrMoveFile( |
FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(), |
context->src_type(), dest_file_info.data_path); |
if (base::PLATFORM_FILE_OK != |
- underlying_file_util_->DeleteFile(context, dest_data_path)) |
+ underlying_file_util()->DeleteFile(context, dest_data_path)) |
LOG(WARNING) << "Leaked a backing file."; |
UpdatePathQuotaUsage(context, context->src_origin_url(), |
context->src_type(), -1, |
@@ -445,7 +697,7 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CopyOrMoveFile( |
return base::PLATFORM_FILE_ERROR_FAILED; |
} |
-PlatformFileError ObfuscatedFileSystemFileUtil::CopyInForeignFile( |
+PlatformFileError ObfuscatedFileUtil::CopyInForeignFile( |
FileSystemOperationContext* context, |
const FilePath& src_file_path, |
const FilePath& dest_file_path) { |
@@ -460,468 +712,82 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CopyInForeignFile( |
if (!db->GetFileInfo(dest_file_id, &dest_file_info) || |
dest_file_info.is_directory()) { |
NOTREACHED(); |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- } |
- FilePath dest_data_path = DataPathToLocalPath(context->dest_origin_url(), |
- context->dest_type(), dest_file_info.data_path); |
- return underlying_file_util_->CopyOrMoveFile(context, |
- src_file_path, dest_data_path, true /* copy */); |
- } else { |
- FileId dest_parent_id; |
- if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { |
- NOTREACHED(); // We shouldn't be called in this case. |
- return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
- } |
- InitFileInfo(&dest_file_info, dest_parent_id, |
- dest_file_path.BaseName().value()); |
- if (!AllocateQuotaForPath(context, 1, dest_file_info.name.size())) |
- return base::PLATFORM_FILE_ERROR_NO_SPACE; |
- return CreateFile(context, context->dest_origin_url(), |
- context->dest_type(), src_file_path, &dest_file_info, 0, NULL); |
- } |
- return base::PLATFORM_FILE_ERROR_FAILED; |
-} |
- |
-PlatformFileError ObfuscatedFileSystemFileUtil::DeleteFile( |
- FileSystemOperationContext* context, |
- const FilePath& virtual_path) { |
- FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
- context->src_origin_url(), context->src_type(), true); |
- if (!db) |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- FileId file_id; |
- if (!db->GetFileWithPath(virtual_path, &file_id)) |
- return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
- FileInfo file_info; |
- if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) { |
- NOTREACHED(); |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- } |
- if (!db->RemoveFileInfo(file_id)) { |
- NOTREACHED(); |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- } |
- AllocateQuotaForPath(context, -1, -static_cast<int64>(file_info.name.size())); |
- UpdatePathQuotaUsage(context, context->src_origin_url(), context->src_type(), |
- -1, -static_cast<int64>(file_info.name.size())); |
- FilePath data_path = DataPathToLocalPath(context->src_origin_url(), |
- context->src_type(), file_info.data_path); |
- if (base::PLATFORM_FILE_OK != |
- underlying_file_util_->DeleteFile(context, data_path)) |
- LOG(WARNING) << "Leaked a backing file."; |
- return base::PLATFORM_FILE_OK; |
-} |
- |
-PlatformFileError ObfuscatedFileSystemFileUtil::DeleteSingleDirectory( |
- FileSystemOperationContext* context, |
- const FilePath& virtual_path) { |
- FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
- context->src_origin_url(), context->src_type(), true); |
- if (!db) |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- FileId file_id; |
- if (!db->GetFileWithPath(virtual_path, &file_id)) |
- return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
- FileInfo file_info; |
- if (!db->GetFileInfo(file_id, &file_info) || !file_info.is_directory()) { |
- NOTREACHED(); |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- } |
- if (!db->RemoveFileInfo(file_id)) |
- return base::PLATFORM_FILE_ERROR_NOT_EMPTY; |
- AllocateQuotaForPath(context, -1, -static_cast<int64>(file_info.name.size())); |
- UpdatePathQuotaUsage(context, context->src_origin_url(), context->src_type(), |
- -1, -static_cast<int64>(file_info.name.size())); |
- return base::PLATFORM_FILE_OK; |
-} |
- |
-PlatformFileError ObfuscatedFileSystemFileUtil::Touch( |
- FileSystemOperationContext* context, |
- const FilePath& virtual_path, |
- const base::Time& last_access_time, |
- const base::Time& last_modified_time) { |
- FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
- context->src_origin_url(), context->src_type(), true); |
- if (!db) |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- FileId file_id; |
- if (db->GetFileWithPath(virtual_path, &file_id)) { |
- FileInfo file_info; |
- if (!db->GetFileInfo(file_id, &file_info)) { |
- NOTREACHED(); |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- } |
- if (file_info.is_directory()) { |
- file_info.modification_time = last_modified_time; |
- if (!db->UpdateFileInfo(file_id, file_info)) |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- return base::PLATFORM_FILE_OK; |
- } |
- FilePath data_path = DataPathToLocalPath(context->src_origin_url(), |
- context->src_type(), file_info.data_path); |
- return underlying_file_util_->Touch( |
- context, data_path, last_access_time, last_modified_time); |
- } |
- FileId parent_id; |
- if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) |
- return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
- |
- FileInfo file_info; |
- InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value()); |
- // In the event of a sporadic underlying failure, we might create a new file, |
- // but fail to update its mtime + atime. |
- if (!AllocateQuotaForPath(context, 1, file_info.name.size())) |
- return base::PLATFORM_FILE_ERROR_NO_SPACE; |
- PlatformFileError error = CreateFile(context, context->src_origin_url(), |
- context->src_type(), FilePath(), &file_info, 0, NULL); |
- if (base::PLATFORM_FILE_OK != error) |
- return error; |
- |
- FilePath data_path = DataPathToLocalPath(context->src_origin_url(), |
- context->src_type(), file_info.data_path); |
- return underlying_file_util_->Touch(context, data_path, |
- last_access_time, last_modified_time); |
-} |
- |
-PlatformFileError ObfuscatedFileSystemFileUtil::Truncate( |
- FileSystemOperationContext* context, |
- const FilePath& virtual_path, |
- int64 length) { |
- FilePath local_path = |
- GetLocalPath(context->src_origin_url(), context->src_type(), |
- virtual_path); |
- if (local_path.empty()) |
- return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
- return underlying_file_util_->Truncate( |
- context, local_path, length); |
-} |
- |
-bool ObfuscatedFileSystemFileUtil::PathExists( |
- FileSystemOperationContext* context, |
- const FilePath& virtual_path) { |
- FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
- context->src_origin_url(), context->src_type(), false); |
- if (!db) |
- return false; |
- FileId file_id; |
- return db->GetFileWithPath(virtual_path, &file_id); |
-} |
- |
-bool ObfuscatedFileSystemFileUtil::DirectoryExists( |
- FileSystemOperationContext* context, |
- const FilePath& virtual_path) { |
- if (IsRootDirectory(virtual_path)) { |
- // It's questionable whether we should return true or false for the |
- // root directory of nonexistent origin, but here we return true |
- // as the current implementation of ReadDirectory always returns an empty |
- // array (rather than erroring out with NOT_FOUND_ERR even) for |
- // nonexistent origins. |
- // Note: if you're going to change this behavior please also consider |
- // changiing the ReadDirectory's behavior! |
- return true; |
- } |
- FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
- context->src_origin_url(), context->src_type(), false); |
- if (!db) |
- return false; |
- FileId file_id; |
- if (!db->GetFileWithPath(virtual_path, &file_id)) |
- return false; |
- FileInfo file_info; |
- if (!db->GetFileInfo(file_id, &file_info)) { |
- NOTREACHED(); |
- return false; |
- } |
- return file_info.is_directory(); |
-} |
- |
-bool ObfuscatedFileSystemFileUtil::IsDirectoryEmpty( |
- FileSystemOperationContext* context, |
- const FilePath& virtual_path) { |
- FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
- context->src_origin_url(), context->src_type(), false); |
- if (!db) |
- return true; // Not a great answer, but it's what others do. |
- FileId file_id; |
- if (!db->GetFileWithPath(virtual_path, &file_id)) |
- return true; // Ditto. |
- FileInfo file_info; |
- if (!db->GetFileInfo(file_id, &file_info)) { |
- DCHECK(!file_id); |
- // It's the root directory and the database hasn't been initialized yet. |
- return true; |
- } |
- if (!file_info.is_directory()) |
- return true; |
- std::vector<FileId> children; |
- // TODO(ericu): This could easily be made faster with help from the database. |
- if (!db->ListChildren(file_id, &children)) |
- return true; |
- return children.empty(); |
-} |
- |
-class ObfuscatedFileSystemFileEnumerator |
- : public FileSystemFileUtil::AbstractFileEnumerator { |
- public: |
- ObfuscatedFileSystemFileEnumerator( |
- FileSystemDirectoryDatabase* db, const FilePath& virtual_root_path) |
- : db_(db) { |
- FileId file_id; |
- FileInfo file_info; |
- if (!db_->GetFileWithPath(virtual_root_path, &file_id)) |
- return; |
- if (!db_->GetFileInfo(file_id, &file_info)) |
- return; |
- if (!file_info.is_directory()) |
- return; |
- FileRecord record = { file_id, file_info, virtual_root_path }; |
- display_queue_.push(record); |
- Next(); // Enumerators don't include the directory itself. |
- } |
- |
- ~ObfuscatedFileSystemFileEnumerator() {} |
- |
- virtual FilePath Next() { |
- ProcessRecurseQueue(); |
- if (display_queue_.empty()) |
- return FilePath(); |
- current_ = display_queue_.front(); |
- display_queue_.pop(); |
- if (current_.file_info.is_directory()) |
- recurse_queue_.push(current_); |
- return current_.file_path; |
- } |
- |
- virtual bool IsDirectory() { |
- return current_.file_info.is_directory(); |
- } |
- |
- private: |
- typedef FileSystemDirectoryDatabase::FileId FileId; |
- typedef FileSystemDirectoryDatabase::FileInfo FileInfo; |
- |
- struct FileRecord { |
- FileId file_id; |
- FileInfo file_info; |
- FilePath file_path; |
- }; |
- |
- void ProcessRecurseQueue() { |
- while (display_queue_.empty() && !recurse_queue_.empty()) { |
- FileRecord directory = recurse_queue_.front(); |
- std::vector<FileId> children; |
- recurse_queue_.pop(); |
- if (!db_->ListChildren(directory.file_id, &children)) |
- return; |
- std::vector<FileId>::iterator iter; |
- for (iter = children.begin(); iter != children.end(); ++iter) { |
- FileRecord child; |
- child.file_id = *iter; |
- if (!db_->GetFileInfo(child.file_id, &child.file_info)) |
- return; |
- child.file_path = directory.file_path.Append(child.file_info.name); |
- display_queue_.push(child); |
- } |
- } |
- } |
- |
- std::queue<FileRecord> display_queue_; |
- std::queue<FileRecord> recurse_queue_; |
- FileRecord current_; |
- FileSystemDirectoryDatabase* db_; |
-}; |
- |
-class ObfuscatedFileSystemOriginEnumerator |
- : public ObfuscatedFileSystemFileUtil::AbstractOriginEnumerator { |
- public: |
- typedef FileSystemOriginDatabase::OriginRecord OriginRecord; |
- ObfuscatedFileSystemOriginEnumerator( |
- FileSystemOriginDatabase* origin_database, |
- const FilePath& base_path) |
- : base_path_(base_path) { |
- if (origin_database) |
- origin_database->ListAllOrigins(&origins_); |
- } |
- |
- ~ObfuscatedFileSystemOriginEnumerator() {} |
- |
- // Returns the next origin. Returns empty if there are no more origins. |
- virtual GURL Next() OVERRIDE { |
- OriginRecord record; |
- if (!origins_.empty()) { |
- record = origins_.back(); |
- origins_.pop_back(); |
- } |
- current_ = record; |
- return GetOriginURLFromIdentifier(record.origin); |
- } |
- |
- // Returns the current origin's information. |
- virtual bool HasFileSystemType(FileSystemType type) const OVERRIDE { |
- if (current_.path.empty()) |
- return false; |
- FilePath::StringType type_string = |
- ObfuscatedFileSystemFileUtil::GetDirectoryNameForType(type); |
- if (type_string.empty()) { |
- NOTREACHED(); |
- return false; |
- } |
- FilePath path = base_path_.Append(current_.path).Append(type_string); |
- return file_util::DirectoryExists(path); |
- } |
- |
- private: |
- std::vector<OriginRecord> origins_; |
- OriginRecord current_; |
- FilePath base_path_; |
-}; |
- |
-ObfuscatedFileSystemFileUtil::AbstractOriginEnumerator* |
-ObfuscatedFileSystemFileUtil::CreateOriginEnumerator() { |
- std::vector<FileSystemOriginDatabase::OriginRecord> origins; |
- |
- InitOriginDatabase(false); |
- return new ObfuscatedFileSystemOriginEnumerator( |
- origin_database_.get(), file_system_directory_); |
-} |
- |
-FileSystemFileUtil::AbstractFileEnumerator* |
-ObfuscatedFileSystemFileUtil::CreateFileEnumerator( |
- FileSystemOperationContext* context, |
- const FilePath& root_path) { |
- FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
- context->src_origin_url(), context->src_type(), false); |
- if (!db) |
- return new FileSystemFileUtil::EmptyFileEnumerator(); |
- return new ObfuscatedFileSystemFileEnumerator(db, root_path); |
-} |
- |
-PlatformFileError ObfuscatedFileSystemFileUtil::GetFileInfoInternal( |
- FileSystemDirectoryDatabase* db, |
- FileSystemOperationContext* context, |
- FileId file_id, |
- FileInfo* local_info, |
- base::PlatformFileInfo* file_info, |
- FilePath* platform_file_path) { |
- DCHECK(db); |
- DCHECK(context); |
- DCHECK(file_info); |
- DCHECK(platform_file_path); |
- |
- if (!db->GetFileInfo(file_id, local_info)) { |
- NOTREACHED(); |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- } |
- |
- if (local_info->is_directory()) { |
- file_info->is_directory = true; |
- file_info->is_symbolic_link = false; |
- file_info->last_modified = local_info->modification_time; |
- *platform_file_path = FilePath(); |
- // We don't fill in ctime or atime. |
- return base::PLATFORM_FILE_OK; |
- } |
- if (local_info->data_path.empty()) |
- return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
- FilePath data_path = DataPathToLocalPath(context->src_origin_url(), |
- context->src_type(), local_info->data_path); |
- return underlying_file_util_->GetFileInfo( |
- context, data_path, file_info, platform_file_path); |
-} |
- |
-PlatformFileError ObfuscatedFileSystemFileUtil::CreateFile( |
- FileSystemOperationContext* context, |
- const GURL& origin_url, FileSystemType type, const FilePath& source_path, |
- FileInfo* file_info, int file_flags, PlatformFile* handle) { |
- if (handle) |
- *handle = base::kInvalidPlatformFileValue; |
- FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
- origin_url, type, true); |
- int64 number; |
- if (!db || !db->GetNextInteger(&number)) |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- // We use the third- and fourth-to-last digits as the directory. |
- int64 directory_number = number % 10000 / 100; |
- FilePath path = |
- GetDirectoryForOriginAndType(origin_url, type, false); |
- if (path.empty()) |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- |
- path = path.AppendASCII(StringPrintf("%02" PRIu64, directory_number)); |
- PlatformFileError error; |
- error = underlying_file_util_->CreateDirectory( |
- context, path, false /* exclusive */, false /* recursive */); |
- if (base::PLATFORM_FILE_OK != error) |
- return error; |
- path = path.AppendASCII(StringPrintf("%08" PRIu64, number)); |
- FilePath data_path = LocalPathToDataPath(origin_url, type, path); |
- if (data_path.empty()) |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- bool created = false; |
- if (!source_path.empty()) { |
- DCHECK(!file_flags); |
- DCHECK(!handle); |
- error = underlying_file_util_->CopyOrMoveFile( |
- context, source_path, path, true /* copy */); |
- created = true; |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+ } |
+ FilePath dest_data_path = DataPathToLocalPath(context->dest_origin_url(), |
+ context->dest_type(), dest_file_info.data_path); |
+ return underlying_file_util()->CopyOrMoveFile(context, |
+ src_file_path, dest_data_path, true /* copy */); |
} else { |
- if (handle) { |
- error = underlying_file_util_->CreateOrOpen( |
- context, path, file_flags, handle, &created); |
- // If this succeeds, we must close handle on any subsequent error. |
- } else { |
- DCHECK(!file_flags); // file_flags is only used by CreateOrOpen. |
- error = underlying_file_util_->EnsureFileExists( |
- context, path, &created); |
+ FileId dest_parent_id; |
+ if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { |
+ NOTREACHED(); // We shouldn't be called in this case. |
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
} |
+ InitFileInfo(&dest_file_info, dest_parent_id, |
+ dest_file_path.BaseName().value()); |
+ if (!AllocateQuotaForPath(context, 1, dest_file_info.name.size())) |
+ return base::PLATFORM_FILE_ERROR_NO_SPACE; |
+ return CreateFile(context, context->dest_origin_url(), |
+ context->dest_type(), src_file_path, &dest_file_info, 0, NULL); |
} |
- if (error != base::PLATFORM_FILE_OK) |
- return error; |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+} |
- if (!created) { |
+PlatformFileError ObfuscatedFileUtil::DeleteFile( |
+ FileSystemOperationContext* context, |
+ const FilePath& virtual_path) { |
+ FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
+ context->src_origin_url(), context->src_type(), true); |
+ if (!db) |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+ FileId file_id; |
+ if (!db->GetFileWithPath(virtual_path, &file_id)) |
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
+ FileInfo file_info; |
+ if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) { |
NOTREACHED(); |
- if (handle) { |
- DCHECK_NE(base::kInvalidPlatformFileValue, *handle); |
- base::ClosePlatformFile(*handle); |
- underlying_file_util_->DeleteFile(context, path); |
- } |
return base::PLATFORM_FILE_ERROR_FAILED; |
} |
- file_info->data_path = data_path; |
- FileId file_id; |
- if (!db->AddFileInfo(*file_info, &file_id)) { |
- if (handle) { |
- DCHECK_NE(base::kInvalidPlatformFileValue, *handle); |
- base::ClosePlatformFile(*handle); |
- } |
- underlying_file_util_->DeleteFile(context, path); |
+ if (!db->RemoveFileInfo(file_id)) { |
+ NOTREACHED(); |
return base::PLATFORM_FILE_ERROR_FAILED; |
} |
- UpdatePathQuotaUsage(context, origin_url, type, 1, file_info->name.size()); |
- |
+ AllocateQuotaForPath(context, -1, -static_cast<int64>(file_info.name.size())); |
+ UpdatePathQuotaUsage(context, context->src_origin_url(), context->src_type(), |
+ -1, -static_cast<int64>(file_info.name.size())); |
+ FilePath data_path = DataPathToLocalPath(context->src_origin_url(), |
+ context->src_type(), file_info.data_path); |
+ if (base::PLATFORM_FILE_OK != |
+ underlying_file_util()->DeleteFile(context, data_path)) |
+ LOG(WARNING) << "Leaked a backing file."; |
return base::PLATFORM_FILE_OK; |
} |
-FilePath ObfuscatedFileSystemFileUtil::GetLocalPath( |
- const GURL& origin_url, |
- FileSystemType type, |
+PlatformFileError ObfuscatedFileUtil::DeleteSingleDirectory( |
+ FileSystemOperationContext* context, |
const FilePath& virtual_path) { |
FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
- origin_url, type, false); |
+ context->src_origin_url(), context->src_type(), true); |
if (!db) |
- return FilePath(); |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
FileId file_id; |
if (!db->GetFileWithPath(virtual_path, &file_id)) |
- return FilePath(); |
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
FileInfo file_info; |
- if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) { |
+ if (!db->GetFileInfo(file_id, &file_info) || !file_info.is_directory()) { |
NOTREACHED(); |
- return FilePath(); // Directories have no local path. |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
} |
- return DataPathToLocalPath(origin_url, type, file_info.data_path); |
+ if (!db->RemoveFileInfo(file_id)) |
+ return base::PLATFORM_FILE_ERROR_NOT_EMPTY; |
+ AllocateQuotaForPath(context, -1, -static_cast<int64>(file_info.name.size())); |
+ UpdatePathQuotaUsage(context, context->src_origin_url(), context->src_type(), |
+ -1, -static_cast<int64>(file_info.name.size())); |
+ return base::PLATFORM_FILE_OK; |
} |
-FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOriginAndType( |
+FilePath ObfuscatedFileUtil::GetDirectoryForOriginAndType( |
const GURL& origin, FileSystemType type, bool create) { |
FilePath origin_dir = GetDirectoryForOrigin(origin, create); |
if (origin_dir.empty()) |
@@ -938,7 +804,7 @@ FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOriginAndType( |
return path; |
} |
-bool ObfuscatedFileSystemFileUtil::DeleteDirectoryForOriginAndType( |
+bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType( |
const GURL& origin, FileSystemType type) { |
FilePath origin_type_path = GetDirectoryForOriginAndType(origin, type, false); |
if (!file_util::PathExists(origin_type_path)) |
@@ -968,7 +834,7 @@ bool ObfuscatedFileSystemFileUtil::DeleteDirectoryForOriginAndType( |
return true; |
} |
-bool ObfuscatedFileSystemFileUtil::MigrateFromOldSandbox( |
+bool ObfuscatedFileUtil::MigrateFromOldSandbox( |
const GURL& origin_url, FileSystemType type, const FilePath& src_root) { |
if (!DestroyDirectoryDatabase(origin_url, type)) |
return false; |
@@ -1040,7 +906,7 @@ bool ObfuscatedFileSystemFileUtil::MigrateFromOldSandbox( |
} |
// static |
-FilePath::StringType ObfuscatedFileSystemFileUtil::GetDirectoryNameForType( |
+FilePath::StringType ObfuscatedFileUtil::GetDirectoryNameForType( |
FileSystemType type) { |
switch (type) { |
case kFileSystemTypeTemporary: |
@@ -1053,7 +919,171 @@ FilePath::StringType ObfuscatedFileSystemFileUtil::GetDirectoryNameForType( |
} |
} |
-FilePath ObfuscatedFileSystemFileUtil::DataPathToLocalPath( |
+ObfuscatedFileUtil::AbstractOriginEnumerator* |
+ObfuscatedFileUtil::CreateOriginEnumerator() { |
+ std::vector<FileSystemOriginDatabase::OriginRecord> origins; |
+ |
+ InitOriginDatabase(false); |
+ return new ObfuscatedOriginEnumerator( |
+ origin_database_.get(), file_system_directory_); |
+} |
+ |
+bool ObfuscatedFileUtil::DestroyDirectoryDatabase( |
+ const GURL& origin, FileSystemType type) { |
+ std::string type_string = |
+ FileSystemPathManager::GetFileSystemTypeString(type); |
+ if (type_string.empty()) { |
+ LOG(WARNING) << "Unknown filesystem type requested:" << type; |
+ return true; |
+ } |
+ std::string key = GetOriginIdentifierFromURL(origin) + type_string; |
+ DirectoryMap::iterator iter = directories_.find(key); |
+ if (iter != directories_.end()) { |
+ FileSystemDirectoryDatabase* database = iter->second; |
+ directories_.erase(iter); |
+ delete database; |
+ } |
+ |
+ FilePath path = GetDirectoryForOriginAndType(origin, type, false); |
+ if (path.empty()) |
+ return true; |
+ if (!file_util::DirectoryExists(path)) |
+ return true; |
+ path = path.AppendASCII(kDirectoryDatabaseName); |
+ return FileSystemDirectoryDatabase::DestroyDatabase(path); |
+} |
+ |
+// static |
+int64 ObfuscatedFileUtil::ComputeFilePathCost(const FilePath& path) { |
+ return GetPathQuotaUsage(1, path.BaseName().value().size()); |
+} |
+ |
+PlatformFileError ObfuscatedFileUtil::GetFileInfoInternal( |
+ FileSystemDirectoryDatabase* db, |
+ FileSystemOperationContext* context, |
+ FileId file_id, |
+ FileInfo* local_info, |
+ base::PlatformFileInfo* file_info, |
+ FilePath* platform_file_path) { |
+ DCHECK(db); |
+ DCHECK(context); |
+ DCHECK(file_info); |
+ DCHECK(platform_file_path); |
+ |
+ if (!db->GetFileInfo(file_id, local_info)) { |
+ NOTREACHED(); |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+ } |
+ |
+ if (local_info->is_directory()) { |
+ file_info->is_directory = true; |
+ file_info->is_symbolic_link = false; |
+ file_info->last_modified = local_info->modification_time; |
+ *platform_file_path = FilePath(); |
+ // We don't fill in ctime or atime. |
+ return base::PLATFORM_FILE_OK; |
+ } |
+ if (local_info->data_path.empty()) |
+ return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
+ FilePath data_path = DataPathToLocalPath(context->src_origin_url(), |
+ context->src_type(), local_info->data_path); |
+ return underlying_file_util()->GetFileInfo( |
+ context, data_path, file_info, platform_file_path); |
+} |
+ |
+PlatformFileError ObfuscatedFileUtil::CreateFile( |
+ FileSystemOperationContext* context, |
+ const GURL& origin_url, FileSystemType type, const FilePath& source_path, |
+ FileInfo* file_info, int file_flags, PlatformFile* handle) { |
+ if (handle) |
+ *handle = base::kInvalidPlatformFileValue; |
+ FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
+ origin_url, type, true); |
+ int64 number; |
+ if (!db || !db->GetNextInteger(&number)) |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+ // We use the third- and fourth-to-last digits as the directory. |
+ int64 directory_number = number % 10000 / 100; |
+ FilePath path = |
+ GetDirectoryForOriginAndType(origin_url, type, false); |
+ if (path.empty()) |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+ |
+ path = path.AppendASCII(StringPrintf("%02" PRIu64, directory_number)); |
+ PlatformFileError error; |
+ error = underlying_file_util()->CreateDirectory( |
+ context, path, false /* exclusive */, false /* recursive */); |
+ if (base::PLATFORM_FILE_OK != error) |
+ return error; |
+ path = path.AppendASCII(StringPrintf("%08" PRIu64, number)); |
+ FilePath data_path = LocalPathToDataPath(origin_url, type, path); |
+ if (data_path.empty()) |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+ bool created = false; |
+ if (!source_path.empty()) { |
+ DCHECK(!file_flags); |
+ DCHECK(!handle); |
+ error = underlying_file_util()->CopyOrMoveFile( |
+ context, source_path, path, true /* copy */); |
+ created = true; |
+ } else { |
+ if (handle) { |
+ error = underlying_file_util()->CreateOrOpen( |
+ context, path, file_flags, handle, &created); |
+ // If this succeeds, we must close handle on any subsequent error. |
+ } else { |
+ DCHECK(!file_flags); // file_flags is only used by CreateOrOpen. |
+ error = underlying_file_util()->EnsureFileExists( |
+ context, path, &created); |
+ } |
+ } |
+ if (error != base::PLATFORM_FILE_OK) |
+ return error; |
+ |
+ if (!created) { |
+ NOTREACHED(); |
+ if (handle) { |
+ DCHECK_NE(base::kInvalidPlatformFileValue, *handle); |
+ base::ClosePlatformFile(*handle); |
+ underlying_file_util()->DeleteFile(context, path); |
+ } |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+ } |
+ file_info->data_path = data_path; |
+ FileId file_id; |
+ if (!db->AddFileInfo(*file_info, &file_id)) { |
+ if (handle) { |
+ DCHECK_NE(base::kInvalidPlatformFileValue, *handle); |
+ base::ClosePlatformFile(*handle); |
+ } |
+ underlying_file_util()->DeleteFile(context, path); |
+ return base::PLATFORM_FILE_ERROR_FAILED; |
+ } |
+ UpdatePathQuotaUsage(context, origin_url, type, 1, file_info->name.size()); |
+ |
+ return base::PLATFORM_FILE_OK; |
+} |
+ |
+FilePath ObfuscatedFileUtil::GetLocalPath( |
+ const GURL& origin_url, |
+ FileSystemType type, |
+ const FilePath& virtual_path) { |
+ FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
+ origin_url, type, false); |
+ if (!db) |
+ return FilePath(); |
+ FileId file_id; |
+ if (!db->GetFileWithPath(virtual_path, &file_id)) |
+ return FilePath(); |
+ FileInfo file_info; |
+ if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) { |
+ NOTREACHED(); |
+ return FilePath(); // Directories have no local path. |
+ } |
+ return DataPathToLocalPath(origin_url, type, file_info.data_path); |
+} |
+ |
+FilePath ObfuscatedFileUtil::DataPathToLocalPath( |
const GURL& origin, FileSystemType type, const FilePath& data_path) { |
FilePath root = GetDirectoryForOriginAndType(origin, type, false); |
if (root.empty()) |
@@ -1061,7 +1091,7 @@ FilePath ObfuscatedFileSystemFileUtil::DataPathToLocalPath( |
return root.Append(data_path); |
} |
-FilePath ObfuscatedFileSystemFileUtil::LocalPathToDataPath( |
+FilePath ObfuscatedFileUtil::LocalPathToDataPath( |
const GURL& origin, FileSystemType type, const FilePath& local_path) { |
FilePath root = GetDirectoryForOriginAndType(origin, type, false); |
if (root.empty()) |
@@ -1074,7 +1104,7 @@ FilePath ObfuscatedFileSystemFileUtil::LocalPathToDataPath( |
// TODO: How to do the whole validation-without-creation thing? We may not have |
// quota even to create the database. Ah, in that case don't even get here? |
// Still doesn't answer the quota issue, though. |
-FileSystemDirectoryDatabase* ObfuscatedFileSystemFileUtil::GetDirectoryDatabase( |
+FileSystemDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase( |
const GURL& origin, FileSystemType type, bool create) { |
std::string type_string = |
FileSystemPathManager::GetFileSystemTypeString(type); |
@@ -1105,7 +1135,7 @@ FileSystemDirectoryDatabase* ObfuscatedFileSystemFileUtil::GetDirectoryDatabase( |
return database; |
} |
-FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOrigin( |
+FilePath ObfuscatedFileUtil::GetDirectoryForOrigin( |
const GURL& origin, bool create) { |
if (!InitOriginDatabase(create)) |
return FilePath(); |
@@ -1122,52 +1152,22 @@ FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOrigin( |
return path; |
} |
-void ObfuscatedFileSystemFileUtil::MarkUsed() { |
+void ObfuscatedFileUtil::MarkUsed() { |
if (timer_.IsRunning()) |
timer_.Reset(); |
else |
timer_.Start(base::TimeDelta::FromSeconds(kFlushDelaySeconds), this, |
- &ObfuscatedFileSystemFileUtil::DropDatabases); |
+ &ObfuscatedFileUtil::DropDatabases); |
} |
-void ObfuscatedFileSystemFileUtil::DropDatabases() { |
+void ObfuscatedFileUtil::DropDatabases() { |
origin_database_.reset(); |
STLDeleteContainerPairSecondPointers( |
directories_.begin(), directories_.end()); |
directories_.clear(); |
} |
-// static |
-int64 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(const FilePath& path) { |
- return GetPathQuotaUsage(1, path.BaseName().value().size()); |
-} |
- |
-bool ObfuscatedFileSystemFileUtil::DestroyDirectoryDatabase( |
- const GURL& origin, FileSystemType type) { |
- std::string type_string = |
- FileSystemPathManager::GetFileSystemTypeString(type); |
- if (type_string.empty()) { |
- LOG(WARNING) << "Unknown filesystem type requested:" << type; |
- return true; |
- } |
- std::string key = GetOriginIdentifierFromURL(origin) + type_string; |
- DirectoryMap::iterator iter = directories_.find(key); |
- if (iter != directories_.end()) { |
- FileSystemDirectoryDatabase* database = iter->second; |
- directories_.erase(iter); |
- delete database; |
- } |
- |
- FilePath path = GetDirectoryForOriginAndType(origin, type, false); |
- if (path.empty()) |
- return true; |
- if (!file_util::DirectoryExists(path)) |
- return true; |
- path = path.AppendASCII(kDirectoryDatabaseName); |
- return FileSystemDirectoryDatabase::DestroyDatabase(path); |
-} |
- |
-bool ObfuscatedFileSystemFileUtil::InitOriginDatabase(bool create) { |
+bool ObfuscatedFileUtil::InitOriginDatabase(bool create) { |
if (!origin_database_.get()) { |
if (!create && !file_util::DirectoryExists(file_system_directory_)) |
return false; |