<commit_before>// 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_system_operation.h"

#include "base/bind.h"
#include "base/sequenced_task_runner.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "net/base/escape.h"
#include "net/url_request/url_request_context.h"
#include "webkit/blob/shareable_file_reference.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_file_util_proxy.h"
#include "webkit/fileapi/file_system_mount_point_provider.h"
#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_quota_util.h"
#include "webkit/fileapi/file_system_types.h"
#include "webkit/fileapi/file_system_util.h"
#include "webkit/fileapi/file_writer_delegate.h"
#include "webkit/fileapi/sandbox_file_writer.h"
#include "webkit/quota/quota_manager.h"
#include "webkit/quota/quota_types.h"

namespace fileapi {

namespace {

void GetMetadataForSnapshot(
    const FileSystemOperationInterface::SnapshotFileCallback& callback,
    base::PlatformFileError result,
    const base::PlatformFileInfo& file_info,
    const FilePath& platform_path) {
  // We don't want the third party to delete our local file, so just returning
  // NULL as |file_reference|.
  callback.Run(result, file_info, platform_path, NULL);
}

}  // anonymous namespace

class FileSystemOperation::ScopedQuotaNotifier {
 public:
  ScopedQuotaNotifier(FileSystemContext* context,
                      const GURL& origin_url,
                      FileSystemType type);
  ~ScopedQuotaNotifier();

 private:
  // Not owned; owned by the owner of this instance (i.e. FileSystemOperation).
  FileSystemQuotaUtil* quota_util_;
  const GURL origin_url_;
  FileSystemType type_;
  DISALLOW_COPY_AND_ASSIGN(ScopedQuotaNotifier);
};

FileSystemOperation::ScopedQuotaNotifier::ScopedQuotaNotifier(
    FileSystemContext* context, const GURL& origin_url, FileSystemType type)
    : origin_url_(origin_url), type_(type) {
  DCHECK(context);
  DCHECK(type_ != kFileSystemTypeUnknown);
  quota_util_ = context->GetQuotaUtil(type_);
  if (quota_util_) {
    DCHECK(quota_util_->proxy());
    quota_util_->proxy()->StartUpdateOrigin(origin_url_, type_);
  }
}

FileSystemOperation::ScopedQuotaNotifier::~ScopedQuotaNotifier() {
  if (quota_util_) {
    DCHECK(quota_util_->proxy());
    quota_util_->proxy()->EndUpdateOrigin(origin_url_, type_);
  }
}

FileSystemOperation::TaskParamsForDidGetQuota::TaskParamsForDidGetQuota()
    : type(kFileSystemTypeUnknown) {
}

FileSystemOperation::TaskParamsForDidGetQuota::~TaskParamsForDidGetQuota() {}

FileSystemOperation::~FileSystemOperation() {
}

void FileSystemOperation::CreateFile(const GURL& path_url,
                                     bool exclusive,
                                     const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationCreateFile));

  base::PlatformFileError result = SetUpFileSystemPath(
      path_url, &src_path_, &src_util_, PATH_FOR_CREATE);
  if (result != base::PLATFORM_FILE_OK) {
    callback.Run(result);
    delete this;
    return;
  }

  GetUsageAndQuotaThenRunTask(
      src_path_.origin(), src_path_.type(),
      base::Bind(&FileSystemOperation::DoCreateFile,
                 base::Unretained(this), callback, exclusive),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}

void FileSystemOperation::CreateDirectory(const GURL& path_url,
                                          bool exclusive,
                                          bool recursive,
                                          const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationCreateDirectory));

  base::PlatformFileError result = SetUpFileSystemPath(
      path_url, &src_path_, &src_util_, PATH_FOR_CREATE);
  if (result != base::PLATFORM_FILE_OK) {
    callback.Run(result);
    delete this;
    return;
  }
  GetUsageAndQuotaThenRunTask(
      src_path_.origin(), src_path_.type(),
      base::Bind(&FileSystemOperation::DoCreateDirectory,
                 base::Unretained(this), callback, exclusive, recursive),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}

