| 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;
|
|
|