1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/files/file_proxy.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <memory>
8*6777b538SAndroid Build Coastguard Worker #include <optional>
9*6777b538SAndroid Build Coastguard Worker #include <utility>
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker #include "base/containers/heap_array.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/files/file.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/task/task_runner.h"
19*6777b538SAndroid Build Coastguard Worker
20*6777b538SAndroid Build Coastguard Worker namespace {
21*6777b538SAndroid Build Coastguard Worker
FileDeleter(base::File file)22*6777b538SAndroid Build Coastguard Worker void FileDeleter(base::File file) {
23*6777b538SAndroid Build Coastguard Worker }
24*6777b538SAndroid Build Coastguard Worker
25*6777b538SAndroid Build Coastguard Worker } // namespace
26*6777b538SAndroid Build Coastguard Worker
27*6777b538SAndroid Build Coastguard Worker namespace base {
28*6777b538SAndroid Build Coastguard Worker
29*6777b538SAndroid Build Coastguard Worker class FileHelper {
30*6777b538SAndroid Build Coastguard Worker public:
FileHelper(base::WeakPtr<FileProxy> proxy,File file)31*6777b538SAndroid Build Coastguard Worker FileHelper(base::WeakPtr<FileProxy> proxy, File file)
32*6777b538SAndroid Build Coastguard Worker : file_(std::move(file)),
33*6777b538SAndroid Build Coastguard Worker task_runner_(proxy->task_runner()),
34*6777b538SAndroid Build Coastguard Worker proxy_(proxy) {}
35*6777b538SAndroid Build Coastguard Worker FileHelper(const FileHelper&) = delete;
36*6777b538SAndroid Build Coastguard Worker FileHelper& operator=(const FileHelper&) = delete;
37*6777b538SAndroid Build Coastguard Worker
PassFile()38*6777b538SAndroid Build Coastguard Worker void PassFile() {
39*6777b538SAndroid Build Coastguard Worker if (proxy_)
40*6777b538SAndroid Build Coastguard Worker proxy_->SetFile(std::move(file_));
41*6777b538SAndroid Build Coastguard Worker else if (file_.IsValid())
42*6777b538SAndroid Build Coastguard Worker task_runner_->PostTask(FROM_HERE,
43*6777b538SAndroid Build Coastguard Worker BindOnce(&FileDeleter, std::move(file_)));
44*6777b538SAndroid Build Coastguard Worker }
45*6777b538SAndroid Build Coastguard Worker
46*6777b538SAndroid Build Coastguard Worker protected:
47*6777b538SAndroid Build Coastguard Worker File file_;
48*6777b538SAndroid Build Coastguard Worker File::Error error_ = File::FILE_ERROR_FAILED;
49*6777b538SAndroid Build Coastguard Worker
50*6777b538SAndroid Build Coastguard Worker private:
51*6777b538SAndroid Build Coastguard Worker scoped_refptr<TaskRunner> task_runner_;
52*6777b538SAndroid Build Coastguard Worker WeakPtr<FileProxy> proxy_;
53*6777b538SAndroid Build Coastguard Worker };
54*6777b538SAndroid Build Coastguard Worker
55*6777b538SAndroid Build Coastguard Worker namespace {
56*6777b538SAndroid Build Coastguard Worker
57*6777b538SAndroid Build Coastguard Worker class GenericFileHelper : public FileHelper {
58*6777b538SAndroid Build Coastguard Worker public:
GenericFileHelper(base::WeakPtr<FileProxy> proxy,File file)59*6777b538SAndroid Build Coastguard Worker GenericFileHelper(base::WeakPtr<FileProxy> proxy, File file)
60*6777b538SAndroid Build Coastguard Worker : FileHelper(std::move(proxy), std::move(file)) {}
61*6777b538SAndroid Build Coastguard Worker GenericFileHelper(const GenericFileHelper&) = delete;
62*6777b538SAndroid Build Coastguard Worker GenericFileHelper& operator=(const GenericFileHelper&) = delete;
63*6777b538SAndroid Build Coastguard Worker
Close()64*6777b538SAndroid Build Coastguard Worker void Close() {
65*6777b538SAndroid Build Coastguard Worker file_.Close();
66*6777b538SAndroid Build Coastguard Worker error_ = File::FILE_OK;
67*6777b538SAndroid Build Coastguard Worker }
68*6777b538SAndroid Build Coastguard Worker
SetTimes(Time last_access_time,Time last_modified_time)69*6777b538SAndroid Build Coastguard Worker void SetTimes(Time last_access_time, Time last_modified_time) {
70*6777b538SAndroid Build Coastguard Worker bool rv = file_.SetTimes(last_access_time, last_modified_time);
71*6777b538SAndroid Build Coastguard Worker error_ = rv ? File::FILE_OK : File::FILE_ERROR_FAILED;
72*6777b538SAndroid Build Coastguard Worker }
73*6777b538SAndroid Build Coastguard Worker
SetLength(int64_t length)74*6777b538SAndroid Build Coastguard Worker void SetLength(int64_t length) {
75*6777b538SAndroid Build Coastguard Worker if (file_.SetLength(length))
76*6777b538SAndroid Build Coastguard Worker error_ = File::FILE_OK;
77*6777b538SAndroid Build Coastguard Worker }
78*6777b538SAndroid Build Coastguard Worker
Flush()79*6777b538SAndroid Build Coastguard Worker void Flush() {
80*6777b538SAndroid Build Coastguard Worker if (file_.Flush())
81*6777b538SAndroid Build Coastguard Worker error_ = File::FILE_OK;
82*6777b538SAndroid Build Coastguard Worker }
83*6777b538SAndroid Build Coastguard Worker
Reply(FileProxy::StatusCallback callback)84*6777b538SAndroid Build Coastguard Worker void Reply(FileProxy::StatusCallback callback) {
85*6777b538SAndroid Build Coastguard Worker PassFile();
86*6777b538SAndroid Build Coastguard Worker if (!callback.is_null())
87*6777b538SAndroid Build Coastguard Worker std::move(callback).Run(error_);
88*6777b538SAndroid Build Coastguard Worker }
89*6777b538SAndroid Build Coastguard Worker };
90*6777b538SAndroid Build Coastguard Worker
91*6777b538SAndroid Build Coastguard Worker class CreateOrOpenHelper : public FileHelper {
92*6777b538SAndroid Build Coastguard Worker public:
CreateOrOpenHelper(base::WeakPtr<FileProxy> proxy,File file)93*6777b538SAndroid Build Coastguard Worker CreateOrOpenHelper(base::WeakPtr<FileProxy> proxy, File file)
94*6777b538SAndroid Build Coastguard Worker : FileHelper(std::move(proxy), std::move(file)) {}
95*6777b538SAndroid Build Coastguard Worker CreateOrOpenHelper(const CreateOrOpenHelper&) = delete;
96*6777b538SAndroid Build Coastguard Worker CreateOrOpenHelper& operator=(const CreateOrOpenHelper&) = delete;
97*6777b538SAndroid Build Coastguard Worker
RunWork(const FilePath & file_path,uint32_t file_flags)98*6777b538SAndroid Build Coastguard Worker void RunWork(const FilePath& file_path, uint32_t file_flags) {
99*6777b538SAndroid Build Coastguard Worker file_.Initialize(file_path, file_flags);
100*6777b538SAndroid Build Coastguard Worker error_ = file_.IsValid() ? File::FILE_OK : file_.error_details();
101*6777b538SAndroid Build Coastguard Worker }
102*6777b538SAndroid Build Coastguard Worker
Reply(FileProxy::StatusCallback callback)103*6777b538SAndroid Build Coastguard Worker void Reply(FileProxy::StatusCallback callback) {
104*6777b538SAndroid Build Coastguard Worker DCHECK(!callback.is_null());
105*6777b538SAndroid Build Coastguard Worker PassFile();
106*6777b538SAndroid Build Coastguard Worker std::move(callback).Run(error_);
107*6777b538SAndroid Build Coastguard Worker }
108*6777b538SAndroid Build Coastguard Worker };
109*6777b538SAndroid Build Coastguard Worker
110*6777b538SAndroid Build Coastguard Worker class CreateTemporaryHelper : public FileHelper {
111*6777b538SAndroid Build Coastguard Worker public:
CreateTemporaryHelper(base::WeakPtr<FileProxy> proxy,File file)112*6777b538SAndroid Build Coastguard Worker CreateTemporaryHelper(base::WeakPtr<FileProxy> proxy, File file)
113*6777b538SAndroid Build Coastguard Worker : FileHelper(std::move(proxy), std::move(file)) {}
114*6777b538SAndroid Build Coastguard Worker CreateTemporaryHelper(const CreateTemporaryHelper&) = delete;
115*6777b538SAndroid Build Coastguard Worker CreateTemporaryHelper& operator=(const CreateTemporaryHelper&) = delete;
116*6777b538SAndroid Build Coastguard Worker
RunWork(uint32_t additional_file_flags)117*6777b538SAndroid Build Coastguard Worker void RunWork(uint32_t additional_file_flags) {
118*6777b538SAndroid Build Coastguard Worker // TODO(darin): file_util should have a variant of CreateTemporaryFile
119*6777b538SAndroid Build Coastguard Worker // that returns a FilePath and a File.
120*6777b538SAndroid Build Coastguard Worker if (!CreateTemporaryFile(&file_path_)) {
121*6777b538SAndroid Build Coastguard Worker // TODO(davidben): base::CreateTemporaryFile should preserve the error
122*6777b538SAndroid Build Coastguard Worker // code.
123*6777b538SAndroid Build Coastguard Worker error_ = File::FILE_ERROR_FAILED;
124*6777b538SAndroid Build Coastguard Worker return;
125*6777b538SAndroid Build Coastguard Worker }
126*6777b538SAndroid Build Coastguard Worker
127*6777b538SAndroid Build Coastguard Worker uint32_t file_flags = File::FLAG_WRITE | File::FLAG_WIN_TEMPORARY |
128*6777b538SAndroid Build Coastguard Worker File::FLAG_CREATE_ALWAYS | additional_file_flags;
129*6777b538SAndroid Build Coastguard Worker
130*6777b538SAndroid Build Coastguard Worker file_.Initialize(file_path_, file_flags);
131*6777b538SAndroid Build Coastguard Worker if (file_.IsValid()) {
132*6777b538SAndroid Build Coastguard Worker error_ = File::FILE_OK;
133*6777b538SAndroid Build Coastguard Worker } else {
134*6777b538SAndroid Build Coastguard Worker error_ = file_.error_details();
135*6777b538SAndroid Build Coastguard Worker DeleteFile(file_path_);
136*6777b538SAndroid Build Coastguard Worker file_path_.clear();
137*6777b538SAndroid Build Coastguard Worker }
138*6777b538SAndroid Build Coastguard Worker }
139*6777b538SAndroid Build Coastguard Worker
Reply(FileProxy::CreateTemporaryCallback callback)140*6777b538SAndroid Build Coastguard Worker void Reply(FileProxy::CreateTemporaryCallback callback) {
141*6777b538SAndroid Build Coastguard Worker DCHECK(!callback.is_null());
142*6777b538SAndroid Build Coastguard Worker PassFile();
143*6777b538SAndroid Build Coastguard Worker std::move(callback).Run(error_, file_path_);
144*6777b538SAndroid Build Coastguard Worker }
145*6777b538SAndroid Build Coastguard Worker
146*6777b538SAndroid Build Coastguard Worker private:
147*6777b538SAndroid Build Coastguard Worker FilePath file_path_;
148*6777b538SAndroid Build Coastguard Worker };
149*6777b538SAndroid Build Coastguard Worker
150*6777b538SAndroid Build Coastguard Worker class GetInfoHelper : public FileHelper {
151*6777b538SAndroid Build Coastguard Worker public:
GetInfoHelper(base::WeakPtr<FileProxy> proxy,File file)152*6777b538SAndroid Build Coastguard Worker GetInfoHelper(base::WeakPtr<FileProxy> proxy, File file)
153*6777b538SAndroid Build Coastguard Worker : FileHelper(std::move(proxy), std::move(file)) {}
154*6777b538SAndroid Build Coastguard Worker GetInfoHelper(const GetInfoHelper&) = delete;
155*6777b538SAndroid Build Coastguard Worker GetInfoHelper& operator=(const GetInfoHelper&) = delete;
156*6777b538SAndroid Build Coastguard Worker
RunWork()157*6777b538SAndroid Build Coastguard Worker void RunWork() {
158*6777b538SAndroid Build Coastguard Worker if (file_.GetInfo(&file_info_))
159*6777b538SAndroid Build Coastguard Worker error_ = File::FILE_OK;
160*6777b538SAndroid Build Coastguard Worker }
161*6777b538SAndroid Build Coastguard Worker
Reply(FileProxy::GetFileInfoCallback callback)162*6777b538SAndroid Build Coastguard Worker void Reply(FileProxy::GetFileInfoCallback callback) {
163*6777b538SAndroid Build Coastguard Worker PassFile();
164*6777b538SAndroid Build Coastguard Worker DCHECK(!callback.is_null());
165*6777b538SAndroid Build Coastguard Worker std::move(callback).Run(error_, file_info_);
166*6777b538SAndroid Build Coastguard Worker }
167*6777b538SAndroid Build Coastguard Worker
168*6777b538SAndroid Build Coastguard Worker private:
169*6777b538SAndroid Build Coastguard Worker File::Info file_info_;
170*6777b538SAndroid Build Coastguard Worker };
171*6777b538SAndroid Build Coastguard Worker
172*6777b538SAndroid Build Coastguard Worker class ReadHelper : public FileHelper {
173*6777b538SAndroid Build Coastguard Worker public:
ReadHelper(base::WeakPtr<FileProxy> proxy,File file,int bytes_to_read)174*6777b538SAndroid Build Coastguard Worker ReadHelper(base::WeakPtr<FileProxy> proxy, File file, int bytes_to_read)
175*6777b538SAndroid Build Coastguard Worker : FileHelper(std::move(proxy), std::move(file)),
176*6777b538SAndroid Build Coastguard Worker // SAFETY - References to `buffer_` are provided as a span only after
177*6777b538SAndroid Build Coastguard Worker // successfully reading some bytes.
178*6777b538SAndroid Build Coastguard Worker buffer_(base::HeapArray<uint8_t>::Uninit(
179*6777b538SAndroid Build Coastguard Worker static_cast<size_t>(bytes_to_read))) {}
180*6777b538SAndroid Build Coastguard Worker
181*6777b538SAndroid Build Coastguard Worker ReadHelper(const ReadHelper&) = delete;
182*6777b538SAndroid Build Coastguard Worker ReadHelper& operator=(const ReadHelper&) = delete;
183*6777b538SAndroid Build Coastguard Worker
RunWork(int64_t offset)184*6777b538SAndroid Build Coastguard Worker void RunWork(int64_t offset) {
185*6777b538SAndroid Build Coastguard Worker std::optional<size_t> result = file_.Read(offset, buffer_);
186*6777b538SAndroid Build Coastguard Worker if (!result.has_value()) {
187*6777b538SAndroid Build Coastguard Worker bytes_read_ = -1;
188*6777b538SAndroid Build Coastguard Worker error_ = File::FILE_ERROR_FAILED;
189*6777b538SAndroid Build Coastguard Worker return;
190*6777b538SAndroid Build Coastguard Worker }
191*6777b538SAndroid Build Coastguard Worker bytes_read_ = checked_cast<int>(result.value());
192*6777b538SAndroid Build Coastguard Worker error_ = File::FILE_OK;
193*6777b538SAndroid Build Coastguard Worker }
194*6777b538SAndroid Build Coastguard Worker
Reply(FileProxy::ReadCallback callback)195*6777b538SAndroid Build Coastguard Worker void Reply(FileProxy::ReadCallback callback) {
196*6777b538SAndroid Build Coastguard Worker PassFile();
197*6777b538SAndroid Build Coastguard Worker DCHECK(!callback.is_null());
198*6777b538SAndroid Build Coastguard Worker base::span<uint8_t> read_span;
199*6777b538SAndroid Build Coastguard Worker if (error_ == File::FILE_OK) {
200*6777b538SAndroid Build Coastguard Worker read_span = buffer_.first(checked_cast<size_t>(bytes_read_));
201*6777b538SAndroid Build Coastguard Worker }
202*6777b538SAndroid Build Coastguard Worker std::move(callback).Run(error_, base::as_chars(read_span));
203*6777b538SAndroid Build Coastguard Worker }
204*6777b538SAndroid Build Coastguard Worker
205*6777b538SAndroid Build Coastguard Worker private:
206*6777b538SAndroid Build Coastguard Worker base::HeapArray<uint8_t> buffer_;
207*6777b538SAndroid Build Coastguard Worker int bytes_read_ = 0;
208*6777b538SAndroid Build Coastguard Worker };
209*6777b538SAndroid Build Coastguard Worker
210*6777b538SAndroid Build Coastguard Worker class WriteHelper : public FileHelper {
211*6777b538SAndroid Build Coastguard Worker public:
WriteHelper(base::WeakPtr<FileProxy> proxy,File file,base::span<const uint8_t> data)212*6777b538SAndroid Build Coastguard Worker WriteHelper(base::WeakPtr<FileProxy> proxy,
213*6777b538SAndroid Build Coastguard Worker File file,
214*6777b538SAndroid Build Coastguard Worker base::span<const uint8_t> data)
215*6777b538SAndroid Build Coastguard Worker : FileHelper(std::move(proxy), std::move(file)),
216*6777b538SAndroid Build Coastguard Worker buffer_(base::HeapArray<uint8_t>::CopiedFrom(data)) {}
217*6777b538SAndroid Build Coastguard Worker
218*6777b538SAndroid Build Coastguard Worker WriteHelper(const WriteHelper&) = delete;
219*6777b538SAndroid Build Coastguard Worker WriteHelper& operator=(const WriteHelper&) = delete;
220*6777b538SAndroid Build Coastguard Worker
RunWork(int64_t offset)221*6777b538SAndroid Build Coastguard Worker void RunWork(int64_t offset) {
222*6777b538SAndroid Build Coastguard Worker std::optional<size_t> result = file_.Write(offset, buffer_);
223*6777b538SAndroid Build Coastguard Worker if (!result.has_value()) {
224*6777b538SAndroid Build Coastguard Worker bytes_written_ = -1;
225*6777b538SAndroid Build Coastguard Worker error_ = File::FILE_ERROR_FAILED;
226*6777b538SAndroid Build Coastguard Worker return;
227*6777b538SAndroid Build Coastguard Worker }
228*6777b538SAndroid Build Coastguard Worker bytes_written_ = checked_cast<int>(result.value());
229*6777b538SAndroid Build Coastguard Worker error_ = File::FILE_OK;
230*6777b538SAndroid Build Coastguard Worker }
231*6777b538SAndroid Build Coastguard Worker
Reply(FileProxy::WriteCallback callback)232*6777b538SAndroid Build Coastguard Worker void Reply(FileProxy::WriteCallback callback) {
233*6777b538SAndroid Build Coastguard Worker PassFile();
234*6777b538SAndroid Build Coastguard Worker if (!callback.is_null())
235*6777b538SAndroid Build Coastguard Worker std::move(callback).Run(error_, bytes_written_);
236*6777b538SAndroid Build Coastguard Worker }
237*6777b538SAndroid Build Coastguard Worker
238*6777b538SAndroid Build Coastguard Worker private:
239*6777b538SAndroid Build Coastguard Worker base::HeapArray<uint8_t> buffer_;
240*6777b538SAndroid Build Coastguard Worker int bytes_written_ = 0;
241*6777b538SAndroid Build Coastguard Worker };
242*6777b538SAndroid Build Coastguard Worker
243*6777b538SAndroid Build Coastguard Worker } // namespace
244*6777b538SAndroid Build Coastguard Worker
FileProxy(TaskRunner * task_runner)245*6777b538SAndroid Build Coastguard Worker FileProxy::FileProxy(TaskRunner* task_runner) : task_runner_(task_runner) {}
246*6777b538SAndroid Build Coastguard Worker
~FileProxy()247*6777b538SAndroid Build Coastguard Worker FileProxy::~FileProxy() {
248*6777b538SAndroid Build Coastguard Worker if (file_.IsValid())
249*6777b538SAndroid Build Coastguard Worker task_runner_->PostTask(FROM_HERE, BindOnce(&FileDeleter, std::move(file_)));
250*6777b538SAndroid Build Coastguard Worker }
251*6777b538SAndroid Build Coastguard Worker
CreateOrOpen(const FilePath & file_path,uint32_t file_flags,StatusCallback callback)252*6777b538SAndroid Build Coastguard Worker bool FileProxy::CreateOrOpen(const FilePath& file_path,
253*6777b538SAndroid Build Coastguard Worker uint32_t file_flags,
254*6777b538SAndroid Build Coastguard Worker StatusCallback callback) {
255*6777b538SAndroid Build Coastguard Worker DCHECK(!file_.IsValid());
256*6777b538SAndroid Build Coastguard Worker CreateOrOpenHelper* helper =
257*6777b538SAndroid Build Coastguard Worker new CreateOrOpenHelper(weak_ptr_factory_.GetWeakPtr(), File());
258*6777b538SAndroid Build Coastguard Worker return task_runner_->PostTaskAndReply(
259*6777b538SAndroid Build Coastguard Worker FROM_HERE,
260*6777b538SAndroid Build Coastguard Worker BindOnce(&CreateOrOpenHelper::RunWork, Unretained(helper), file_path,
261*6777b538SAndroid Build Coastguard Worker file_flags),
262*6777b538SAndroid Build Coastguard Worker BindOnce(&CreateOrOpenHelper::Reply, Owned(helper), std::move(callback)));
263*6777b538SAndroid Build Coastguard Worker }
264*6777b538SAndroid Build Coastguard Worker
CreateTemporary(uint32_t additional_file_flags,CreateTemporaryCallback callback)265*6777b538SAndroid Build Coastguard Worker bool FileProxy::CreateTemporary(uint32_t additional_file_flags,
266*6777b538SAndroid Build Coastguard Worker CreateTemporaryCallback callback) {
267*6777b538SAndroid Build Coastguard Worker DCHECK(!file_.IsValid());
268*6777b538SAndroid Build Coastguard Worker CreateTemporaryHelper* helper =
269*6777b538SAndroid Build Coastguard Worker new CreateTemporaryHelper(weak_ptr_factory_.GetWeakPtr(), File());
270*6777b538SAndroid Build Coastguard Worker return task_runner_->PostTaskAndReply(
271*6777b538SAndroid Build Coastguard Worker FROM_HERE,
272*6777b538SAndroid Build Coastguard Worker BindOnce(&CreateTemporaryHelper::RunWork, Unretained(helper),
273*6777b538SAndroid Build Coastguard Worker additional_file_flags),
274*6777b538SAndroid Build Coastguard Worker BindOnce(&CreateTemporaryHelper::Reply, Owned(helper),
275*6777b538SAndroid Build Coastguard Worker std::move(callback)));
276*6777b538SAndroid Build Coastguard Worker }
277*6777b538SAndroid Build Coastguard Worker
IsValid() const278*6777b538SAndroid Build Coastguard Worker bool FileProxy::IsValid() const {
279*6777b538SAndroid Build Coastguard Worker return file_.IsValid();
280*6777b538SAndroid Build Coastguard Worker }
281*6777b538SAndroid Build Coastguard Worker
SetFile(File file)282*6777b538SAndroid Build Coastguard Worker void FileProxy::SetFile(File file) {
283*6777b538SAndroid Build Coastguard Worker DCHECK(!file_.IsValid());
284*6777b538SAndroid Build Coastguard Worker file_ = std::move(file);
285*6777b538SAndroid Build Coastguard Worker }
286*6777b538SAndroid Build Coastguard Worker
TakeFile()287*6777b538SAndroid Build Coastguard Worker File FileProxy::TakeFile() {
288*6777b538SAndroid Build Coastguard Worker return std::move(file_);
289*6777b538SAndroid Build Coastguard Worker }
290*6777b538SAndroid Build Coastguard Worker
DuplicateFile()291*6777b538SAndroid Build Coastguard Worker File FileProxy::DuplicateFile() {
292*6777b538SAndroid Build Coastguard Worker return file_.Duplicate();
293*6777b538SAndroid Build Coastguard Worker }
294*6777b538SAndroid Build Coastguard Worker
GetPlatformFile() const295*6777b538SAndroid Build Coastguard Worker PlatformFile FileProxy::GetPlatformFile() const {
296*6777b538SAndroid Build Coastguard Worker return file_.GetPlatformFile();
297*6777b538SAndroid Build Coastguard Worker }
298*6777b538SAndroid Build Coastguard Worker
Close(StatusCallback callback)299*6777b538SAndroid Build Coastguard Worker bool FileProxy::Close(StatusCallback callback) {
300*6777b538SAndroid Build Coastguard Worker DCHECK(file_.IsValid());
301*6777b538SAndroid Build Coastguard Worker GenericFileHelper* helper =
302*6777b538SAndroid Build Coastguard Worker new GenericFileHelper(weak_ptr_factory_.GetWeakPtr(), std::move(file_));
303*6777b538SAndroid Build Coastguard Worker return task_runner_->PostTaskAndReply(
304*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&GenericFileHelper::Close, Unretained(helper)),
305*6777b538SAndroid Build Coastguard Worker BindOnce(&GenericFileHelper::Reply, Owned(helper), std::move(callback)));
306*6777b538SAndroid Build Coastguard Worker }
307*6777b538SAndroid Build Coastguard Worker
GetInfo(GetFileInfoCallback callback)308*6777b538SAndroid Build Coastguard Worker bool FileProxy::GetInfo(GetFileInfoCallback callback) {
309*6777b538SAndroid Build Coastguard Worker DCHECK(file_.IsValid());
310*6777b538SAndroid Build Coastguard Worker GetInfoHelper* helper =
311*6777b538SAndroid Build Coastguard Worker new GetInfoHelper(weak_ptr_factory_.GetWeakPtr(), std::move(file_));
312*6777b538SAndroid Build Coastguard Worker return task_runner_->PostTaskAndReply(
313*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&GetInfoHelper::RunWork, Unretained(helper)),
314*6777b538SAndroid Build Coastguard Worker BindOnce(&GetInfoHelper::Reply, Owned(helper), std::move(callback)));
315*6777b538SAndroid Build Coastguard Worker }
316*6777b538SAndroid Build Coastguard Worker
Read(int64_t offset,int bytes_to_read,ReadCallback callback)317*6777b538SAndroid Build Coastguard Worker bool FileProxy::Read(int64_t offset, int bytes_to_read, ReadCallback callback) {
318*6777b538SAndroid Build Coastguard Worker DCHECK(file_.IsValid());
319*6777b538SAndroid Build Coastguard Worker if (bytes_to_read < 0)
320*6777b538SAndroid Build Coastguard Worker return false;
321*6777b538SAndroid Build Coastguard Worker
322*6777b538SAndroid Build Coastguard Worker ReadHelper* helper = new ReadHelper(weak_ptr_factory_.GetWeakPtr(),
323*6777b538SAndroid Build Coastguard Worker std::move(file_), bytes_to_read);
324*6777b538SAndroid Build Coastguard Worker return task_runner_->PostTaskAndReply(
325*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&ReadHelper::RunWork, Unretained(helper), offset),
326*6777b538SAndroid Build Coastguard Worker BindOnce(&ReadHelper::Reply, Owned(helper), std::move(callback)));
327*6777b538SAndroid Build Coastguard Worker }
328*6777b538SAndroid Build Coastguard Worker
Write(int64_t offset,base::span<const uint8_t> data,WriteCallback callback)329*6777b538SAndroid Build Coastguard Worker bool FileProxy::Write(int64_t offset,
330*6777b538SAndroid Build Coastguard Worker base::span<const uint8_t> data,
331*6777b538SAndroid Build Coastguard Worker WriteCallback callback) {
332*6777b538SAndroid Build Coastguard Worker DCHECK(file_.IsValid());
333*6777b538SAndroid Build Coastguard Worker if (data.empty()) {
334*6777b538SAndroid Build Coastguard Worker return false;
335*6777b538SAndroid Build Coastguard Worker }
336*6777b538SAndroid Build Coastguard Worker WriteHelper* helper =
337*6777b538SAndroid Build Coastguard Worker new WriteHelper(weak_ptr_factory_.GetWeakPtr(), std::move(file_), data);
338*6777b538SAndroid Build Coastguard Worker
339*6777b538SAndroid Build Coastguard Worker return task_runner_->PostTaskAndReply(
340*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&WriteHelper::RunWork, Unretained(helper), offset),
341*6777b538SAndroid Build Coastguard Worker BindOnce(&WriteHelper::Reply, Owned(helper), std::move(callback)));
342*6777b538SAndroid Build Coastguard Worker }
343*6777b538SAndroid Build Coastguard Worker
SetTimes(Time last_access_time,Time last_modified_time,StatusCallback callback)344*6777b538SAndroid Build Coastguard Worker bool FileProxy::SetTimes(Time last_access_time,
345*6777b538SAndroid Build Coastguard Worker Time last_modified_time,
346*6777b538SAndroid Build Coastguard Worker StatusCallback callback) {
347*6777b538SAndroid Build Coastguard Worker DCHECK(file_.IsValid());
348*6777b538SAndroid Build Coastguard Worker GenericFileHelper* helper =
349*6777b538SAndroid Build Coastguard Worker new GenericFileHelper(weak_ptr_factory_.GetWeakPtr(), std::move(file_));
350*6777b538SAndroid Build Coastguard Worker return task_runner_->PostTaskAndReply(
351*6777b538SAndroid Build Coastguard Worker FROM_HERE,
352*6777b538SAndroid Build Coastguard Worker BindOnce(&GenericFileHelper::SetTimes, Unretained(helper),
353*6777b538SAndroid Build Coastguard Worker last_access_time, last_modified_time),
354*6777b538SAndroid Build Coastguard Worker BindOnce(&GenericFileHelper::Reply, Owned(helper), std::move(callback)));
355*6777b538SAndroid Build Coastguard Worker }
356*6777b538SAndroid Build Coastguard Worker
SetLength(int64_t length,StatusCallback callback)357*6777b538SAndroid Build Coastguard Worker bool FileProxy::SetLength(int64_t length, StatusCallback callback) {
358*6777b538SAndroid Build Coastguard Worker DCHECK(file_.IsValid());
359*6777b538SAndroid Build Coastguard Worker GenericFileHelper* helper =
360*6777b538SAndroid Build Coastguard Worker new GenericFileHelper(weak_ptr_factory_.GetWeakPtr(), std::move(file_));
361*6777b538SAndroid Build Coastguard Worker return task_runner_->PostTaskAndReply(
362*6777b538SAndroid Build Coastguard Worker FROM_HERE,
363*6777b538SAndroid Build Coastguard Worker BindOnce(&GenericFileHelper::SetLength, Unretained(helper), length),
364*6777b538SAndroid Build Coastguard Worker BindOnce(&GenericFileHelper::Reply, Owned(helper), std::move(callback)));
365*6777b538SAndroid Build Coastguard Worker }
366*6777b538SAndroid Build Coastguard Worker
Flush(StatusCallback callback)367*6777b538SAndroid Build Coastguard Worker bool FileProxy::Flush(StatusCallback callback) {
368*6777b538SAndroid Build Coastguard Worker DCHECK(file_.IsValid());
369*6777b538SAndroid Build Coastguard Worker GenericFileHelper* helper =
370*6777b538SAndroid Build Coastguard Worker new GenericFileHelper(weak_ptr_factory_.GetWeakPtr(), std::move(file_));
371*6777b538SAndroid Build Coastguard Worker return task_runner_->PostTaskAndReply(
372*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&GenericFileHelper::Flush, Unretained(helper)),
373*6777b538SAndroid Build Coastguard Worker BindOnce(&GenericFileHelper::Reply, Owned(helper), std::move(callback)));
374*6777b538SAndroid Build Coastguard Worker }
375*6777b538SAndroid Build Coastguard Worker
376*6777b538SAndroid Build Coastguard Worker } // namespace base
377