1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
base / files / file_proxy.h [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_FILES_FILE_PROXY_H_
#define BASE_FILES_FILE_PROXY_H_
#include <stdint.h>
#include "base/base_export.h"
#include "base/containers/span.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/functional/callback_forward.h"
#include "base/memory/weak_ptr.h"
namespace base {
class TaskRunner;
class Time;
// This class provides asynchronous access to a File. All methods follow the
// same rules of the equivalent File method, as they are implemented by bouncing
// the operation to File using a TaskRunner.
//
// This class performs automatic proxying to close the underlying file at
// destruction.
//
// The TaskRunner is in charge of any sequencing of the operations, but a single
// operation can be proxied at a time, regardless of the use of a callback.
// In other words, having a sequence like
//
// proxy.Write(...);
// proxy.Write(...);
//
// means the second Write will always fail.
class BASE_EXPORT FileProxy final {
public:
// This callback is used by methods that report only an error code. It is
// valid to pass a null callback to some functions that takes a
// StatusCallback, in which case the operation will complete silently.
using StatusCallback = OnceCallback<void(File::Error)>;
using CreateTemporaryCallback =
OnceCallback<void(File::Error, const FilePath&)>;
using GetFileInfoCallback =
OnceCallback<void(File::Error, const File::Info&)>;
using ReadCallback =
OnceCallback<void(File::Error, base::span<const char> data)>;
using WriteCallback = OnceCallback<void(File::Error, int bytes_written)>;
explicit FileProxy(TaskRunner* task_runner);
FileProxy(const FileProxy&) = delete;
FileProxy& operator=(const FileProxy&) = delete;
~FileProxy();
// Creates or opens a file with the given flags. It is invalid to pass a null
// callback. If File::FLAG_CREATE is set in |file_flags| it always tries to
// create a new file at the given |file_path| and fails if the file already
// exists.
//
// This returns false if task posting to |task_runner| has failed.
bool CreateOrOpen(const FilePath& file_path,
uint32_t file_flags,
StatusCallback callback);
// Creates a temporary file for writing. The path and an open file are
// returned. It is invalid to pass a null callback. These additional file
// flags will be added on top of the default file flags:
// File::FLAG_CREATE_ALWAYS
// File::FLAG_WRITE
// File::FLAG_WIN_TEMPORARY.
//
// This returns false if task posting to |task_runner| has failed.
bool CreateTemporary(uint32_t additional_file_flags,
CreateTemporaryCallback callback);
// Returns true if the underlying |file_| is valid.
bool IsValid() const;
// Returns true if a new file was created (or an old one truncated to zero
// length to simulate a new file), and false otherwise.
bool created() const { return file_.created(); }
// Claims ownership of |file|. It is an error to call this method when
// IsValid() returns true.
void SetFile(File file);
File TakeFile();
// Returns a new File object that is a duplicate of the underlying |file_|.
// See the comment at File::Duplicate for caveats.
File DuplicateFile();
PlatformFile GetPlatformFile() const;
// Proxies File::Close. The callback can be null.
// This returns false if task posting to |task_runner| has failed.
bool Close(StatusCallback callback);
// Proxies File::GetInfo. The callback can't be null.
// This returns false if task posting to |task_runner| has failed.
bool GetInfo(GetFileInfoCallback callback);
// Proxies File::Read. The callback can't be null.
// This returns false if |bytes_to_read| is less than zero, or
// if task posting to |task_runner| has failed.
bool Read(int64_t offset, int bytes_to_read, ReadCallback callback);
// Proxies File::Write. The callback can be null.
// This returns false if |bytes_to_write| is less than or equal to zero,
// if |buffer| is NULL, or if task posting to |task_runner| has failed.
bool Write(int64_t offset,
base::span<const uint8_t> data,
WriteCallback callback);
// Proxies File::SetTimes. The callback can be null.
// This returns false if task posting to |task_runner| has failed.
bool SetTimes(Time last_access_time,
Time last_modified_time,
StatusCallback callback);
// Proxies File::SetLength. The callback can be null.
// This returns false if task posting to |task_runner| has failed.
bool SetLength(int64_t length, StatusCallback callback);
// Proxies File::Flush. The callback can be null.
// This returns false if task posting to |task_runner| has failed.
bool Flush(StatusCallback callback);
private:
friend class FileHelper;
TaskRunner* task_runner() { return task_runner_.get(); }
scoped_refptr<TaskRunner> task_runner_;
File file_;
base::WeakPtrFactory<FileProxy> weak_ptr_factory_{this};
};
} // namespace base
#endif // BASE_FILES_FILE_PROXY_H_