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

Side by Side Diff: base/file_util_proxy.cc

Issue 8424006: Bind: Merge FileUtilProxy and FileSystemFileUtilProxy: CreateOrOpen/Close (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: '' 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
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 FileUtilProxy::RelayClose(message_loop_proxy_,
101 FileUtilProxy::StatusCallback()); 115 close_task_, file_handle_,
116 FileUtilProxy::StatusCallback());
willchan no longer on Chromium 2011/11/01 22:57:37 Why do we use FileUtilProxy here? Shouldn't we jus
kinuko 2011/11/02 05:48:22 Good point... I think simple PostTask will be enou
102 } 117 }
103 } 118 }
104 119
105 void RunWork(const FilePath& file_path, int file_flags) { 120 void RunWork(const FileUtilProxy::CreateOrOpenTask& task) {
106 if (!file_util::DirectoryExists(file_path.DirName())) { 121 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 } 122 }
115 123
116 void Reply(const FileUtilProxy::CreateOrOpenCallback& callback) { 124 void Reply(const FileUtilProxy::CreateOrOpenCallback& callback) {
117 DCHECK(!callback.is_null()); 125 DCHECK(!callback.is_null());
118 callback.Run(error_, PassPlatformFile(&file_handle_), created_); 126 callback.Run(error_, PassPlatformFile(&file_handle_), created_);
119 } 127 }
120 128
121 private: 129 private:
122 scoped_refptr<MessageLoopProxy> message_loop_proxy_; 130 scoped_refptr<MessageLoopProxy> message_loop_proxy_;
131 FileUtilProxy::CloseTask close_task_;
123 PlatformFile file_handle_; 132 PlatformFile file_handle_;
124 bool created_; 133 bool created_;
125 PlatformFileError error_; 134 PlatformFileError error_;
126 DISALLOW_COPY_AND_ASSIGN(CreateOrOpenHelper); 135 DISALLOW_COPY_AND_ASSIGN(CreateOrOpenHelper);
127 }; 136 };
128 137
129 class CreateTemporaryHelper { 138 class CreateTemporaryHelper {
130 public: 139 public:
131 CreateTemporaryHelper(MessageLoopProxy* message_loop_proxy) 140 CreateTemporaryHelper(MessageLoopProxy* message_loop_proxy)
132 : message_loop_proxy_(message_loop_proxy), 141 : message_loop_proxy_(message_loop_proxy),
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 } 269 }
261 } 270 }
262 271
263 private: 272 private:
264 scoped_array<char> buffer_; 273 scoped_array<char> buffer_;
265 int bytes_to_write_; 274 int bytes_to_write_;
266 int bytes_written_; 275 int bytes_written_;
267 DISALLOW_COPY_AND_ASSIGN(WriteHelper); 276 DISALLOW_COPY_AND_ASSIGN(WriteHelper);
268 }; 277 };
269 278
279
280 PlatformFileError CreateOrOpenAdapter(
281 const FilePath& file_path, int file_flags,
282 PlatformFile* file_handle, bool* created) {
283 DCHECK(file_handle);
284 DCHECK(created);
285 if (!file_util::DirectoryExists(file_path.DirName())) {
286 // If its parent does not exist, should return NOT_FOUND error.
287 return PLATFORM_FILE_ERROR_NOT_FOUND;
288 }
289 PlatformFileError error = PLATFORM_FILE_OK;
290 *file_handle = CreatePlatformFile(file_path, file_flags, created, &error);
291 return error;
292 }
293
294 PlatformFileError CloseAdapter(PlatformFile file_handle) {
295 if (!ClosePlatformFile(file_handle)) {
296 return PLATFORM_FILE_ERROR_FAILED;
297 }
298 return PLATFORM_FILE_OK;
299 }
300
270 } // namespace 301 } // namespace
271 302
272 // static 303 // static
273 bool FileUtilProxy::CreateOrOpen( 304 bool FileUtilProxy::CreateOrOpen(
274 scoped_refptr<MessageLoopProxy> message_loop_proxy, 305 scoped_refptr<MessageLoopProxy> message_loop_proxy,
275 const FilePath& file_path, int file_flags, 306 const FilePath& file_path, int file_flags,
276 const CreateOrOpenCallback& callback) { 307 const CreateOrOpenCallback& callback) {
277 CreateOrOpenHelper* helper = new CreateOrOpenHelper(message_loop_proxy); 308 return RelayCreateOrOpen(
278 return message_loop_proxy->PostTaskAndReply( 309 message_loop_proxy,
279 FROM_HERE, 310 base::Bind(&CreateOrOpenAdapter, file_path, file_flags),
280 Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), 311 base::Bind(&CloseAdapter),
281 file_path, file_flags), 312 callback);
282 Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback));
283 } 313 }
284 314
285 // static 315 // static
286 bool FileUtilProxy::CreateTemporary( 316 bool FileUtilProxy::CreateTemporary(
287 scoped_refptr<MessageLoopProxy> message_loop_proxy, 317 scoped_refptr<MessageLoopProxy> message_loop_proxy,
288 int additional_file_flags, 318 int additional_file_flags,
289 const CreateTemporaryCallback& callback) { 319 const CreateTemporaryCallback& callback) {
290 CreateTemporaryHelper* helper = new CreateTemporaryHelper(message_loop_proxy); 320 CreateTemporaryHelper* helper = new CreateTemporaryHelper(message_loop_proxy);
291 return message_loop_proxy->PostTaskAndReply( 321 return message_loop_proxy->PostTaskAndReply(
292 FROM_HERE, 322 FROM_HERE,
293 Bind(&CreateTemporaryHelper::RunWork, Unretained(helper), 323 Bind(&CreateTemporaryHelper::RunWork, Unretained(helper),
294 additional_file_flags), 324 additional_file_flags),
295 Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback)); 325 Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback));
296 } 326 }
297 327
298 // static 328 // static
299 bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy, 329 bool FileUtilProxy::Close(
300 PlatformFile file_handle, 330 scoped_refptr<MessageLoopProxy> message_loop_proxy,
301 const StatusCallback& callback) { 331 base::PlatformFile file_handle,
302 return PostTaskAndReplyWithStatus<bool>( 332 const StatusCallback& callback) {
303 message_loop_proxy, FROM_HERE, 333 return RelayClose(
304 Bind(&ClosePlatformFile, file_handle), callback, 334 message_loop_proxy,
305 new PlatformFileError); 335 base::Bind(&CloseAdapter),
336 file_handle, callback);
306 } 337 }
307 338
308 // Retrieves the information about a file. It is invalid to pass NULL for the 339 // Retrieves the information about a file. It is invalid to pass NULL for the
309 // callback. 340 // callback.
310 bool FileUtilProxy::GetFileInfo( 341 bool FileUtilProxy::GetFileInfo(
311 scoped_refptr<MessageLoopProxy> message_loop_proxy, 342 scoped_refptr<MessageLoopProxy> message_loop_proxy,
312 const FilePath& file_path, 343 const FilePath& file_path,
313 const GetFileInfoCallback& callback) { 344 const GetFileInfoCallback& callback) {
314 GetFileInfoHelper* helper = new GetFileInfoHelper; 345 GetFileInfoHelper* helper = new GetFileInfoHelper;
315 return message_loop_proxy->PostTaskAndReply( 346 return message_loop_proxy->PostTaskAndReply(
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 bool FileUtilProxy::Flush( 465 bool FileUtilProxy::Flush(
435 scoped_refptr<MessageLoopProxy> message_loop_proxy, 466 scoped_refptr<MessageLoopProxy> message_loop_proxy,
436 PlatformFile file, 467 PlatformFile file,
437 const StatusCallback& callback) { 468 const StatusCallback& callback) {
438 return PostTaskAndReplyWithStatus<bool>( 469 return PostTaskAndReplyWithStatus<bool>(
439 message_loop_proxy, FROM_HERE, 470 message_loop_proxy, FROM_HERE,
440 Bind(&FlushPlatformFile, file), callback, 471 Bind(&FlushPlatformFile, file), callback,
441 new PlatformFileError); 472 new PlatformFileError);
442 } 473 }
443 474
475 // static
476 bool FileUtilProxy::RelayCreateOrOpen(
477 scoped_refptr<MessageLoopProxy> message_loop_proxy,
478 const CreateOrOpenTask& open_task,
479 const CloseTask& close_task,
480 const CreateOrOpenCallback& callback) {
481 CreateOrOpenHelper* helper = new CreateOrOpenHelper(
482 message_loop_proxy, close_task);
483 return message_loop_proxy->PostTaskAndReply(
484 FROM_HERE,
485 Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), open_task),
486 Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback));
487 }
488
489 // static
490 bool FileUtilProxy::RelayClose(
491 scoped_refptr<MessageLoopProxy> message_loop_proxy,
492 const CloseTask& close_task,
493 PlatformFile file_handle,
494 const StatusCallback& callback) {
495 PlatformFileError* result = new PlatformFileError;
496 return message_loop_proxy->PostTaskAndReply(
497 FROM_HERE,
498 ReturnAsParam(close_task, file_handle, result),
499 ReplyHelper(callback, Owned(result)));
500 }
501
444 } // namespace base 502 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698