Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: base/files/file_proxy.cc

Issue 1647803004: Move base to DEPS (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/files/file_proxy.h ('k') | base/files/file_proxy_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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_proxy.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/files/file.h"
10 #include "base/files/file_util.h"
11 #include "base/location.h"
12 #include "base/task_runner.h"
13 #include "base/task_runner_util.h"
14
15 namespace {
16
17 void FileDeleter(base::File file) {
18 }
19
20 } // namespace
21
22 namespace base {
23
24 class FileHelper {
25 public:
26 FileHelper(FileProxy* proxy, File file)
27 : file_(file.Pass()),
28 error_(File::FILE_ERROR_FAILED),
29 task_runner_(proxy->task_runner()),
30 proxy_(AsWeakPtr(proxy)) {
31 }
32
33 void PassFile() {
34 if (proxy_)
35 proxy_->SetFile(file_.Pass());
36 else if (file_.IsValid())
37 task_runner_->PostTask(FROM_HERE, Bind(&FileDeleter, Passed(&file_)));
38 }
39
40 protected:
41 File file_;
42 File::Error error_;
43
44 private:
45 scoped_refptr<TaskRunner> task_runner_;
46 WeakPtr<FileProxy> proxy_;
47 DISALLOW_COPY_AND_ASSIGN(FileHelper);
48 };
49
50 namespace {
51
52 class GenericFileHelper : public FileHelper {
53 public:
54 GenericFileHelper(FileProxy* proxy, File file)
55 : FileHelper(proxy, file.Pass()) {
56 }
57
58 void Close() {
59 file_.Close();
60 error_ = File::FILE_OK;
61 }
62
63 void SetTimes(Time last_access_time, Time last_modified_time) {
64 bool rv = file_.SetTimes(last_access_time, last_modified_time);
65 error_ = rv ? File::FILE_OK : File::FILE_ERROR_FAILED;
66 }
67
68 void SetLength(int64 length) {
69 if (file_.SetLength(length))
70 error_ = File::FILE_OK;
71 }
72
73 void Flush() {
74 if (file_.Flush())
75 error_ = File::FILE_OK;
76 }
77
78 void Reply(const FileProxy::StatusCallback& callback) {
79 PassFile();
80 if (!callback.is_null())
81 callback.Run(error_);
82 }
83
84 private:
85 DISALLOW_COPY_AND_ASSIGN(GenericFileHelper);
86 };
87
88 class CreateOrOpenHelper : public FileHelper {
89 public:
90 CreateOrOpenHelper(FileProxy* proxy, File file)
91 : FileHelper(proxy, file.Pass()) {
92 }
93
94 void RunWork(const FilePath& file_path, int file_flags) {
95 file_.Initialize(file_path, file_flags);
96 error_ = file_.IsValid() ? File::FILE_OK : file_.error_details();
97 }
98
99 void Reply(const FileProxy::StatusCallback& callback) {
100 DCHECK(!callback.is_null());
101 PassFile();
102 callback.Run(error_);
103 }
104
105 private:
106 DISALLOW_COPY_AND_ASSIGN(CreateOrOpenHelper);
107 };
108
109 class CreateTemporaryHelper : public FileHelper {
110 public:
111 CreateTemporaryHelper(FileProxy* proxy, File file)
112 : FileHelper(proxy, file.Pass()) {
113 }
114
115 void RunWork(uint32 additional_file_flags) {
116 // TODO(darin): file_util should have a variant of CreateTemporaryFile
117 // that returns a FilePath and a File.
118 if (!CreateTemporaryFile(&file_path_)) {
119 // TODO(davidben): base::CreateTemporaryFile should preserve the error
120 // code.
121 error_ = File::FILE_ERROR_FAILED;
122 return;
123 }
124
125 uint32 file_flags = File::FLAG_WRITE |
126 File::FLAG_TEMPORARY |
127 File::FLAG_CREATE_ALWAYS |
128 additional_file_flags;
129
130 file_.Initialize(file_path_, file_flags);
131 if (file_.IsValid()) {
132 error_ = File::FILE_OK;
133 } else {
134 error_ = file_.error_details();
135 DeleteFile(file_path_, false);
136 file_path_.clear();
137 }
138 }
139
140 void Reply(const FileProxy::CreateTemporaryCallback& callback) {
141 DCHECK(!callback.is_null());
142 PassFile();
143 callback.Run(error_, file_path_);
144 }
145
146 private:
147 FilePath file_path_;
148 DISALLOW_COPY_AND_ASSIGN(CreateTemporaryHelper);
149 };
150
151 class GetInfoHelper : public FileHelper {
152 public:
153 GetInfoHelper(FileProxy* proxy, File file)
154 : FileHelper(proxy, file.Pass()) {
155 }
156
157 void RunWork() {
158 if (file_.GetInfo(&file_info_))
159 error_ = File::FILE_OK;
160 }
161
162 void Reply(const FileProxy::GetFileInfoCallback& callback) {
163 PassFile();
164 DCHECK(!callback.is_null());
165 callback.Run(error_, file_info_);
166 }
167
168 private:
169 File::Info file_info_;
170 DISALLOW_COPY_AND_ASSIGN(GetInfoHelper);
171 };
172
173 class ReadHelper : public FileHelper {
174 public:
175 ReadHelper(FileProxy* proxy, File file, int bytes_to_read)
176 : FileHelper(proxy, file.Pass()),
177 buffer_(new char[bytes_to_read]),
178 bytes_to_read_(bytes_to_read),
179 bytes_read_(0) {
180 }
181
182 void RunWork(int64 offset) {
183 bytes_read_ = file_.Read(offset, buffer_.get(), bytes_to_read_);
184 error_ = (bytes_read_ < 0) ? File::FILE_ERROR_FAILED : File::FILE_OK;
185 }
186
187 void Reply(const FileProxy::ReadCallback& callback) {
188 PassFile();
189 DCHECK(!callback.is_null());
190 callback.Run(error_, buffer_.get(), bytes_read_);
191 }
192
193 private:
194 scoped_ptr<char[]> buffer_;
195 int bytes_to_read_;
196 int bytes_read_;
197 DISALLOW_COPY_AND_ASSIGN(ReadHelper);
198 };
199
200 class WriteHelper : public FileHelper {
201 public:
202 WriteHelper(FileProxy* proxy,
203 File file,
204 const char* buffer, int bytes_to_write)
205 : FileHelper(proxy, file.Pass()),
206 buffer_(new char[bytes_to_write]),
207 bytes_to_write_(bytes_to_write),
208 bytes_written_(0) {
209 memcpy(buffer_.get(), buffer, bytes_to_write);
210 }
211
212 void RunWork(int64 offset) {
213 bytes_written_ = file_.Write(offset, buffer_.get(), bytes_to_write_);
214 error_ = (bytes_written_ < 0) ? File::FILE_ERROR_FAILED : File::FILE_OK;
215 }
216
217 void Reply(const FileProxy::WriteCallback& callback) {
218 PassFile();
219 if (!callback.is_null())
220 callback.Run(error_, bytes_written_);
221 }
222
223 private:
224 scoped_ptr<char[]> buffer_;
225 int bytes_to_write_;
226 int bytes_written_;
227 DISALLOW_COPY_AND_ASSIGN(WriteHelper);
228 };
229
230 } // namespace
231
232 FileProxy::FileProxy(TaskRunner* task_runner) : task_runner_(task_runner) {
233 }
234
235 FileProxy::~FileProxy() {
236 if (file_.IsValid())
237 task_runner_->PostTask(FROM_HERE, Bind(&FileDeleter, Passed(&file_)));
238 }
239
240 bool FileProxy::CreateOrOpen(const FilePath& file_path,
241 uint32 file_flags,
242 const StatusCallback& callback) {
243 DCHECK(!file_.IsValid());
244 CreateOrOpenHelper* helper = new CreateOrOpenHelper(this, File());
245 return task_runner_->PostTaskAndReply(
246 FROM_HERE,
247 Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), file_path,
248 file_flags),
249 Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback));
250 }
251
252 bool FileProxy::CreateTemporary(uint32 additional_file_flags,
253 const CreateTemporaryCallback& callback) {
254 DCHECK(!file_.IsValid());
255 CreateTemporaryHelper* helper = new CreateTemporaryHelper(this, File());
256 return task_runner_->PostTaskAndReply(
257 FROM_HERE,
258 Bind(&CreateTemporaryHelper::RunWork, Unretained(helper),
259 additional_file_flags),
260 Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback));
261 }
262
263 bool FileProxy::IsValid() const {
264 return file_.IsValid();
265 }
266
267 void FileProxy::SetFile(File file) {
268 DCHECK(!file_.IsValid());
269 file_ = file.Pass();
270 }
271
272 File FileProxy::TakeFile() {
273 return file_.Pass();
274 }
275
276 PlatformFile FileProxy::GetPlatformFile() const {
277 return file_.GetPlatformFile();
278 }
279
280 bool FileProxy::Close(const StatusCallback& callback) {
281 DCHECK(file_.IsValid());
282 GenericFileHelper* helper = new GenericFileHelper(this, file_.Pass());
283 return task_runner_->PostTaskAndReply(
284 FROM_HERE,
285 Bind(&GenericFileHelper::Close, Unretained(helper)),
286 Bind(&GenericFileHelper::Reply, Owned(helper), callback));
287 }
288
289 bool FileProxy::GetInfo(const GetFileInfoCallback& callback) {
290 DCHECK(file_.IsValid());
291 GetInfoHelper* helper = new GetInfoHelper(this, file_.Pass());
292 return task_runner_->PostTaskAndReply(
293 FROM_HERE,
294 Bind(&GetInfoHelper::RunWork, Unretained(helper)),
295 Bind(&GetInfoHelper::Reply, Owned(helper), callback));
296 }
297
298 bool FileProxy::Read(int64 offset,
299 int bytes_to_read,
300 const ReadCallback& callback) {
301 DCHECK(file_.IsValid());
302 if (bytes_to_read < 0)
303 return false;
304
305 ReadHelper* helper = new ReadHelper(this, file_.Pass(), bytes_to_read);
306 return task_runner_->PostTaskAndReply(
307 FROM_HERE,
308 Bind(&ReadHelper::RunWork, Unretained(helper), offset),
309 Bind(&ReadHelper::Reply, Owned(helper), callback));
310 }
311
312 bool FileProxy::Write(int64 offset,
313 const char* buffer,
314 int bytes_to_write,
315 const WriteCallback& callback) {
316 DCHECK(file_.IsValid());
317 if (bytes_to_write <= 0 || buffer == NULL)
318 return false;
319
320 WriteHelper* helper =
321 new WriteHelper(this, file_.Pass(), buffer, bytes_to_write);
322 return task_runner_->PostTaskAndReply(
323 FROM_HERE,
324 Bind(&WriteHelper::RunWork, Unretained(helper), offset),
325 Bind(&WriteHelper::Reply, Owned(helper), callback));
326 }
327
328 bool FileProxy::SetTimes(Time last_access_time,
329 Time last_modified_time,
330 const StatusCallback& callback) {
331 DCHECK(file_.IsValid());
332 GenericFileHelper* helper = new GenericFileHelper(this, file_.Pass());
333 return task_runner_->PostTaskAndReply(
334 FROM_HERE,
335 Bind(&GenericFileHelper::SetTimes, Unretained(helper), last_access_time,
336 last_modified_time),
337 Bind(&GenericFileHelper::Reply, Owned(helper), callback));
338 }
339
340 bool FileProxy::SetLength(int64 length, const StatusCallback& callback) {
341 DCHECK(file_.IsValid());
342 GenericFileHelper* helper = new GenericFileHelper(this, file_.Pass());
343 return task_runner_->PostTaskAndReply(
344 FROM_HERE,
345 Bind(&GenericFileHelper::SetLength, Unretained(helper), length),
346 Bind(&GenericFileHelper::Reply, Owned(helper), callback));
347 }
348
349 bool FileProxy::Flush(const StatusCallback& callback) {
350 DCHECK(file_.IsValid());
351 GenericFileHelper* helper = new GenericFileHelper(this, file_.Pass());
352 return task_runner_->PostTaskAndReply(
353 FROM_HERE,
354 Bind(&GenericFileHelper::Flush, Unretained(helper)),
355 Bind(&GenericFileHelper::Reply, Owned(helper), callback));
356 }
357
358 } // namespace base
OLDNEW
« no previous file with comments | « base/files/file_proxy.h ('k') | base/files/file_proxy_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698