void FileSystemOperation::Copy(const GURL& src_path_url,
                               const GURL& dest_path_url,
                               const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationCopy));

  base::PlatformFileError result = SetUpFileSystemPath(
      src_path_url, &src_path_, &src_util_, PATH_FOR_READ);
  if (result == base::PLATFORM_FILE_OK)
    result = SetUpFileSystemPath(
        dest_path_url, &dest_path_, &dest_util_, PATH_FOR_CREATE);
  if (result != base::PLATFORM_FILE_OK) {
    callback.Run(result);
    delete this;
    return;
  }

  GetUsageAndQuotaThenRunTask(
      dest_path_.origin(), dest_path_.type(),
      base::Bind(&FileSystemOperation::DoCopy,
                 base::Unretained(this), callback),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}

void FileSystemOperation::Move(const GURL& src_path_url,
                               const GURL& dest_path_url,
                               const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationMove));

  base::PlatformFileError result = SetUpFileSystemPath(
      src_path_url, &src_path_, &src_util_, PATH_FOR_WRITE);
  if (result == base::PLATFORM_FILE_OK)
    result = SetUpFileSystemPath(
        dest_path_url, &dest_path_, &dest_util_, PATH_FOR_CREATE);
  if (result != base::PLATFORM_FILE_OK) {
    callback.Run(result);
    delete this;
    return;
  }

  GetUsageAndQuotaThenRunTask(
      dest_path_.origin(), dest_path_.type(),
      base::Bind(&FileSystemOperation::DoMove,
                 base::Unretained(this), callback),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));<commit_msg>Disable cross-filesystem move for sandbox filesystem for now<commit_after>// 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_system_operation.h"

#include "base/bind.h"
#include "base/sequenced_task_runner.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "net/base/escape.h"
#include "net/url_request/url_request_context.h"
#include "webkit/blob/shareable_file_reference.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_file_util_proxy.h"
#include "webkit/fileapi/file_system_mount_point_provider.h"
#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_quota_util.h"
#include "webkit/fileapi/file_system_types.h"
#include "webkit/fileapi/file_system_util.h"
#include "webkit/fileapi/file_writer_delegate.h"
#include "webkit/fileapi/sandbox_file_writer.h"
#include "webkit/quota/quota_manager.h"
#include "webkit/quota/quota_types.h"

namespace fileapi {

namespace {

void GetMetadataForSnapshot(
    const FileSystemOperationInterface::SnapshotFileCallback& callback,
    base::PlatformFileError result,
    const base::PlatformFileInfo& file_info,
    const FilePath& platform_path) {
  // We don't want the third party to delete our local file, so just returning
  // NULL as |file_reference|.
  callback.Run(result, file_info, platform_path, NULL);
}

}  // anonymous namespace

class FileSystemOperation::ScopedQuotaNotifier {
 public:
  ScopedQuotaNotifier(FileSystemContext* context,
                      const GURL& origin_url,
                      FileSystemType type);
  ~ScopedQuotaNotifier();

