summaryrefslogtreecommitdiffstats
path: root/webkit/fileapi/file_util_helper.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/fileapi/file_util_helper.cc')
-rw-r--r--webkit/fileapi/file_util_helper.cc379
1 files changed, 0 insertions, 379 deletions
diff --git a/webkit/fileapi/file_util_helper.cc b/webkit/fileapi/file_util_helper.cc
deleted file mode 100644
index 49ea72c..0000000
--- a/webkit/fileapi/file_util_helper.cc
+++ /dev/null
@@ -1,379 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "webkit/fileapi/file_util_helper.h"
-
-#include <stack>
-#include <utility>
-
-#include "webkit/fileapi/file_system_file_util.h"
-#include "webkit/fileapi/file_system_operation_context.h"
-#include "webkit/fileapi/file_system_url.h"
-#include "webkit/fileapi/file_system_util.h"
-
-using base::PlatformFileError;
-
-namespace fileapi {
-
-namespace {
-
-// A helper class to delete a temporary file.
-class ScopedFileDeleter {
- public:
- explicit ScopedFileDeleter(const base::FilePath& path) : path_(path) {}
- ~ScopedFileDeleter() {
- file_util::Delete(path_, false /* recursive */);
- }
-
- private:
- base::FilePath path_;
-};
-
-bool IsInRoot(const FileSystemURL& url) {
- // If path is in the root, path.DirName() will be ".",
- // since we use paths with no leading '/'.
- base::FilePath parent = url.path().DirName();
- return parent.empty() || parent == base::FilePath(FILE_PATH_LITERAL("."));
-}
-
-// A helper class for cross-FileUtil Copy/Move operations.
-class CrossFileUtilHelper {
- public:
- enum Operation {
- OPERATION_COPY,
- OPERATION_MOVE
- };
-
- CrossFileUtilHelper(FileSystemOperationContext* context,
- FileSystemFileUtil* src_util,
- FileSystemFileUtil* dest_util,
- const FileSystemURL& src_url,
- const FileSystemURL& dest_url,
- Operation operation);
- ~CrossFileUtilHelper();
-
- base::PlatformFileError DoWork();
-
- private:
- // Performs common pre-operation check and preparation.
- // This may delete the destination directory if it's empty.
- base::PlatformFileError PerformErrorCheckAndPreparation();
-
- // Performs recursive copy or move by calling CopyOrMoveFile for individual
- // files. Operations for recursive traversal are encapsulated in this method.
- // It assumes src_url and dest_url have passed
- // PerformErrorCheckAndPreparationForMoveAndCopy().
- base::PlatformFileError CopyOrMoveDirectory(
- const FileSystemURL& src_url,
- const FileSystemURL& dest_url);
-
- // Determines whether a simple same-filesystem move or copy can be done. If
- // so, it delegates to CopyOrMoveFile. Otherwise it looks up the true
- // platform path of the source file, delegates to CopyInForeignFile, and [for
- // move] calls DeleteFile on the source file.
- base::PlatformFileError CopyOrMoveFile(
- const FileSystemURL& src_url,
- const FileSystemURL& dest_url);
-
- FileSystemOperationContext* context_;
- FileSystemFileUtil* src_util_; // Not owned.
- FileSystemFileUtil* dest_util_; // Not owned.
- const FileSystemURL& src_root_url_;
- const FileSystemURL& dest_root_url_;
- Operation operation_;
- bool same_file_system_;
-
- DISALLOW_COPY_AND_ASSIGN(CrossFileUtilHelper);
-};
-
-CrossFileUtilHelper::CrossFileUtilHelper(
- FileSystemOperationContext* context,
- FileSystemFileUtil* src_util,
- FileSystemFileUtil* dest_util,
- const FileSystemURL& src_url,
- const FileSystemURL& dest_url,
- Operation operation)
- : context_(context),
- src_util_(src_util),
- dest_util_(dest_util),
- src_root_url_(src_url),
- dest_root_url_(dest_url),
- operation_(operation) {
- DCHECK(src_util_);
- DCHECK(dest_util_);
- same_file_system_ =
- src_root_url_.origin() == dest_root_url_.origin() &&
- src_root_url_.type() == dest_root_url_.type();
-}
-
-CrossFileUtilHelper::~CrossFileUtilHelper() {}
-
-base::PlatformFileError CrossFileUtilHelper::DoWork() {
- // It is an error to try to copy/move an entry into its child.
- if (same_file_system_ && src_root_url_.path().IsParent(dest_root_url_.path()))
- return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
-
- // It is an error to copy/move an entry into the same path.
- if (same_file_system_ &&
- src_root_url_.path() == dest_root_url_.path())
- return base::PLATFORM_FILE_ERROR_EXISTS;
-
- // First try to copy/move the file.
- base::PlatformFileError error = CopyOrMoveFile(src_root_url_, dest_root_url_);
- if (error == base::PLATFORM_FILE_OK ||
- error != base::PLATFORM_FILE_ERROR_NOT_A_FILE)
- return error;
-
- // Now we should be sure that the source (and destination if exists)
- // is directory.
- // Now let's try to remove the destination directory, this must
- // fail if the directory isn't empty or its parent doesn't exist.
- error = dest_util_->DeleteDirectory(context_, dest_root_url_);
- if (error == base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY)
- return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
- if (error != base::PLATFORM_FILE_OK &&
- error != base::PLATFORM_FILE_ERROR_NOT_FOUND)
- return error;
-
- // Perform the actual work for directory copy/move.
- return CopyOrMoveDirectory(src_root_url_, dest_root_url_);
-}
-
-PlatformFileError CrossFileUtilHelper::CopyOrMoveDirectory(
- const FileSystemURL& src_url,
- const FileSystemURL& dest_url) {
- // At this point we must have gone through
- // PerformErrorCheckAndPreparationForMoveAndCopy so this must be true.
- DCHECK(!same_file_system_ ||
- !src_url.path().IsParent(dest_url.path()));
-
- PlatformFileError error = dest_util_->CreateDirectory(
- context_, dest_url, false /* exclusive */, false /* recursive */);
- if (error != base::PLATFORM_FILE_OK)
- return error;
-
- typedef std::pair<FileSystemURL, base::Time> MovedDirectoryPair;
- typedef std::vector<MovedDirectoryPair> MovedDirectories;
- MovedDirectories directories;
-
- // Store modified timestamp of the root directory.
- if (operation_ == OPERATION_MOVE) {
- base::PlatformFileInfo file_info;
- base::FilePath platform_file_path;
- error = src_util_->GetFileInfo(
- context_, src_url, &file_info, &platform_file_path);
- if (error != base::PLATFORM_FILE_OK)
- return error;
- directories.push_back(
- std::make_pair(dest_url, file_info.last_modified));
- }
-
- scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum(
- src_util_->CreateFileEnumerator(context_,
- src_url,
- true /* recursive */));
- base::FilePath src_file_path_each;
- while (!(src_file_path_each = file_enum->Next()).empty()) {
- base::FilePath dest_file_path_each(dest_url.path());
- src_url.path().AppendRelativePath(
- src_file_path_each, &dest_file_path_each);
-
- if (file_enum->IsDirectory()) {
- error = dest_util_->CreateDirectory(
- context_,
- dest_url.WithPath(dest_file_path_each),
- true /* exclusive */, false /* recursive */);
- if (error != base::PLATFORM_FILE_OK)
- return error;
-
- directories.push_back(std::make_pair(
- dest_url.WithPath(dest_file_path_each),
- file_enum->LastModifiedTime()));
- } else {
- error = CopyOrMoveFile(src_url.WithPath(src_file_path_each),
- dest_url.WithPath(dest_file_path_each));
- if (error != base::PLATFORM_FILE_OK)
- return error;
- }
- }
-
- if (operation_ == OPERATION_MOVE) {
- // Restore modified timestamp of destination directories.
- for (MovedDirectories::const_iterator it(directories.begin());
- it != directories.end(); ++it) {
- error = dest_util_->Touch(context_, it->first, it->second, it->second);
- if (error != base::PLATFORM_FILE_OK)
- return error;
- }
-
- error = FileUtilHelper::Delete(
- context_, src_util_, src_url, true /* recursive */);
- if (error != base::PLATFORM_FILE_OK)
- return error;
- }
-
- return base::PLATFORM_FILE_OK;
-}
-
-PlatformFileError CrossFileUtilHelper::CopyOrMoveFile(
- const FileSystemURL& src_url,
- const FileSystemURL& dest_url) {
- if (same_file_system_) {
- DCHECK(src_util_ == dest_util_);
- // Source and destination are in the same FileSystemFileUtil; now we can
- // safely call FileSystemFileUtil method on src_util_ (== dest_util_).
- return src_util_->CopyOrMoveFile(context_, src_url, dest_url,
- operation_ == OPERATION_COPY);
- }
-
- // Resolve the src_url's underlying file path.
- base::PlatformFileInfo file_info;
- base::FilePath platform_file_path;
- SnapshotFilePolicy snapshot_policy;
-
- PlatformFileError error = src_util_->CreateSnapshotFile(
- context_, src_url, &file_info, &platform_file_path, &snapshot_policy);
- if (error != base::PLATFORM_FILE_OK)
- return error;
-
- // For now we don't support non-snapshot file case.
- // TODO(kinuko): Address this case too.
- DCHECK(!platform_file_path.empty());
-
- scoped_ptr<ScopedFileDeleter> file_deleter;
- if (snapshot_policy == kSnapshotFileTemporary)
- file_deleter.reset(new ScopedFileDeleter(platform_file_path));
-
- // Call CopyInForeignFile() on the dest_util_ with the resolved source path
- // to perform limited cross-FileSystemFileUtil copy/move.
- error = dest_util_->CopyInForeignFile(
- context_, platform_file_path, dest_url);
-
- if (operation_ == OPERATION_COPY || error != base::PLATFORM_FILE_OK)
- return error;
- return src_util_->DeleteFile(context_, src_url);
-}
-
-} // anonymous namespace
-
-// static
-bool FileUtilHelper::DirectoryExists(FileSystemOperationContext* context,
- FileSystemFileUtil* file_util,
- const FileSystemURL& url) {
- if (url.path().empty())
- return true;
-
- base::PlatformFileInfo file_info;
- base::FilePath platform_path;
- PlatformFileError error = file_util->GetFileInfo(
- context, url, &file_info, &platform_path);
- return error == base::PLATFORM_FILE_OK && file_info.is_directory;
-}
-
-// static
-base::PlatformFileError FileUtilHelper::Copy(
- FileSystemOperationContext* context,
- FileSystemFileUtil* src_file_util,
- FileSystemFileUtil* dest_file_util,
- const FileSystemURL& src_root_url,
- const FileSystemURL& dest_root_url) {
- return CrossFileUtilHelper(context, src_file_util, dest_file_util,
- src_root_url, dest_root_url,
- CrossFileUtilHelper::OPERATION_COPY).DoWork();
-}
-
-// static
-base::PlatformFileError FileUtilHelper::Move(
- FileSystemOperationContext* context,
- FileSystemFileUtil* src_file_util,
- FileSystemFileUtil* dest_file_util,
- const FileSystemURL& src_root_url,
- const FileSystemURL& dest_root_url) {
- return CrossFileUtilHelper(context, src_file_util, dest_file_util,
- src_root_url, dest_root_url,
- CrossFileUtilHelper::OPERATION_MOVE).DoWork();
-}
-
-// static
-base::PlatformFileError FileUtilHelper::Delete(
- FileSystemOperationContext* context,
- FileSystemFileUtil* file_util,
- const FileSystemURL& url,
- bool recursive) {
- if (DirectoryExists(context, file_util, url)) {
- if (!recursive)
- return file_util->DeleteDirectory(context, url);
- else
- return DeleteDirectoryRecursive(context, file_util, url);
- } else {
- return file_util->DeleteFile(context, url);
- }
-}
-
-// static
-base::PlatformFileError FileUtilHelper::ReadDirectory(
- FileSystemOperationContext* context,
- FileSystemFileUtil* file_util,
- const FileSystemURL& url,
- std::vector<base::FileUtilProxy::Entry>* entries) {
- DCHECK(entries);
-
- base::PlatformFileInfo file_info;
- base::FilePath platform_path;
- PlatformFileError error = file_util->GetFileInfo(
- context, url, &file_info, &platform_path);
- if (error != base::PLATFORM_FILE_OK)
- return error;
- if (!file_info.is_directory)
- return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
-
- scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum(
- file_util->CreateFileEnumerator(context, url, false /* recursive */));
-
- base::FilePath current;
- while (!(current = file_enum->Next()).empty()) {
- base::FileUtilProxy::Entry entry;
- entry.is_directory = file_enum->IsDirectory();
- entry.name = VirtualPath::BaseName(current).value();
- entry.size = file_enum->Size();
- entry.last_modified_time = file_enum->LastModifiedTime();
- entries->push_back(entry);
- }
- return base::PLATFORM_FILE_OK;
-}
-
-// static
-base::PlatformFileError FileUtilHelper::DeleteDirectoryRecursive(
- FileSystemOperationContext* context,
- FileSystemFileUtil* file_util,
- const FileSystemURL& url) {
-
- scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum(
- file_util->CreateFileEnumerator(context, url, true /* recursive */));
- base::FilePath file_path_each;
- std::stack<base::FilePath> directories;
- while (!(file_path_each = file_enum->Next()).empty()) {
- if (file_enum->IsDirectory()) {
- directories.push(file_path_each);
- } else {
- PlatformFileError error = file_util->DeleteFile(
- context, url.WithPath(file_path_each));
- if (error != base::PLATFORM_FILE_ERROR_NOT_FOUND &&
- error != base::PLATFORM_FILE_OK)
- return error;
- }
- }
-
- while (!directories.empty()) {
- PlatformFileError error = file_util->DeleteDirectory(
- context, url.WithPath(directories.top()));
- if (error != base::PLATFORM_FILE_ERROR_NOT_FOUND &&
- error != base::PLATFORM_FILE_OK)
- return error;
- directories.pop();
- }
- return file_util->DeleteDirectory(context, url);
-}
-
-} // namespace fileapi