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

Side by Side Diff: base/file_util_proxy.cc

Issue 8424007: Bind: Merge FileUtilProxy and FileSystemFileUtilProxy: Delete/Touch/Truncate/Copy/Move (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased2 Created 9 years, 1 month 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
« no previous file with comments | « base/file_util_proxy.h ('k') | webkit/fileapi/file_system_file_util_proxy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/message_loop_proxy.h" 10 #include "base/message_loop_proxy.h"
11 11
12 namespace base { 12 namespace base {
13 13
14 namespace { 14 namespace {
15 15
16 // Helper templates to call file_util or base::PlatformFile methods 16 // Helper templates to call file_util or base::PlatformFile methods
17 // and reply with the returned value. 17 // and reply with the returned value.
18 // 18 //
19 // Typically when you have these methods: 19 // Typically when you have these methods:
20 // R DoWorkAndReturn(); 20 // R DoWorkAndReturn();
21 // void Callback(R& result); 21 // void Callback(R& result);
22 // 22 //
23 // You can pass the result of DoWorkAndReturn to the Callback by: 23 // You can pass the result of DoWorkAndReturn to the Callback by:
24 // 24 //
25 // R* result = new R; 25 // R* result = new R;
26 // message_loop_proxy->PostTaskAndReply( 26 // message_loop_proxy->PostTaskAndReply(
27 // from_here, 27 // from_here,
28 // ReturnAsParam<R>(Bind(&DoWorkAndReturn), result), 28 // ReturnAsParam<R>(Bind(&DoWorkAndReturn), result),
29 // CallbackWithReturn(Bind(&Callback), Owned(result))); 29 // RelayHelper(Bind(&Callback), Owned(result)));
30 // 30 //
31 // Or just use PostTaskAndReplyWithStatus helper template (see the code below). 31 // Or just use PostTaskAndReplyWithStatus helper template (see the code below).
32 template <typename R1, typename R2> 32 template <typename R1, typename R2>
33 struct ReturnValueTranslator { 33 struct ReturnValueTranslator {
34 static R2 Value(const R1& value); 34 static R2 Value(const R1& value);
35 }; 35 };
36 36
37 template <typename R> 37 template <typename R>
38 struct ReturnValueTranslator<R, R> { 38 struct ReturnValueTranslator<R, R> {
39 static R Value(const R& value) { return value; } 39 static R Value(const R& value) { return value; }
(...skipping 13 matching lines...) Expand all
53 if (!func.is_null()) 53 if (!func.is_null())
54 *result = ReturnValueTranslator<R1, R2>::Value(func.Run()); 54 *result = ReturnValueTranslator<R1, R2>::Value(func.Run());
55 } 55 }
56 56
57 template <typename R1, typename R2> 57 template <typename R1, typename R2>
58 Closure ReturnAsParam(const Callback<R1(void)>& func, R2* result) { 58 Closure ReturnAsParam(const Callback<R1(void)>& func, R2* result) {
59 DCHECK(result); 59 DCHECK(result);
60 return Bind(&ReturnAsParamAdapter<R1, R2>, func, result); 60 return Bind(&ReturnAsParamAdapter<R1, R2>, func, result);
61 } 61 }
62 62
63 template <typename R, typename A1>
64 void ReturnAsParamAdapter1(const Callback<R(A1)>& func, A1 a1, R* result) {
65 if (!func.is_null())
66 *result = func.Run(a1);
67 }
68
69 template <typename R, typename A1>
70 Closure ReturnAsParam(const Callback<R(A1)>& func, A1 a1, R* result) {
71 DCHECK(result);
72 return Bind(&ReturnAsParamAdapter1<R, A1>, func, a1, result);
73 }
74
63 template <typename R> 75 template <typename R>
64 void ReplyAdapter(const Callback<void(R)>& callback, R* result) { 76 void ReplyAdapter(const Callback<void(R)>& callback, R* result) {
65 DCHECK(result); 77 DCHECK(result);
66 if (!callback.is_null()) 78 if (!callback.is_null())
67 callback.Run(*result); 79 callback.Run(*result);
68 } 80 }
69 81
70 template <typename R, typename OWNED> 82 template <typename R, typename OWNED>
71 Closure ReplyHelper(const Callback<void(R)>& callback, OWNED result) { 83 Closure ReplyHelper(const Callback<void(R)>& callback, OWNED result) {
72 return Bind(&ReplyAdapter<R>, callback, result); 84 return Bind(&ReplyAdapter<R>, callback, result);
73 } 85 }
74 86
75 // Putting everything together. 87 // Putting everything together.
76 template <typename R1, typename R2> 88 template <typename R1, typename R2>
77 bool PostTaskAndReplyWithStatus( 89 bool PostTaskAndReplyWithStatus(
78 const scoped_refptr<MessageLoopProxy>& message_loop_proxy, 90 const scoped_refptr<MessageLoopProxy>& message_loop_proxy,
79 const tracked_objects::Location& from_here, 91 const tracked_objects::Location& from_here,
80 const Callback<R1(void)>& file_util_work, 92 const Callback<R1(void)>& file_util_work,
81 const Callback<void(R2)>& callback, 93 const Callback<void(R2)>& callback,
82 R2* result) { 94 R2* result) {
83 return message_loop_proxy->PostTaskAndReply( 95 return message_loop_proxy->PostTaskAndReply(
84 from_here, 96 from_here,
85 ReturnAsParam<R1>(file_util_work, result), 97 ReturnAsParam<R1>(file_util_work, result),
86 ReplyHelper(callback, Owned(result))); 98 ReplyHelper(callback, Owned(result)));
87 } 99 }
88 100
89 // Helper classes or routines for individual methods. 101 // Helper classes or routines for individual methods.
90 class CreateOrOpenHelper { 102 class CreateOrOpenHelper {
91 public: 103 public:
92 CreateOrOpenHelper(MessageLoopProxy* message_loop_proxy) 104 CreateOrOpenHelper(MessageLoopProxy* message_loop_proxy,
105 const FileUtilProxy::CloseTask& close_task)
93 : message_loop_proxy_(message_loop_proxy), 106 : message_loop_proxy_(message_loop_proxy),
107 close_task_(close_task),
94 file_handle_(kInvalidPlatformFileValue), 108 file_handle_(kInvalidPlatformFileValue),
95 created_(false), 109 created_(false),
96 error_(PLATFORM_FILE_OK) {} 110 error_(PLATFORM_FILE_OK) {}
97 111
98 ~CreateOrOpenHelper() { 112 ~CreateOrOpenHelper() {
99 if (file_handle_ != kInvalidPlatformFileValue) { 113 if (file_handle_ != kInvalidPlatformFileValue) {
100 FileUtilProxy::Close(message_loop_proxy_, file_handle_, 114 message_loop_proxy_->PostTask(
101 FileUtilProxy::StatusCallback()); 115 FROM_HERE, base::Bind(close_task_, file_handle_));
102 } 116 }
103 } 117 }
104 118
105 void RunWork(const FilePath& file_path, int file_flags) { 119 void RunWork(const FileUtilProxy::CreateOrOpenTask& task) {
106 if (!file_util::DirectoryExists(file_path.DirName())) { 120 error_ = task.Run(&file_handle_, &created_);
107 // If its parent does not exist, should return NOT_FOUND error.
108 error_ = PLATFORM_FILE_ERROR_NOT_FOUND;
109 return;
110 }
111 error_ = PLATFORM_FILE_OK;
112 file_handle_ = CreatePlatformFile(file_path, file_flags,
113 &created_, &error_);
114 } 121 }
115 122
116 void Reply(const FileUtilProxy::CreateOrOpenCallback& callback) { 123 void Reply(const FileUtilProxy::CreateOrOpenCallback& callback) {
117 DCHECK(!callback.is_null()); 124 DCHECK(!callback.is_null());
118 callback.Run(error_, PassPlatformFile(&file_handle_), created_); 125 callback.Run(error_, PassPlatformFile(&file_handle_), created_);
119 } 126 }
120 127
121 private: 128 private:
122 scoped_refptr<MessageLoopProxy> message_loop_proxy_; 129 scoped_refptr<MessageLoopProxy> message_loop_proxy_;
130 FileUtilProxy::CloseTask close_task_;
123 PlatformFile file_handle_; 131 PlatformFile file_handle_;
124 bool created_; 132 bool created_;
125 PlatformFileError error_; 133 PlatformFileError error_;
126 DISALLOW_COPY_AND_ASSIGN(CreateOrOpenHelper); 134 DISALLOW_COPY_AND_ASSIGN(CreateOrOpenHelper);
127 }; 135 };
128 136
129 class CreateTemporaryHelper { 137 class CreateTemporaryHelper {
130 public: 138 public:
131 CreateTemporaryHelper(MessageLoopProxy* message_loop_proxy) 139 CreateTemporaryHelper(MessageLoopProxy* message_loop_proxy)
132 : message_loop_proxy_(message_loop_proxy), 140 : message_loop_proxy_(message_loop_proxy),
(...skipping 28 matching lines...) Expand all
161 } 169 }
162 170
163 private: 171 private:
164 scoped_refptr<MessageLoopProxy> message_loop_proxy_; 172 scoped_refptr<MessageLoopProxy> message_loop_proxy_;
165 PlatformFile file_handle_; 173 PlatformFile file_handle_;
166 FilePath file_path_; 174 FilePath file_path_;
167 PlatformFileError error_; 175 PlatformFileError error_;
168 DISALLOW_COPY_AND_ASSIGN(CreateTemporaryHelper); 176 DISALLOW_COPY_AND_ASSIGN(CreateTemporaryHelper);
169 }; 177 };
170 178
171 PlatformFileError DeleteHelper(const FilePath& file_path, bool recursive) {
172 if (!file_util::PathExists(file_path)) {
173 return PLATFORM_FILE_ERROR_NOT_FOUND;
174 }
175 if (!file_util::Delete(file_path, recursive)) {
176 if (!recursive && !file_util::IsDirectoryEmpty(file_path)) {
177 return PLATFORM_FILE_ERROR_NOT_EMPTY;
178 }
179 return PLATFORM_FILE_ERROR_FAILED;
180 }
181 return PLATFORM_FILE_OK;
182 }
183
184 class GetFileInfoHelper { 179 class GetFileInfoHelper {
185 public: 180 public:
186 GetFileInfoHelper() 181 GetFileInfoHelper()
187 : error_(PLATFORM_FILE_OK) {} 182 : error_(PLATFORM_FILE_OK) {}
188 183
189 void RunWorkForFilePath(const FilePath& file_path) { 184 void RunWorkForFilePath(const FilePath& file_path) {
190 if (!file_util::PathExists(file_path)) { 185 if (!file_util::PathExists(file_path)) {
191 error_ = PLATFORM_FILE_ERROR_NOT_FOUND; 186 error_ = PLATFORM_FILE_ERROR_NOT_FOUND;
192 return; 187 return;
193 } 188 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 } 255 }
261 } 256 }
262 257
263 private: 258 private:
264 scoped_array<char> buffer_; 259 scoped_array<char> buffer_;
265 int bytes_to_write_; 260 int bytes_to_write_;
266 int bytes_written_; 261 int bytes_written_;
267 DISALLOW_COPY_AND_ASSIGN(WriteHelper); 262 DISALLOW_COPY_AND_ASSIGN(WriteHelper);
268 }; 263 };
269 264
265
266 PlatformFileError CreateOrOpenAdapter(
267 const FilePath& file_path, int file_flags,
268 PlatformFile* file_handle, bool* created) {
269 DCHECK(file_handle);
270 DCHECK(created);
271 if (!file_util::DirectoryExists(file_path.DirName())) {
272 // If its parent does not exist, should return NOT_FOUND error.
273 return PLATFORM_FILE_ERROR_NOT_FOUND;
274 }
275 PlatformFileError error = PLATFORM_FILE_OK;
276 *file_handle = CreatePlatformFile(file_path, file_flags, created, &error);
277 return error;
278 }
279
280 PlatformFileError CloseAdapter(PlatformFile file_handle) {
281 if (!ClosePlatformFile(file_handle)) {
282 return PLATFORM_FILE_ERROR_FAILED;
283 }
284 return PLATFORM_FILE_OK;
285 }
286
287 PlatformFileError DeleteAdapter(const FilePath& file_path, bool recursive) {
288 if (!file_util::PathExists(file_path)) {
289 return PLATFORM_FILE_ERROR_NOT_FOUND;
290 }
291 if (!file_util::Delete(file_path, recursive)) {
292 if (!recursive && !file_util::IsDirectoryEmpty(file_path)) {
293 return PLATFORM_FILE_ERROR_NOT_EMPTY;
294 }
295 return PLATFORM_FILE_ERROR_FAILED;
296 }
297 return PLATFORM_FILE_OK;
298 }
299
270 } // namespace 300 } // namespace
271 301
272 // static 302 // static
273 bool FileUtilProxy::CreateOrOpen( 303 bool FileUtilProxy::CreateOrOpen(
274 scoped_refptr<MessageLoopProxy> message_loop_proxy, 304 scoped_refptr<MessageLoopProxy> message_loop_proxy,
275 const FilePath& file_path, int file_flags, 305 const FilePath& file_path, int file_flags,
276 const CreateOrOpenCallback& callback) { 306 const CreateOrOpenCallback& callback) {
277 CreateOrOpenHelper* helper = new CreateOrOpenHelper(message_loop_proxy); 307 return RelayCreateOrOpen(
278 return message_loop_proxy->PostTaskAndReply( 308 message_loop_proxy,
279 FROM_HERE, 309 base::Bind(&CreateOrOpenAdapter, file_path, file_flags),
280 Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), 310 base::Bind(&CloseAdapter),
281 file_path, file_flags), 311 callback);
282 Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback));
283 } 312 }
284 313
285 // static 314 // static
286 bool FileUtilProxy::CreateTemporary( 315 bool FileUtilProxy::CreateTemporary(
287 scoped_refptr<MessageLoopProxy> message_loop_proxy, 316 scoped_refptr<MessageLoopProxy> message_loop_proxy,
288 int additional_file_flags, 317 int additional_file_flags,
289 const CreateTemporaryCallback& callback) { 318 const CreateTemporaryCallback& callback) {
290 CreateTemporaryHelper* helper = new CreateTemporaryHelper(message_loop_proxy); 319 CreateTemporaryHelper* helper = new CreateTemporaryHelper(message_loop_proxy);
291 return message_loop_proxy->PostTaskAndReply( 320 return message_loop_proxy->PostTaskAndReply(
292 FROM_HERE, 321 FROM_HERE,
293 Bind(&CreateTemporaryHelper::RunWork, Unretained(helper), 322 Bind(&CreateTemporaryHelper::RunWork, Unretained(helper),
294 additional_file_flags), 323 additional_file_flags),
295 Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback)); 324 Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback));
296 } 325 }
297 326
298 // static 327 // static
299 bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy, 328 bool FileUtilProxy::Close(
300 PlatformFile file_handle, 329 scoped_refptr<MessageLoopProxy> message_loop_proxy,
301 const StatusCallback& callback) { 330 base::PlatformFile file_handle,
302 return PostTaskAndReplyWithStatus<bool>( 331 const StatusCallback& callback) {
303 message_loop_proxy, FROM_HERE, 332 return RelayClose(
304 Bind(&ClosePlatformFile, file_handle), callback, 333 message_loop_proxy,
305 new PlatformFileError); 334 base::Bind(&CloseAdapter),
335 file_handle, callback);
306 } 336 }
307 337
308 // Retrieves the information about a file. It is invalid to pass NULL for the 338 // Retrieves the information about a file. It is invalid to pass NULL for the
309 // callback. 339 // callback.
310 bool FileUtilProxy::GetFileInfo( 340 bool FileUtilProxy::GetFileInfo(
311 scoped_refptr<MessageLoopProxy> message_loop_proxy, 341 scoped_refptr<MessageLoopProxy> message_loop_proxy,
312 const FilePath& file_path, 342 const FilePath& file_path,
313 const GetFileInfoCallback& callback) { 343 const GetFileInfoCallback& callback) {
314 GetFileInfoHelper* helper = new GetFileInfoHelper; 344 GetFileInfoHelper* helper = new GetFileInfoHelper;
315 return message_loop_proxy->PostTaskAndReply( 345 return message_loop_proxy->PostTaskAndReply(
(...skipping 14 matching lines...) Expand all
330 Bind(&GetFileInfoHelper::RunWorkForPlatformFile, 360 Bind(&GetFileInfoHelper::RunWorkForPlatformFile,
331 Unretained(helper), file), 361 Unretained(helper), file),
332 Bind(&GetFileInfoHelper::Reply, Owned(helper), callback)); 362 Bind(&GetFileInfoHelper::Reply, Owned(helper), callback));
333 } 363 }
334 364
335 // static 365 // static
336 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, 366 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy,
337 const FilePath& file_path, 367 const FilePath& file_path,
338 bool recursive, 368 bool recursive,
339 const StatusCallback& callback) { 369 const StatusCallback& callback) {
340 return PostTaskAndReplyWithStatus<PlatformFileError>( 370 return RelayFileTask(
341 message_loop_proxy, FROM_HERE, 371 message_loop_proxy, FROM_HERE,
342 Bind(&DeleteHelper, file_path, recursive), callback, 372 Bind(&DeleteAdapter, file_path, recursive),
343 new PlatformFileError); 373 callback);
344 } 374 }
345 375
346 // static 376 // static
347 bool FileUtilProxy::RecursiveDelete( 377 bool FileUtilProxy::RecursiveDelete(
348 scoped_refptr<MessageLoopProxy> message_loop_proxy, 378 scoped_refptr<MessageLoopProxy> message_loop_proxy,
349 const FilePath& file_path, 379 const FilePath& file_path,
350 const StatusCallback& callback) { 380 const StatusCallback& callback) {
351 return PostTaskAndReplyWithStatus<PlatformFileError>( 381 return RelayFileTask(
352 message_loop_proxy, FROM_HERE, 382 message_loop_proxy, FROM_HERE,
353 Bind(&DeleteHelper, file_path, true /* recursive */), callback, 383 Bind(&DeleteAdapter, file_path, true /* recursive */),
354 new PlatformFileError); 384 callback);
355 } 385 }
356 386
357 // static 387 // static
358 bool FileUtilProxy::Read( 388 bool FileUtilProxy::Read(
359 scoped_refptr<MessageLoopProxy> message_loop_proxy, 389 scoped_refptr<MessageLoopProxy> message_loop_proxy,
360 PlatformFile file, 390 PlatformFile file,
361 int64 offset, 391 int64 offset,
362 int bytes_to_read, 392 int bytes_to_read,
363 const ReadCallback& callback) { 393 const ReadCallback& callback) {
364 if (bytes_to_read < 0) { 394 if (bytes_to_read < 0) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 bool FileUtilProxy::Flush( 464 bool FileUtilProxy::Flush(
435 scoped_refptr<MessageLoopProxy> message_loop_proxy, 465 scoped_refptr<MessageLoopProxy> message_loop_proxy,
436 PlatformFile file, 466 PlatformFile file,
437 const StatusCallback& callback) { 467 const StatusCallback& callback) {
438 return PostTaskAndReplyWithStatus<bool>( 468 return PostTaskAndReplyWithStatus<bool>(
439 message_loop_proxy, FROM_HERE, 469 message_loop_proxy, FROM_HERE,
440 Bind(&FlushPlatformFile, file), callback, 470 Bind(&FlushPlatformFile, file), callback,
441 new PlatformFileError); 471 new PlatformFileError);
442 } 472 }
443 473
474 // static
475 bool FileUtilProxy::RelayFileTask(
476 scoped_refptr<MessageLoopProxy> message_loop_proxy,
477 const tracked_objects::Location& from_here,
478 const FileTask& file_task,
479 const StatusCallback& callback) {
480 PlatformFileError* result = new PlatformFileError;
481 return message_loop_proxy->PostTaskAndReply(
482 from_here,
483 ReturnAsParam(file_task, result),
484 ReplyHelper(callback, Owned(result)));
485 }
486
487 // static
488 bool FileUtilProxy::RelayCreateOrOpen(
489 scoped_refptr<MessageLoopProxy> message_loop_proxy,
490 const CreateOrOpenTask& open_task,
491 const CloseTask& close_task,
492 const CreateOrOpenCallback& callback) {
493 CreateOrOpenHelper* helper = new CreateOrOpenHelper(
494 message_loop_proxy, close_task);
495 return message_loop_proxy->PostTaskAndReply(
496 FROM_HERE,
497 Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), open_task),
498 Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback));
499 }
500
501 // static
502 bool FileUtilProxy::RelayClose(
503 scoped_refptr<MessageLoopProxy> message_loop_proxy,
504 const CloseTask& close_task,
505 PlatformFile file_handle,
506 const StatusCallback& callback) {
507 PlatformFileError* result = new PlatformFileError;
508 return message_loop_proxy->PostTaskAndReply(
509 FROM_HERE,
510 ReturnAsParam(close_task, file_handle, result),
511 ReplyHelper(callback, Owned(result)));
512 }
513
444 } // namespace base 514 } // namespace base
OLDNEW
« no previous file with comments | « base/file_util_proxy.h ('k') | webkit/fileapi/file_system_file_util_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698