 private:
  // Not owned; owned by the owner of this instance (i.e. FileSystemOperation).
  FileSystemQuotaUtil* quota_util_;
  const GURL origin_url_;
  FileSystemType type_;
  DISALLOW_COPY_AND_ASSIGN(ScopedQuotaNotifier);
};

FileSystemOperation::ScopedQuotaNotifier::ScopedQuotaNotifier(
    FileSystemContext* context, const GURL& origin_url, FileSystemType type)
    : origin_url_(origin_url), type_(type) {
  DCHECK(context);
  DCHECK(type_ != kFileSystemTypeUnknown);
  quota_util_ = context->GetQuotaUtil(type_);
  if (quota_util_) {
    DCHECK(quota_util_->proxy());
    quota_util_->proxy()->StartUpdateOrigin(origin_url_, type_);
  }
}

FileSystemOperation::ScopedQuotaNotifier::~ScopedQuotaNotifier() {
  if (quota_util_) {
    DCHECK(quota_util_->proxy());
    quota_util_->proxy()->EndUpdateOrigin(origin_url_, type_);
  }
}

FileSystemOperation::TaskParamsForDidGetQuota::TaskParamsForDidGetQuota()
    : type(kFileSystemTypeUnknown) {
}

FileSystemOperation::TaskParamsForDidGetQuota::~TaskParamsForDidGetQuota() {}

FileSystemOperation::~FileSystemOperation() {
}

void FileSystemOperation::CreateFile(const GURL& path_url,
                                     bool exclusive,
                                     const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationCreateFile));

  base::PlatformFileError result = SetUpFileSystemPath(
      path_url, &src_path_, &src_util_, PATH_FOR_CREATE);
  if (result != base::PLATFORM_FILE_OK) {
    callback.Run(result);
    delete this;
    return;
  }

  GetUsageAndQuotaThenRunTask(
      src_path_.origin(), src_path_.type(),
      base::Bind(&FileSystemOperation::DoCreateFile,
                 base::Unretained(this), callback, exclusive),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}

void FileSystemOperation::CreateDirectory(const GURL& path_url,
                                          bool exclusive,
                                          bool recursive,
                                          const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationCreateDirectory));

  base::PlatformFileError result = SetUpFileSystemPath(
      path_url, &src_path_, &src_util_, PATH_FOR_CREATE);
  if (result != base::PLATFORM_FILE_OK) {
    callback.Run(result);
    delete this;
    return;
  }
  GetUsageAndQuotaThenRunTask(
      src_path_.origin(), src_path_.type(),
      base::Bind(&FileSystemOperation::DoCreateDirectory,
                 base::Unretained(this), callback, exclusive, recursive),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}

void FileSystemOperation::Copy(const GURL& src_path_url,
                               const GURL& dest_path_url,
                               const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationCopy));

  base::PlatformFileError result = SetUpFileSystemPath(
      src_path_url, &src_path_, &src_util_, PATH_FOR_READ);
  if (result == base::PLATFORM_FILE_OK)
    result = SetUpFileSystemPath(
        dest_path_url, &dest_path_, &dest_util_, PATH_FOR_CREATE);
  if (result != base::PLATFORM_FILE_OK) {
    callback.Run(result);
    delete this;
    return;
  }

  GetUsageAndQuotaThenRunTask(
      dest_path_.origin(), dest_path_.type(),
      base::Bind(&FileSystemOperation::DoCopy,
                 base::Unretained(this), callback),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}

void FileSystemOperation::Move(const GURL& src_path_url,
                               const GURL& dest_path_url,
                               const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationMove));
  scoped_ptr<FileSystemOperation> deleter(this);

  base::PlatformFileError result = SetUpFileSystemPath(
      src_path_url, &src_path_, &src_util_, PATH_FOR_WRITE);
  if (result == base::PLATFORM_FILE_OK)
    result = SetUpFileSystemPath(
        dest_path_url, &dest_path_, &dest_util_, PATH_FOR_CREATE);
  if (result != base::PLATFORM_FILE_OK) {
    callback.Run(result);
    return;
  }

  // Temporarily disables cross-filesystem move for sandbox filesystems.
  // TODO(kinuko,tzik,kinaba): This special handling must be removed once
  // we support saner cross-filesystem operation.
  // (See http://crbug.com/130055)
  if (src_path_.type() != dest_path_.type() &&
      (src_path_.type() == kFileSystemTypeTemporary ||
       src_path_.type() == kFileSystemTypePersistent)) {
    callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
    return;
  }

  GetUsageAndQuotaThenRunTask(
      dest_path_.origin(), dest_path_.type(),
      base::Bind(&FileSystemOperation::DoMove,
                 base::Unretained(deleter.release()), callback),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
{'fraction_non_alphanumeric': 0.10556131812016277, 'fraction_numerical': 0.0011170509853985478, 'mean_word_length': 3.90951821386604, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3940026', 'n_tokens_mistral': 3860, 'n_tokens_neox': 3804, 'n_words': 677}