1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/files/file_util_proxy.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/files/file_util.h"
10#include "base/location.h"
11#include "base/task_runner.h"
12#include "base/task_runner_util.h"
13
14namespace base {
15
16namespace {
17
18void CallWithTranslatedParameter(const FileUtilProxy::StatusCallback& callback,
19                                 bool value) {
20  DCHECK(!callback.is_null());
21  callback.Run(value ? File::FILE_OK : File::FILE_ERROR_FAILED);
22}
23
24class GetFileInfoHelper {
25 public:
26  GetFileInfoHelper()
27      : error_(File::FILE_OK) {}
28
29  void RunWorkForFilePath(const FilePath& file_path) {
30    if (!PathExists(file_path)) {
31      error_ = File::FILE_ERROR_NOT_FOUND;
32      return;
33    }
34    if (!GetFileInfo(file_path, &file_info_))
35      error_ = File::FILE_ERROR_FAILED;
36  }
37
38  void Reply(const FileUtilProxy::GetFileInfoCallback& callback) {
39    if (!callback.is_null()) {
40      callback.Run(error_, file_info_);
41    }
42  }
43
44 private:
45  File::Error error_;
46  File::Info file_info_;
47  DISALLOW_COPY_AND_ASSIGN(GetFileInfoHelper);
48};
49
50File::Error DeleteAdapter(const FilePath& file_path, bool recursive) {
51  if (!PathExists(file_path)) {
52    return File::FILE_ERROR_NOT_FOUND;
53  }
54  if (!base::DeleteFile(file_path, recursive)) {
55    if (!recursive && !base::IsDirectoryEmpty(file_path)) {
56      return File::FILE_ERROR_NOT_EMPTY;
57    }
58    return File::FILE_ERROR_FAILED;
59  }
60  return File::FILE_OK;
61}
62
63}  // namespace
64
65// Retrieves the information about a file. It is invalid to pass NULL for the
66// callback.
67bool FileUtilProxy::GetFileInfo(
68    TaskRunner* task_runner,
69    const FilePath& file_path,
70    const GetFileInfoCallback& callback) {
71  GetFileInfoHelper* helper = new GetFileInfoHelper;
72  return task_runner->PostTaskAndReply(
73      FROM_HERE,
74      Bind(&GetFileInfoHelper::RunWorkForFilePath,
75           Unretained(helper), file_path),
76      Bind(&GetFileInfoHelper::Reply, Owned(helper), callback));
77}
78
79// static
80bool FileUtilProxy::DeleteFile(TaskRunner* task_runner,
81                               const FilePath& file_path,
82                               bool recursive,
83                               const StatusCallback& callback) {
84  return base::PostTaskAndReplyWithResult(
85      task_runner, FROM_HERE,
86      Bind(&DeleteAdapter, file_path, recursive),
87      callback);
88}
89
90// static
91bool FileUtilProxy::Touch(
92    TaskRunner* task_runner,
93    const FilePath& file_path,
94    const Time& last_access_time,
95    const Time& last_modified_time,
96    const StatusCallback& callback) {
97  return base::PostTaskAndReplyWithResult(
98      task_runner,
99      FROM_HERE,
100      Bind(&TouchFile, file_path, last_access_time, last_modified_time),
101      Bind(&CallWithTranslatedParameter, callback));
102}
103
104}  // namespace base
105