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

Side by Side Diff: base/file_util_proxy.cc

Issue 8231004: Remaining cleanup (base::Bind): Replacing FileUtilProxy calls with new callback (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: got it building Created 9 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/file_util_proxy.h" 5 #include "base/file_util_proxy.h"
6 6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/file_util.h"
7 #include "base/message_loop_proxy.h" 10 #include "base/message_loop_proxy.h"
8 11
9 // TODO(jianli): Move the code from anonymous namespace to base namespace so 12 namespace base {
10 // that all of the base:: prefixes would be unnecessary. 13
11 namespace { 14 bool FileUtilProxy::MessageLoopRelay::Start(
12 15 scoped_refptr<MessageLoopProxy> message_loop_proxy,
13 namespace { 16 const tracked_objects::Location& from_here) {
14 17 return message_loop_proxy->PostTaskAndReply(
15 // Performs common checks for move and copy. 18 from_here,
16 // This also removes the destination directory if it's non-empty and all other 19 base::Bind(&MessageLoopRelay::RunWork, this),
17 // checks are passed (so that the copy/move correctly overwrites the 20 base::Bind(&MessageLoopRelay::RunCallback, this));
18 // destination).
19 static base::PlatformFileError PerformCommonCheckAndPreparationForMoveAndCopy(
20 const FilePath& src_file_path,
21 const FilePath& dest_file_path) {
22 // Exits earlier if the source path does not exist.
23 if (!file_util::PathExists(src_file_path))
24 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
25
26 // The parent of the |dest_file_path| does not exist.
27 if (!file_util::DirectoryExists(dest_file_path.DirName()))
28 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
29
30 // It is an error to try to copy/move an entry into its child.
31 if (src_file_path.IsParent(dest_file_path))
32 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
33
34 // Now it is ok to return if the |dest_file_path| does not exist.
35 if (!file_util::PathExists(dest_file_path))
36 return base::PLATFORM_FILE_OK;
37
38 // |src_file_path| exists and is a directory.
39 // |dest_file_path| exists and is a file.
40 bool src_is_directory = file_util::DirectoryExists(src_file_path);
41 bool dest_is_directory = file_util::DirectoryExists(dest_file_path);
42 if (src_is_directory && !dest_is_directory)
43 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
44
45 // |src_file_path| exists and is a file.
46 // |dest_file_path| exists and is a directory.
47 if (!src_is_directory && dest_is_directory)
48 return base::PLATFORM_FILE_ERROR_NOT_A_FILE;
49
50 // It is an error to copy/move an entry into the same path.
51 if (src_file_path.value() == dest_file_path.value())
52 return base::PLATFORM_FILE_ERROR_EXISTS;
53
54 if (dest_is_directory) {
55 // It is an error to copy/move an entry to a non-empty directory.
56 // Otherwise the copy/move attempt must overwrite the destination, but
57 // the file_util's Copy or Move method doesn't perform overwrite
58 // on all platforms, so we delete the destination directory here.
59 // TODO(kinuko): may be better to change the file_util::{Copy,Move}.
60 if (!file_util::Delete(dest_file_path, false /* recursive */)) {
61 if (!file_util::IsDirectoryEmpty(dest_file_path))
62 return base::PLATFORM_FILE_ERROR_NOT_EMPTY;
63 return base::PLATFORM_FILE_ERROR_FAILED;
64 }
65 }
66 return base::PLATFORM_FILE_OK;
67 } 21 }
68 22
69 } // anonymous namespace 23 class RelayCreateOrOpen : public FileUtilProxy::MessageLoopRelay {
70
71 class MessageLoopRelay
72 : public base::RefCountedThreadSafe<MessageLoopRelay> {
73 public:
74 MessageLoopRelay()
75 : origin_message_loop_proxy_(
76 base::MessageLoopProxy::current()),
77 error_code_(base::PLATFORM_FILE_OK) {
78 }
79
80 bool Start(scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
81 const tracked_objects::Location& from_here) {
82 return message_loop_proxy->PostTask(
83 from_here,
84 NewRunnableMethod(this, &MessageLoopRelay::ProcessOnTargetThread));
85 }
86
87 protected:
88 friend class base::RefCountedThreadSafe<MessageLoopRelay>;
89 virtual ~MessageLoopRelay() {}
90
91 // Called to perform work on the FILE thread.
92 virtual void RunWork() = 0;
93
94 // Called to notify the callback on the origin thread.
95 virtual void RunCallback() = 0;
96
97 void set_error_code(base::PlatformFileError error_code) {
98 error_code_ = error_code;
99 }
100
101 base::PlatformFileError error_code() const {
102 return error_code_;
103 }
104
105 private:
106 void ProcessOnTargetThread() {
107 RunWork();
108 origin_message_loop_proxy_->PostTask(
109 FROM_HERE,
110 NewRunnableMethod(this, &MessageLoopRelay::RunCallback));
111 }
112
113 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_;
114 base::PlatformFileError error_code_;
115 };
116
117 class RelayCreateOrOpen : public MessageLoopRelay {
118 public: 24 public:
119 RelayCreateOrOpen( 25 RelayCreateOrOpen(
120 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, 26 scoped_refptr<MessageLoopProxy> message_loop_proxy,
121 const FilePath& file_path, 27 const FilePath& file_path,
122 int file_flags, 28 int file_flags,
123 base::FileUtilProxy::CreateOrOpenCallback* callback) 29 const FileUtilProxy::CreateOrOpenCallback& callback)
124 : message_loop_proxy_(message_loop_proxy), 30 : message_loop_proxy_(message_loop_proxy),
125 file_path_(file_path), 31 file_path_(file_path),
126 file_flags_(file_flags), 32 file_flags_(file_flags),
127 callback_(callback), 33 callback_(callback),
128 file_handle_(base::kInvalidPlatformFileValue), 34 file_handle_(kInvalidPlatformFileValue),
129 created_(false) { 35 created_(false),
130 DCHECK(callback); 36 error_code_(PLATFORM_FILE_OK) {
37 DCHECK(!callback.is_null());
131 } 38 }
132 39
133 protected: 40 protected:
134 virtual ~RelayCreateOrOpen() { 41 virtual ~RelayCreateOrOpen() {
135 if (file_handle_ != base::kInvalidPlatformFileValue) 42 if (file_handle_ != kInvalidPlatformFileValue) {
136 base::FileUtilProxy::Close(message_loop_proxy_, file_handle_, NULL); 43 message_loop_proxy_->PostTask(
137 } 44 FROM_HERE,
138 45 base::IgnoreReturn(base::Callback<bool(void)>(
139 virtual void RunWork() { 46 base::Bind(&ClosePlatformFile, file_handle_))));
47 }
48 }
49
50 virtual void RunWork() OVERRIDE {
140 if (!file_util::DirectoryExists(file_path_.DirName())) { 51 if (!file_util::DirectoryExists(file_path_.DirName())) {
141 // If its parent does not exist, should return NOT_FOUND error. 52 // If its parent does not exist, should return NOT_FOUND error.
142 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); 53 error_code_ = PLATFORM_FILE_ERROR_NOT_FOUND;
143 return; 54 return;
144 } 55 }
145 base::PlatformFileError error_code = base::PLATFORM_FILE_OK; 56 PlatformFileError error_code = PLATFORM_FILE_OK;
146 file_handle_ = base::CreatePlatformFile(file_path_, file_flags_, 57 file_handle_ = CreatePlatformFile(file_path_, file_flags_,
147 &created_, &error_code); 58 &created_, &error_code);
148 set_error_code(error_code); 59 error_code_ = error_code;
149 } 60 }
150 61
151 virtual void RunCallback() { 62 virtual void RunCallback() OVERRIDE {
152 callback_->Run(error_code(), base::PassPlatformFile(&file_handle_), 63 callback_.Run(error_code_, PassPlatformFile(&file_handle_), created_);
153 created_); 64 }
154 delete callback_; 65
155 } 66 private:
156 67 scoped_refptr<MessageLoopProxy> message_loop_proxy_;
157 private:
158 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
159 FilePath file_path_; 68 FilePath file_path_;
160 int file_flags_; 69 int file_flags_;
161 base::FileUtilProxy::CreateOrOpenCallback* callback_; 70 FileUtilProxy::CreateOrOpenCallback callback_;
162 base::PlatformFile file_handle_; 71 PlatformFile file_handle_;
163 bool created_; 72 bool created_;
164 }; 73 PlatformFileError error_code_;
165 74 };
166 class RelayCreateTemporary : public MessageLoopRelay { 75
76 class RelayCreateTemporary : public FileUtilProxy::MessageLoopRelay {
167 public: 77 public:
168 RelayCreateTemporary( 78 RelayCreateTemporary(
169 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, 79 scoped_refptr<MessageLoopProxy> message_loop_proxy,
170 int additional_file_flags, 80 int additional_file_flags,
171 base::FileUtilProxy::CreateTemporaryCallback* callback) 81 const FileUtilProxy::CreateTemporaryCallback& callback)
172 : message_loop_proxy_(message_loop_proxy), 82 : message_loop_proxy_(message_loop_proxy),
173 additional_file_flags_(additional_file_flags), 83 additional_file_flags_(additional_file_flags),
174 callback_(callback), 84 callback_(callback),
175 file_handle_(base::kInvalidPlatformFileValue) { 85 file_handle_(kInvalidPlatformFileValue),
176 DCHECK(callback); 86 error_code_(PLATFORM_FILE_OK) {
87 DCHECK(!callback.is_null());
177 } 88 }
178 89
179 protected: 90 protected:
180 virtual ~RelayCreateTemporary() { 91 virtual ~RelayCreateTemporary() {
181 if (file_handle_ != base::kInvalidPlatformFileValue) 92 if (file_handle_ != kInvalidPlatformFileValue) {
182 base::FileUtilProxy::Close(message_loop_proxy_, file_handle_, NULL); 93 message_loop_proxy_->PostTask(
183 } 94 FROM_HERE,
184 95 base::IgnoreReturn(base::Callback<bool(void)>(
185 virtual void RunWork() { 96 base::Bind(&ClosePlatformFile, file_handle_))));
97 }
98 }
99
100 virtual void RunWork() OVERRIDE {
186 // TODO(darin): file_util should have a variant of CreateTemporaryFile 101 // TODO(darin): file_util should have a variant of CreateTemporaryFile
187 // that returns a FilePath and a PlatformFile. 102 // that returns a FilePath and a PlatformFile.
188 file_util::CreateTemporaryFile(&file_path_); 103 file_util::CreateTemporaryFile(&file_path_);
189 104
190 int file_flags = 105 int file_flags =
191 base::PLATFORM_FILE_WRITE | 106 PLATFORM_FILE_WRITE |
192 base::PLATFORM_FILE_TEMPORARY | 107 PLATFORM_FILE_TEMPORARY |
193 base::PLATFORM_FILE_CREATE_ALWAYS | 108 PLATFORM_FILE_CREATE_ALWAYS |
194 additional_file_flags_; 109 additional_file_flags_;
195 110
196 base::PlatformFileError error_code = base::PLATFORM_FILE_OK; 111 PlatformFileError error_code = PLATFORM_FILE_OK;
197 file_handle_ = base::CreatePlatformFile(file_path_, file_flags, 112 file_handle_ = CreatePlatformFile(file_path_, file_flags,
198 NULL, &error_code); 113 NULL, &error_code);
199 set_error_code(error_code); 114 error_code_ = error_code;
200 } 115 }
201 116
202 virtual void RunCallback() { 117 virtual void RunCallback() OVERRIDE {
203 callback_->Run(error_code(), base::PassPlatformFile(&file_handle_), 118 callback_.Run(error_code_, PassPlatformFile(&file_handle_), file_path_);
204 file_path_); 119 }
205 delete callback_; 120
206 } 121 private:
207 122 scoped_refptr<MessageLoopProxy> message_loop_proxy_;
208 private:
209 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
210 int additional_file_flags_; 123 int additional_file_flags_;
211 base::FileUtilProxy::CreateTemporaryCallback* callback_; 124 FileUtilProxy::CreateTemporaryCallback callback_;
212 base::PlatformFile file_handle_; 125 PlatformFile file_handle_;
213 FilePath file_path_; 126 FilePath file_path_;
214 }; 127 PlatformFileError error_code_;
215 128 };
216 class RelayWithStatusCallback : public MessageLoopRelay { 129
217 public: 130 class RelayGetFileInfo : public FileUtilProxy::MessageLoopRelay {
218 explicit RelayWithStatusCallback( 131 public:
219 base::FileUtilProxy::StatusCallback* callback) 132 RelayGetFileInfo(const FilePath& file_path,
220 : callback_(callback) { 133 const FileUtilProxy::GetFileInfoCallback& callback)
221 // It is OK for callback to be NULL. 134 : callback_(callback),
222 }
223
224 protected:
225 virtual void RunCallback() {
226 // The caller may not have been interested in the result.
227 if (callback_) {
228 callback_->Run(error_code());
229 delete callback_;
230 }
231 }
232
233 private:
234 base::FileUtilProxy::StatusCallback* callback_;
235 };
236
237 class RelayClose : public RelayWithStatusCallback {
238 public:
239 RelayClose(base::PlatformFile file_handle,
240 base::FileUtilProxy::StatusCallback* callback)
241 : RelayWithStatusCallback(callback),
242 file_handle_(file_handle) {
243 }
244
245 protected:
246 virtual void RunWork() {
247 if (!base::ClosePlatformFile(file_handle_))
248 set_error_code(base::PLATFORM_FILE_ERROR_FAILED);
249 }
250
251 private:
252 base::PlatformFile file_handle_;
253 };
254
255 class RelayEnsureFileExists : public MessageLoopRelay {
256 public:
257 RelayEnsureFileExists(
258 scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
259 const FilePath& file_path,
260 base::FileUtilProxy::EnsureFileExistsCallback* callback)
261 : message_loop_proxy_(message_loop_proxy),
262 file_path_(file_path), 135 file_path_(file_path),
263 callback_(callback), 136 error_code_(PLATFORM_FILE_OK) {
264 created_(false) { 137 DCHECK(!callback.is_null());
265 DCHECK(callback); 138 }
266 } 139
267 140 protected:
268 protected: 141 virtual void RunWork() OVERRIDE {
269 virtual void RunWork() { 142 if (!file_util::PathExists(file_path_)) {
270 if (!file_util::DirectoryExists(file_path_.DirName())) { 143 error_code_ = PLATFORM_FILE_ERROR_NOT_FOUND;
271 // If its parent does not exist, should return NOT_FOUND error.
272 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND);
273 return; 144 return;
274 } 145 }
275 base::PlatformFileError error_code = base::PLATFORM_FILE_OK; 146 if (!file_util::GetFileInfo(file_path_, &file_info_))
276 // Tries to create the |file_path_| exclusively. This should fail 147 error_code_ = PLATFORM_FILE_ERROR_FAILED;
277 // with PLATFORM_FILE_ERROR_EXISTS if the path already exists. 148 }
278 base::PlatformFile handle = base::CreatePlatformFile( 149
279 file_path_, 150 virtual void RunCallback() OVERRIDE {
280 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_READ, 151 callback_.Run(error_code_, file_info_);
281 &created_, &error_code); 152 }
282 if (error_code == base::PLATFORM_FILE_ERROR_EXISTS) { 153
283 // Make sure created_ is false. 154 private:
284 created_ = false; 155 FileUtilProxy::GetFileInfoCallback callback_;
285 error_code = base::PLATFORM_FILE_OK;
286 }
287 if (handle != base::kInvalidPlatformFileValue)
288 base::ClosePlatformFile(handle);
289 set_error_code(error_code);
290 }
291
292 virtual void RunCallback() {
293 callback_->Run(error_code(), created_);
294 delete callback_;
295 }
296
297 private:
298 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
299 FilePath file_path_; 156 FilePath file_path_;
300 base::FileUtilProxy::EnsureFileExistsCallback* callback_; 157 PlatformFileInfo file_info_;
301 bool created_; 158 PlatformFileError error_code_;
302 }; 159 };
303 160
304 class RelayDelete : public RelayWithStatusCallback { 161 class RelayGetFileInfoFromPlatformFile
305 public: 162 : public FileUtilProxy::MessageLoopRelay {
306 RelayDelete(const FilePath& file_path, 163 public:
307 bool recursive, 164 RelayGetFileInfoFromPlatformFile(
308 base::FileUtilProxy::StatusCallback* callback) 165 PlatformFile file,
309 : RelayWithStatusCallback(callback), 166 const FileUtilProxy::GetFileInfoCallback& callback)
310 file_path_(file_path),
311 recursive_(recursive) {
312 }
313
314 protected:
315 virtual void RunWork() {
316 if (!file_util::PathExists(file_path_)) {
317 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND);
318 return;
319 }
320 if (!file_util::Delete(file_path_, recursive_)) {
321 if (!recursive_ && !file_util::IsDirectoryEmpty(file_path_)) {
322 set_error_code(base::PLATFORM_FILE_ERROR_NOT_EMPTY);
323 return;
324 }
325 set_error_code(base::PLATFORM_FILE_ERROR_FAILED);
326 }
327 }
328
329 private:
330 FilePath file_path_;
331 bool recursive_;
332 };
333
334 class RelayCopy : public RelayWithStatusCallback {
335 public:
336 RelayCopy(const FilePath& src_file_path,
337 const FilePath& dest_file_path,
338 base::FileUtilProxy::StatusCallback* callback)
339 : RelayWithStatusCallback(callback),
340 src_file_path_(src_file_path),
341 dest_file_path_(dest_file_path) {
342 }
343
344 protected:
345 virtual void RunWork() {
346 set_error_code(PerformCommonCheckAndPreparationForMoveAndCopy(
347 src_file_path_, dest_file_path_));
348 if (error_code() != base::PLATFORM_FILE_OK)
349 return;
350 if (!file_util::CopyDirectory(src_file_path_, dest_file_path_,
351 true /* recursive */))
352 set_error_code(base::PLATFORM_FILE_ERROR_FAILED);
353 }
354
355 private:
356 FilePath src_file_path_;
357 FilePath dest_file_path_;
358 };
359
360 class RelayMove : public RelayWithStatusCallback {
361 public:
362 RelayMove(const FilePath& src_file_path,
363 const FilePath& dest_file_path,
364 base::FileUtilProxy::StatusCallback* callback)
365 : RelayWithStatusCallback(callback),
366 src_file_path_(src_file_path),
367 dest_file_path_(dest_file_path) {
368 }
369
370 protected:
371 virtual void RunWork() {
372 set_error_code(PerformCommonCheckAndPreparationForMoveAndCopy(
373 src_file_path_, dest_file_path_));
374 if (error_code() != base::PLATFORM_FILE_OK)
375 return;
376 if (!file_util::Move(src_file_path_, dest_file_path_))
377 set_error_code(base::PLATFORM_FILE_ERROR_FAILED);
378 }
379
380 private:
381 FilePath src_file_path_;
382 FilePath dest_file_path_;
383 };
384
385 class RelayCreateDirectory : public RelayWithStatusCallback {
386 public:
387 RelayCreateDirectory(
388 const FilePath& file_path,
389 bool exclusive,
390 bool recursive,
391 base::FileUtilProxy::StatusCallback* callback)
392 : RelayWithStatusCallback(callback),
393 file_path_(file_path),
394 exclusive_(exclusive),
395 recursive_(recursive) {
396 }
397
398 protected:
399 virtual void RunWork() {
400 bool path_exists = file_util::PathExists(file_path_);
401 // If parent dir of file doesn't exist.
402 if (!recursive_ && !file_util::PathExists(file_path_.DirName())) {
403 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND);
404 return;
405 }
406 if (exclusive_ && path_exists) {
407 set_error_code(base::PLATFORM_FILE_ERROR_EXISTS);
408 return;
409 }
410 // If file exists at the path.
411 if (path_exists && !file_util::DirectoryExists(file_path_)) {
412 set_error_code(base::PLATFORM_FILE_ERROR_EXISTS);
413 return;
414 }
415 if (!file_util::CreateDirectory(file_path_))
416 set_error_code(base::PLATFORM_FILE_ERROR_FAILED);
417 }
418
419 private:
420 FilePath file_path_;
421 bool exclusive_;
422 bool recursive_;
423 };
424
425 class RelayReadDirectory : public MessageLoopRelay {
426 public:
427 RelayReadDirectory(const FilePath& file_path,
428 base::FileUtilProxy::ReadDirectoryCallback* callback)
429 : callback_(callback), file_path_(file_path) {
430 DCHECK(callback);
431 }
432
433 protected:
434 virtual void RunWork() {
435 // TODO(kkanetkar): Implement directory read in multiple chunks.
436 if (!file_util::DirectoryExists(file_path_)) {
437 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND);
438 return;
439 }
440
441 file_util::FileEnumerator file_enum(
442 file_path_, false, static_cast<file_util::FileEnumerator::FileType>(
443 file_util::FileEnumerator::FILES |
444 file_util::FileEnumerator::DIRECTORIES));
445 FilePath current;
446 while (!(current = file_enum.Next()).empty()) {
447 base::FileUtilProxy::Entry entry;
448 file_util::FileEnumerator::FindInfo info;
449 file_enum.GetFindInfo(&info);
450 entry.is_directory = file_enum.IsDirectory(info);
451 // This will just give the entry's name instead of entire path
452 // if we use current.value().
453 entry.name = file_util::FileEnumerator::GetFilename(info).value();
454 entry.size = file_util::FileEnumerator::GetFilesize(info);
455 entry.last_modified_time =
456 file_util::FileEnumerator::GetLastModifiedTime(info);
457 entries_.push_back(entry);
458 }
459 }
460
461 virtual void RunCallback() {
462 callback_->Run(error_code(), entries_);
463 delete callback_;
464 }
465
466 private:
467 base::FileUtilProxy::ReadDirectoryCallback* callback_;
468 FilePath file_path_;
469 std::vector<base::FileUtilProxy::Entry> entries_;
470 };
471
472 class RelayGetFileInfo : public MessageLoopRelay {
473 public:
474 RelayGetFileInfo(const FilePath& file_path,
475 base::FileUtilProxy::GetFileInfoCallback* callback)
476 : callback_(callback), 167 : callback_(callback),
477 file_path_(file_path) { 168 file_(file),
478 DCHECK(callback); 169 error_code_(PLATFORM_FILE_OK) {
479 } 170 DCHECK(!callback.is_null());
480 171 }
481 protected: 172
482 virtual void RunWork() { 173 protected:
483 if (!file_util::PathExists(file_path_)) { 174 virtual void RunWork() OVERRIDE {
484 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); 175 if (!GetPlatformFileInfo(file_, &file_info_))
485 return; 176 error_code_ = PLATFORM_FILE_ERROR_FAILED;
486 } 177 }
487 if (!file_util::GetFileInfo(file_path_, &file_info_)) 178
488 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 179 virtual void RunCallback() OVERRIDE {
489 } 180 callback_.Run(error_code_, file_info_);
490 181 }
491 virtual void RunCallback() { 182
492 callback_->Run(error_code(), file_info_); 183 private:
493 delete callback_; 184 FileUtilProxy::GetFileInfoCallback callback_;
494 } 185 PlatformFile file_;
495 186 PlatformFileInfo file_info_;
496 private: 187 PlatformFileError error_code_;
497 base::FileUtilProxy::GetFileInfoCallback* callback_; 188 };
498 FilePath file_path_; 189
499 base::PlatformFileInfo file_info_; 190 class RelayRead : public FileUtilProxy::MessageLoopRelay {
500 }; 191 public:
501 192 RelayRead(PlatformFile file,
502 class RelayGetFileInfoFromPlatformFile : public MessageLoopRelay {
503 public:
504 RelayGetFileInfoFromPlatformFile(
505 base::PlatformFile file,
506 base::FileUtilProxy::GetFileInfoCallback* callback)
507 : callback_(callback),
508 file_(file) {
509 DCHECK(callback);
510 }
511
512 protected:
513 virtual void RunWork() {
514 if (!base::GetPlatformFileInfo(file_, &file_info_))
515 set_error_code(base::PLATFORM_FILE_ERROR_FAILED);
516 }
517
518 virtual void RunCallback() {
519 callback_->Run(error_code(), file_info_);
520 delete callback_;
521 }
522
523 private:
524 base::FileUtilProxy::GetFileInfoCallback* callback_;
525 base::PlatformFile file_;
526 base::PlatformFileInfo file_info_;
527 };
528
529 class RelayRead : public MessageLoopRelay {
530 public:
531 RelayRead(base::PlatformFile file,
532 int64 offset, 193 int64 offset,
533 int bytes_to_read, 194 int bytes_to_read,
534 base::FileUtilProxy::ReadCallback* callback) 195 const FileUtilProxy::ReadCallback& callback)
535 : file_(file), 196 : file_(file),
536 offset_(offset), 197 offset_(offset),
537 buffer_(new char[bytes_to_read]), 198 buffer_(new char[bytes_to_read]),
538 bytes_to_read_(bytes_to_read), 199 bytes_to_read_(bytes_to_read),
539 callback_(callback), 200 callback_(callback),
540 bytes_read_(0) { 201 bytes_read_(0),
541 } 202 error_code_(PLATFORM_FILE_OK) {
542 203 }
543 protected: 204
544 virtual void RunWork() { 205 protected:
545 bytes_read_ = base::ReadPlatformFile(file_, offset_, buffer_.get(), 206 virtual void RunWork() OVERRIDE {
546 bytes_to_read_); 207 bytes_read_ = ReadPlatformFile(file_, offset_, buffer_.get(),
208 bytes_to_read_);
547 if (bytes_read_ < 0) 209 if (bytes_read_ < 0)
548 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 210 error_code_ = PLATFORM_FILE_ERROR_FAILED;
549 } 211 }
550 212
551 virtual void RunCallback() { 213 virtual void RunCallback() OVERRIDE {
552 if (callback_) { 214 if (!callback_.is_null()) {
553 callback_->Run(error_code(), buffer_.get(), bytes_read_); 215 callback_.Run(error_code_, buffer_.get(), bytes_read_);
554 delete callback_; 216 }
555 } 217 }
556 } 218
557 219 private:
558 private: 220 PlatformFile file_;
559 base::PlatformFile file_;
560 int64 offset_; 221 int64 offset_;
561 scoped_array<char> buffer_; 222 scoped_array<char> buffer_;
562 int bytes_to_read_; 223 int bytes_to_read_;
563 base::FileUtilProxy::ReadCallback* callback_; 224 FileUtilProxy::ReadCallback callback_;
564 int bytes_read_; 225 int bytes_read_;
565 }; 226 PlatformFileError error_code_;
566 227 };
567 class RelayWrite : public MessageLoopRelay { 228
568 public: 229 class RelayWrite : public FileUtilProxy::MessageLoopRelay {
569 RelayWrite(base::PlatformFile file, 230 public:
231 RelayWrite(PlatformFile file,
570 int64 offset, 232 int64 offset,
571 const char* buffer, 233 const char* buffer,
572 int bytes_to_write, 234 int bytes_to_write,
573 base::FileUtilProxy::WriteCallback* callback) 235 const FileUtilProxy::WriteCallback& callback)
574 : file_(file), 236 : file_(file),
575 offset_(offset), 237 offset_(offset),
576 buffer_(new char[bytes_to_write]), 238 buffer_(new char[bytes_to_write]),
577 bytes_to_write_(bytes_to_write), 239 bytes_to_write_(bytes_to_write),
578 callback_(callback), 240 callback_(callback),
579 bytes_written_(0) { 241 bytes_written_(0),
242 error_code_(PLATFORM_FILE_OK) {
580 memcpy(buffer_.get(), buffer, bytes_to_write); 243 memcpy(buffer_.get(), buffer, bytes_to_write);
581 } 244 }
582 245
583 protected: 246 protected:
584 virtual void RunWork() { 247 virtual void RunWork() OVERRIDE {
585 bytes_written_ = base::WritePlatformFile(file_, offset_, buffer_.get(), 248 bytes_written_ = WritePlatformFile(file_, offset_, buffer_.get(),
586 bytes_to_write_); 249 bytes_to_write_);
587 if (bytes_written_ < 0) 250 if (bytes_written_ < 0)
588 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 251 error_code_ = PLATFORM_FILE_ERROR_FAILED;
589 } 252 }
590 253
591 virtual void RunCallback() { 254 virtual void RunCallback() OVERRIDE {
592 if (callback_) { 255 if (!callback_.is_null()) {
593 callback_->Run(error_code(), bytes_written_); 256 callback_.Run(error_code_, bytes_written_);
594 delete callback_; 257 }
595 } 258 }
596 } 259
597 260 private:
598 private: 261 PlatformFile file_;
599 base::PlatformFile file_;
600 int64 offset_; 262 int64 offset_;
601 scoped_array<char> buffer_; 263 scoped_array<char> buffer_;
602 int bytes_to_write_; 264 int bytes_to_write_;
603 base::FileUtilProxy::WriteCallback* callback_; 265 FileUtilProxy::WriteCallback callback_;
604 int bytes_written_; 266 int bytes_written_;
605 }; 267 PlatformFileError error_code_;
606
607 class RelayTouch : public RelayWithStatusCallback {
608 public:
609 RelayTouch(base::PlatformFile file,
610 const base::Time& last_access_time,
611 const base::Time& last_modified_time,
612 base::FileUtilProxy::StatusCallback* callback)
613 : RelayWithStatusCallback(callback),
614 file_(file),
615 last_access_time_(last_access_time),
616 last_modified_time_(last_modified_time) {
617 }
618
619 protected:
620 virtual void RunWork() {
621 if (!base::TouchPlatformFile(file_, last_access_time_, last_modified_time_))
622 set_error_code(base::PLATFORM_FILE_ERROR_FAILED);
623 }
624
625 private:
626 base::PlatformFile file_;
627 base::Time last_access_time_;
628 base::Time last_modified_time_;
629 };
630
631 class RelayTouchFilePath : public RelayWithStatusCallback {
632 public:
633 RelayTouchFilePath(const FilePath& file_path,
634 const base::Time& last_access_time,
635 const base::Time& last_modified_time,
636 base::FileUtilProxy::StatusCallback* callback)
637 : RelayWithStatusCallback(callback),
638 file_path_(file_path),
639 last_access_time_(last_access_time),
640 last_modified_time_(last_modified_time) {
641 }
642
643 protected:
644 virtual void RunWork() {
645 if (!file_util::TouchFile(
646 file_path_, last_access_time_, last_modified_time_))
647 set_error_code(base::PLATFORM_FILE_ERROR_FAILED);
648 }
649
650 private:
651 FilePath file_path_;
652 base::Time last_access_time_;
653 base::Time last_modified_time_;
654 };
655
656 class RelayTruncatePlatformFile : public RelayWithStatusCallback {
657 public:
658 RelayTruncatePlatformFile(base::PlatformFile file,
659 int64 length,
660 base::FileUtilProxy::StatusCallback* callback)
661 : RelayWithStatusCallback(callback),
662 file_(file),
663 length_(length) {
664 }
665
666 protected:
667 virtual void RunWork() {
668 if (!base::TruncatePlatformFile(file_, length_))
669 set_error_code(base::PLATFORM_FILE_ERROR_FAILED);
670 }
671
672 private:
673 base::PlatformFile file_;
674 int64 length_;
675 };
676
677 class RelayTruncate : public RelayWithStatusCallback {
678 public:
679 RelayTruncate(const FilePath& path,
680 int64 length,
681 base::FileUtilProxy::StatusCallback* callback)
682 : RelayWithStatusCallback(callback),
683 path_(path),
684 length_(length) {
685 }
686
687 protected:
688 virtual void RunWork() {
689 base::PlatformFileError error_code(base::PLATFORM_FILE_ERROR_FAILED);
690 base::PlatformFile file =
691 base::CreatePlatformFile(
692 path_,
693 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
694 NULL,
695 &error_code);
696 if (error_code != base::PLATFORM_FILE_OK) {
697 set_error_code(error_code);
698 return;
699 }
700 if (!base::TruncatePlatformFile(file, length_))
701 set_error_code(base::PLATFORM_FILE_ERROR_FAILED);
702 base::ClosePlatformFile(file);
703 }
704
705 private:
706 FilePath path_;
707 int64 length_;
708 };
709
710 class RelayFlush : public RelayWithStatusCallback {
711 public:
712 RelayFlush(base::PlatformFile file,
713 base::FileUtilProxy::StatusCallback* callback)
714 : RelayWithStatusCallback(callback),
715 file_(file) {
716 }
717
718 protected:
719 virtual void RunWork() {
720 if (!base::FlushPlatformFile(file_))
721 set_error_code(base::PLATFORM_FILE_ERROR_FAILED);
722 }
723
724 private:
725 base::PlatformFile file_;
726 }; 268 };
727 269
728 bool Start(const tracked_objects::Location& from_here, 270 bool Start(const tracked_objects::Location& from_here,
729 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, 271 scoped_refptr<MessageLoopProxy> message_loop_proxy,
730 scoped_refptr<MessageLoopRelay> relay) { 272 scoped_refptr<FileUtilProxy::MessageLoopRelay> relay) {
731 return relay->Start(message_loop_proxy, from_here); 273 return relay->Start(message_loop_proxy, from_here);
732 } 274 }
733 275
734 } // namespace 276 } // namespace
735 277
736 namespace base { 278 namespace base {
737 279
738 // static 280 // static
739 bool FileUtilProxy::CreateOrOpen( 281 bool FileUtilProxy::CreateOrOpen(
740 scoped_refptr<MessageLoopProxy> message_loop_proxy, 282 scoped_refptr<MessageLoopProxy> message_loop_proxy,
741 const FilePath& file_path, int file_flags, 283 const FilePath& file_path, int file_flags,
742 CreateOrOpenCallback* callback) { 284 const CreateOrOpenCallback& callback) {
743 return Start(FROM_HERE, message_loop_proxy, new RelayCreateOrOpen( 285 return Start(FROM_HERE, message_loop_proxy, new RelayCreateOrOpen(
744 message_loop_proxy, file_path, file_flags, callback)); 286 message_loop_proxy, file_path, file_flags, callback));
745 } 287 }
746 288
747 // static 289 // static
748 bool FileUtilProxy::CreateTemporary( 290 bool FileUtilProxy::CreateTemporary(
749 scoped_refptr<MessageLoopProxy> message_loop_proxy, 291 scoped_refptr<MessageLoopProxy> message_loop_proxy,
750 int additional_file_flags, 292 int additional_file_flags,
751 CreateTemporaryCallback* callback) { 293 const CreateTemporaryCallback& callback) {
752 return Start(FROM_HERE, message_loop_proxy, 294 return Start(FROM_HERE, message_loop_proxy,
753 new RelayCreateTemporary(message_loop_proxy, 295 new RelayCreateTemporary(message_loop_proxy,
754 additional_file_flags, 296 additional_file_flags,
755 callback)); 297 callback));
756 } 298 }
757 299
758 // static
759 bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy,
760 base::PlatformFile file_handle,
761 StatusCallback* callback) {
762 return Start(FROM_HERE, message_loop_proxy,
763 new RelayClose(file_handle, callback));
764 }
765
766 // static
767 bool FileUtilProxy::EnsureFileExists(
768 scoped_refptr<MessageLoopProxy> message_loop_proxy,
769 const FilePath& file_path,
770 EnsureFileExistsCallback* callback) {
771 return Start(FROM_HERE, message_loop_proxy, new RelayEnsureFileExists(
772 message_loop_proxy, file_path, callback));
773 }
774
775 // Retrieves the information about a file. It is invalid to pass NULL for the 300 // Retrieves the information about a file. It is invalid to pass NULL for the
776 // callback. 301 // callback.
777 bool FileUtilProxy::GetFileInfo( 302 bool FileUtilProxy::GetFileInfo(
778 scoped_refptr<MessageLoopProxy> message_loop_proxy, 303 scoped_refptr<MessageLoopProxy> message_loop_proxy,
779 const FilePath& file_path, 304 const FilePath& file_path,
780 GetFileInfoCallback* callback) { 305 const GetFileInfoCallback& callback) {
781 return Start(FROM_HERE, message_loop_proxy, new RelayGetFileInfo( 306 return Start(FROM_HERE, message_loop_proxy, new RelayGetFileInfo(
782 file_path, callback)); 307 file_path, callback));
783 } 308 }
784 309
785 // static 310 // static
786 bool FileUtilProxy::GetFileInfoFromPlatformFile( 311 bool FileUtilProxy::GetFileInfoFromPlatformFile(
787 scoped_refptr<MessageLoopProxy> message_loop_proxy, 312 scoped_refptr<MessageLoopProxy> message_loop_proxy,
788 PlatformFile file, 313 PlatformFile file,
789 GetFileInfoCallback* callback) { 314 const GetFileInfoCallback& callback) {
790 return Start(FROM_HERE, message_loop_proxy, 315 return Start(FROM_HERE, message_loop_proxy,
791 new RelayGetFileInfoFromPlatformFile(file, callback)); 316 new RelayGetFileInfoFromPlatformFile(file, callback));
792 } 317 }
793 318
794 // static 319 // static
795 bool FileUtilProxy::ReadDirectory(
796 scoped_refptr<MessageLoopProxy> message_loop_proxy,
797 const FilePath& file_path,
798 ReadDirectoryCallback* callback) {
799 return Start(FROM_HERE, message_loop_proxy, new RelayReadDirectory(
800 file_path, callback));
801 }
802
803 // static
804 bool FileUtilProxy::CreateDirectory(
805 scoped_refptr<MessageLoopProxy> message_loop_proxy,
806 const FilePath& file_path,
807 bool exclusive,
808 bool recursive,
809 StatusCallback* callback) {
810 return Start(FROM_HERE, message_loop_proxy, new RelayCreateDirectory(
811 file_path, exclusive, recursive, callback));
812 }
813
814 // static
815 bool FileUtilProxy::Copy(scoped_refptr<MessageLoopProxy> message_loop_proxy,
816 const FilePath& src_file_path,
817 const FilePath& dest_file_path,
818 StatusCallback* callback) {
819 return Start(FROM_HERE, message_loop_proxy,
820 new RelayCopy(src_file_path, dest_file_path, callback));
821 }
822
823 // static
824 bool FileUtilProxy::Move(scoped_refptr<MessageLoopProxy> message_loop_proxy,
825 const FilePath& src_file_path,
826 const FilePath& dest_file_path,
827 StatusCallback* callback) {
828 return Start(FROM_HERE, message_loop_proxy,
829 new RelayMove(src_file_path, dest_file_path, callback));
830 }
831
832 // static
833 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy,
834 const FilePath& file_path,
835 bool recursive,
836 StatusCallback* callback) {
837 return Start(FROM_HERE, message_loop_proxy,
838 new RelayDelete(file_path, recursive, callback));
839 }
840
841 // static
842 bool FileUtilProxy::RecursiveDelete(
843 scoped_refptr<MessageLoopProxy> message_loop_proxy,
844 const FilePath& file_path,
845 StatusCallback* callback) {
846 return Start(FROM_HERE, message_loop_proxy,
847 new RelayDelete(file_path, true, callback));
848 }
849
850 // static
851 bool FileUtilProxy::Read( 320 bool FileUtilProxy::Read(
852 scoped_refptr<MessageLoopProxy> message_loop_proxy, 321 scoped_refptr<MessageLoopProxy> message_loop_proxy,
853 PlatformFile file, 322 PlatformFile file,
854 int64 offset, 323 int64 offset,
855 int bytes_to_read, 324 int bytes_to_read,
856 ReadCallback* callback) { 325 const ReadCallback& callback) {
857 if (bytes_to_read < 0) { 326 if (bytes_to_read < 0) {
858 delete callback;
859 return false; 327 return false;
860 } 328 }
861 return Start(FROM_HERE, message_loop_proxy, 329 return Start(FROM_HERE, message_loop_proxy,
862 new RelayRead(file, offset, bytes_to_read, callback)); 330 new RelayRead(file, offset, bytes_to_read, callback));
863 } 331 }
864 332
865 // static 333 // static
866 bool FileUtilProxy::Write( 334 bool FileUtilProxy::Write(
867 scoped_refptr<MessageLoopProxy> message_loop_proxy, 335 scoped_refptr<MessageLoopProxy> message_loop_proxy,
868 PlatformFile file, 336 PlatformFile file,
869 int64 offset, 337 int64 offset,
870 const char* buffer, 338 const char* buffer,
871 int bytes_to_write, 339 int bytes_to_write,
872 WriteCallback* callback) { 340 const WriteCallback& callback) {
873 if (bytes_to_write <= 0) { 341 if (bytes_to_write <= 0) {
874 delete callback;
875 return false; 342 return false;
876 } 343 }
877 return Start(FROM_HERE, message_loop_proxy, 344 return Start(FROM_HERE, message_loop_proxy,
878 new RelayWrite(file, offset, buffer, bytes_to_write, callback)); 345 new RelayWrite(file, offset, buffer, bytes_to_write, callback));
879 } 346 }
880 347
881 // static
882 bool FileUtilProxy::Touch(
883 scoped_refptr<MessageLoopProxy> message_loop_proxy,
884 PlatformFile file,
885 const base::Time& last_access_time,
886 const base::Time& last_modified_time,
887 StatusCallback* callback) {
888 return Start(FROM_HERE, message_loop_proxy,
889 new RelayTouch(file, last_access_time, last_modified_time,
890 callback));
891 }
892
893 // static
894 bool FileUtilProxy::Touch(
895 scoped_refptr<MessageLoopProxy> message_loop_proxy,
896 const FilePath& file_path,
897 const base::Time& last_access_time,
898 const base::Time& last_modified_time,
899 StatusCallback* callback) {
900 return Start(FROM_HERE, message_loop_proxy,
901 new RelayTouchFilePath(file_path, last_access_time,
902 last_modified_time, callback));
903 }
904
905 // static
906 bool FileUtilProxy::Truncate(
907 scoped_refptr<MessageLoopProxy> message_loop_proxy,
908 PlatformFile file,
909 int64 length,
910 StatusCallback* callback) {
911 return Start(FROM_HERE, message_loop_proxy,
912 new RelayTruncatePlatformFile(file, length, callback));
913 }
914
915 // static
916 bool FileUtilProxy::Truncate(
917 scoped_refptr<MessageLoopProxy> message_loop_proxy,
918 const FilePath& path,
919 int64 length,
920 StatusCallback* callback) {
921 return Start(FROM_HERE, message_loop_proxy,
922 new RelayTruncate(path, length, callback));
923 }
924
925 // static
926 bool FileUtilProxy::Flush(
927 scoped_refptr<MessageLoopProxy> message_loop_proxy,
928 PlatformFile file,
929 StatusCallback* callback) {
930 return Start(FROM_HERE, message_loop_proxy, new RelayFlush(file, callback));
931 }
932
933 } // namespace base 348 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698