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

Side by Side Diff: base/file_util_proxy.cc

Issue 8339012: Reimplementing FileUtilProxy using PostTaskAndReply (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: updated with Owned 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
« no previous file with comments | « no previous file | no next file » | 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"
9 #include "base/file_util.h"
8 #include "base/message_loop_proxy.h" 10 #include "base/message_loop_proxy.h"
9 11
10 namespace base { 12 namespace base {
11 13
12 namespace { 14 namespace {
13 15
14 class MessageLoopRelay 16 // Helper templates to call file_util or base::PlatformFile methods
15 : public RefCountedThreadSafe<MessageLoopRelay> { 17 // and reply with the returned value.
18 //
19 // Typically when you have these methods:
20 // R DoWorkAndReturn();
21 // void Callback(R& result);
22 //
23 // You can pass the result of DoWorkAndReturn to the Callback by:
24 //
25 // R* result = new R;
26 // message_loop_proxy->PostTaskAndReply(
27 // from_here,
28 // ReturnAsParam<R>(Bind(&DoWorkAndReturn), result),
29 // CallbackWithReturn(Bind(&Callback), Owned(result)));
30 //
31 // Or just use PostTaskAndReplyWithStatus helper template (see the code below).
32 template <typename R1, typename R2>
33 struct ReturnValueTranslator {
34 static R2 Value(const R1& value);
35 };
36
37 template <typename R>
38 struct ReturnValueTranslator<R, R> {
39 static R Value(const R& value) { return value; }
40 };
41
42 template <>
43 struct ReturnValueTranslator<bool, PlatformFileError> {
44 static PlatformFileError Value(const bool& value) {
45 if (value)
46 return PLATFORM_FILE_OK;
47 return PLATFORM_FILE_ERROR_FAILED;
48 }
49 };
50
51 template <typename R1, typename R2>
52 void ReturnAsParamAdapter(const Callback<R1(void)>& func, R2* result) {
53 if (!func.is_null())
54 *result = ReturnValueTranslator<R1, R2>::Value(func.Run());
55 }
56
57 template <typename R1, typename R2>
58 Closure ReturnAsParam(const Callback<R1(void)>& func, R2* result) {
59 DCHECK(result);
60 return Bind(&ReturnAsParamAdapter<R1, R2>, func, result);
61 }
62
63 template <typename R>
64 void ReplyAdapter(const Callback<void(R)>& callback, R* result) {
65 DCHECK(result);
66 if (!callback.is_null())
67 callback.Run(*result);
68 }
69
70 template <typename R, typename OWNED>
71 Closure ReplyHelper(const Callback<void(R)>& callback, OWNED result) {
72 return Bind(&ReplyAdapter<R>, callback, result);
73 }
74
75 // Putting everything together.
76 template <typename R1, typename R2>
77 bool PostTaskAndReplyWithStatus(
78 scoped_refptr<MessageLoopProxy> message_loop_proxy,
willchan no longer on Chromium 2011/10/21 17:56:51 Can you use const scoped_refptr<MessageLoopProxy>&
kinuko 2011/10/24 10:14:17 Done.
79 const tracked_objects::Location& from_here,
80 const Callback<R1(void)>& file_util_work,
81 const Callback<void(R2)>& callback,
82 R2* result) {
83 return message_loop_proxy->PostTaskAndReply(
84 from_here,
85 ReturnAsParam<R1>(file_util_work, result),
86 ReplyHelper(callback, Owned(result)));
87 }
88
89 // Helper classes or routines for individual methods.
90 class CreateOrOpenHelper {
16 public: 91 public:
17 MessageLoopRelay() 92 CreateOrOpenHelper(MessageLoopProxy* message_loop_proxy)
18 : origin_message_loop_proxy_( 93 : message_loop_proxy_(message_loop_proxy),
19 MessageLoopProxy::current()), 94 file_handle_(kInvalidPlatformFileValue),
20 error_code_(PLATFORM_FILE_OK) { 95 created_(false),
96 error_(PLATFORM_FILE_OK) {}
97
98 ~CreateOrOpenHelper() {
99 if (file_handle_ != kInvalidPlatformFileValue) {
100 FileUtilProxy::Close(message_loop_proxy_, file_handle_,
101 FileUtilProxy::StatusCallback());
102 }
21 } 103 }
22 104
23 bool Start(scoped_refptr<MessageLoopProxy> message_loop_proxy, 105 void RunWork(const FilePath& file_path, int file_flags) {
24 const tracked_objects::Location& from_here) { 106 if (!file_util::DirectoryExists(file_path.DirName())) {
25 return message_loop_proxy->PostTask( 107 // If its parent does not exist, should return NOT_FOUND error.
26 from_here, Bind(&MessageLoopRelay::ProcessOnTargetThread, this)); 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_);
27 } 114 }
28 115
29 protected: 116 void Reply(const FileUtilProxy::CreateOrOpenCallback& callback) {
30 friend class RefCountedThreadSafe<MessageLoopRelay>; 117 DCHECK(!callback.is_null());
31 virtual ~MessageLoopRelay() {} 118 callback.Run(error_, PassPlatformFile(&file_handle_), created_);
32
33 // Called to perform work on the FILE thread.
34 virtual void RunWork() = 0;
35
36 // Called to notify the callback on the origin thread.
37 virtual void RunCallback() = 0;
38
39 void set_error_code(PlatformFileError error_code) {
40 error_code_ = error_code;
41 }
42
43 PlatformFileError error_code() const {
44 return error_code_;
45 }
46
47 private:
48 void ProcessOnTargetThread() {
49 RunWork();
50 origin_message_loop_proxy_->PostTask(
51 FROM_HERE, Bind(&MessageLoopRelay::RunCallback, this));
52 }
53
54 scoped_refptr<MessageLoopProxy> origin_message_loop_proxy_;
55 PlatformFileError error_code_;
56 };
57
58 class RelayCreateOrOpen : public MessageLoopRelay {
59 public:
60 RelayCreateOrOpen(
61 scoped_refptr<MessageLoopProxy> message_loop_proxy,
62 const FilePath& file_path,
63 int file_flags,
64 const FileUtilProxy::CreateOrOpenCallback& callback)
65 : message_loop_proxy_(message_loop_proxy),
66 file_path_(file_path),
67 file_flags_(file_flags),
68 callback_(callback),
69 file_handle_(kInvalidPlatformFileValue),
70 created_(false) {
71 DCHECK_EQ(false, callback.is_null());
72 }
73
74 protected:
75 virtual ~RelayCreateOrOpen() {
76 if (file_handle_ != kInvalidPlatformFileValue)
77 FileUtilProxy::Close(message_loop_proxy_, file_handle_,
78 FileUtilProxy::StatusCallback());
79 }
80
81 virtual void RunWork() {
82 if (!file_util::DirectoryExists(file_path_.DirName())) {
83 // If its parent does not exist, should return NOT_FOUND error.
84 set_error_code(PLATFORM_FILE_ERROR_NOT_FOUND);
85 return;
86 }
87 PlatformFileError error_code = PLATFORM_FILE_OK;
88 file_handle_ = CreatePlatformFile(file_path_, file_flags_,
89 &created_, &error_code);
90 set_error_code(error_code);
91 }
92
93 virtual void RunCallback() {
94 callback_.Run(error_code(), PassPlatformFile(&file_handle_),
95 created_);
96 } 119 }
97 120
98 private: 121 private:
99 scoped_refptr<MessageLoopProxy> message_loop_proxy_; 122 scoped_refptr<MessageLoopProxy> message_loop_proxy_;
100 FilePath file_path_;
101 int file_flags_;
102 FileUtilProxy::CreateOrOpenCallback callback_;
103 PlatformFile file_handle_; 123 PlatformFile file_handle_;
104 bool created_; 124 bool created_;
125 PlatformFileError error_;
126 DISALLOW_COPY_AND_ASSIGN(CreateOrOpenHelper);
105 }; 127 };
106 128
107 class RelayCreateTemporary : public MessageLoopRelay { 129 class CreateTemporaryHelper {
108 public: 130 public:
109 RelayCreateTemporary( 131 CreateTemporaryHelper(MessageLoopProxy* message_loop_proxy)
110 scoped_refptr<MessageLoopProxy> message_loop_proxy,
111 int additional_file_flags,
112 const FileUtilProxy::CreateTemporaryCallback& callback)
113 : message_loop_proxy_(message_loop_proxy), 132 : message_loop_proxy_(message_loop_proxy),
114 additional_file_flags_(additional_file_flags), 133 file_handle_(kInvalidPlatformFileValue),
115 callback_(callback), 134 error_(PLATFORM_FILE_OK) {}
116 file_handle_(kInvalidPlatformFileValue) { 135
117 DCHECK_EQ(false, callback.is_null()); 136 ~CreateTemporaryHelper() {
137 if (file_handle_ != kInvalidPlatformFileValue) {
138 FileUtilProxy::Close(message_loop_proxy_, file_handle_,
139 FileUtilProxy::StatusCallback());
140 }
118 } 141 }
119 142
120 protected: 143 void RunWork(int additional_file_flags) {
121 virtual ~RelayCreateTemporary() {
122 if (file_handle_ != kInvalidPlatformFileValue)
123 FileUtilProxy::Close(message_loop_proxy_, file_handle_,
124 FileUtilProxy::StatusCallback());
125 }
126
127 virtual void RunWork() {
128 // TODO(darin): file_util should have a variant of CreateTemporaryFile 144 // TODO(darin): file_util should have a variant of CreateTemporaryFile
129 // that returns a FilePath and a PlatformFile. 145 // that returns a FilePath and a PlatformFile.
130 file_util::CreateTemporaryFile(&file_path_); 146 file_util::CreateTemporaryFile(&file_path_);
131 147
132 int file_flags = 148 int file_flags =
133 PLATFORM_FILE_WRITE | 149 PLATFORM_FILE_WRITE |
134 PLATFORM_FILE_TEMPORARY | 150 PLATFORM_FILE_TEMPORARY |
135 PLATFORM_FILE_CREATE_ALWAYS | 151 PLATFORM_FILE_CREATE_ALWAYS |
136 additional_file_flags_; 152 additional_file_flags;
137 153
138 PlatformFileError error_code = PLATFORM_FILE_OK; 154 error_ = PLATFORM_FILE_OK;
139 file_handle_ = CreatePlatformFile(file_path_, file_flags, 155 file_handle_ = CreatePlatformFile(file_path_, file_flags, NULL, &error_);
140 NULL, &error_code);
141 set_error_code(error_code);
142 } 156 }
143 157
144 virtual void RunCallback() { 158 void Reply(const FileUtilProxy::CreateTemporaryCallback& callback) {
145 callback_.Run(error_code(), PassPlatformFile(&file_handle_), 159 DCHECK(!callback.is_null());
146 file_path_); 160 callback.Run(error_, PassPlatformFile(&file_handle_), file_path_);
147 } 161 }
148 162
149 private: 163 private:
150 scoped_refptr<MessageLoopProxy> message_loop_proxy_; 164 scoped_refptr<MessageLoopProxy> message_loop_proxy_;
151 int additional_file_flags_;
152 FileUtilProxy::CreateTemporaryCallback callback_;
153 PlatformFile file_handle_; 165 PlatformFile file_handle_;
154 FilePath file_path_; 166 FilePath file_path_;
167 PlatformFileError error_;
168 DISALLOW_COPY_AND_ASSIGN(CreateTemporaryHelper);
155 }; 169 };
156 170
157 class RelayWithStatusCallback : public MessageLoopRelay { 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 {
158 public: 185 public:
159 explicit RelayWithStatusCallback( 186 GetFileInfoHelper()
160 const FileUtilProxy::StatusCallback& callback) 187 : error_(PLATFORM_FILE_OK) {}
161 : callback_(callback) { 188
162 // It is OK for callback to be NULL. 189 void RunWorkForFilePath(const FilePath& file_path) {
190 if (!file_util::PathExists(file_path)) {
191 error_ = PLATFORM_FILE_ERROR_NOT_FOUND;
192 return;
193 }
194 if (!file_util::GetFileInfo(file_path, &file_info_))
195 error_ = PLATFORM_FILE_ERROR_FAILED;
163 } 196 }
164 197
165 protected: 198 void RunWorkForPlatformFile(PlatformFile file) {
166 virtual void RunCallback() { 199 if (!GetPlatformFileInfo(file, &file_info_))
167 // The caller may not have been interested in the result. 200 error_ = PLATFORM_FILE_ERROR_FAILED;
168 if (!callback_.is_null())
169 callback_.Run(error_code());
170 } 201 }
171 202
172 private: 203 void Reply(const FileUtilProxy::GetFileInfoCallback& callback) {
173 FileUtilProxy::StatusCallback callback_; 204 if (!callback.is_null()) {
174 }; 205 callback.Run(error_, file_info_);
175
176 class RelayClose : public RelayWithStatusCallback {
177 public:
178 RelayClose(PlatformFile file_handle,
179 const FileUtilProxy::StatusCallback& callback)
180 : RelayWithStatusCallback(callback),
181 file_handle_(file_handle) {
182 }
183
184 protected:
185 virtual void RunWork() {
186 if (!ClosePlatformFile(file_handle_))
187 set_error_code(PLATFORM_FILE_ERROR_FAILED);
188 }
189
190 private:
191 PlatformFile file_handle_;
192 };
193
194 class RelayDelete : public RelayWithStatusCallback {
195 public:
196 RelayDelete(const FilePath& file_path,
197 bool recursive,
198 const FileUtilProxy::StatusCallback& callback)
199 : RelayWithStatusCallback(callback),
200 file_path_(file_path),
201 recursive_(recursive) {
202 }
203
204 protected:
205 virtual void RunWork() {
206 if (!file_util::PathExists(file_path_)) {
207 set_error_code(PLATFORM_FILE_ERROR_NOT_FOUND);
208 return;
209 }
210 if (!file_util::Delete(file_path_, recursive_)) {
211 if (!recursive_ && !file_util::IsDirectoryEmpty(file_path_)) {
212 set_error_code(PLATFORM_FILE_ERROR_NOT_EMPTY);
213 return;
214 }
215 set_error_code(PLATFORM_FILE_ERROR_FAILED);
216 } 206 }
217 } 207 }
218 208
219 private: 209 private:
220 FilePath file_path_; 210 PlatformFileError error_;
221 bool recursive_; 211 PlatformFileInfo file_info_;
212 DISALLOW_COPY_AND_ASSIGN(GetFileInfoHelper);
222 }; 213 };
223 214
224 class RelayGetFileInfo : public MessageLoopRelay { 215 class ReadHelper {
225 public: 216 public:
226 RelayGetFileInfo(const FilePath& file_path, 217 ReadHelper(int bytes_to_read)
227 const FileUtilProxy::GetFileInfoCallback& callback) 218 : buffer_(new char[bytes_to_read]),
228 : callback_(callback), 219 bytes_to_read_(bytes_to_read),
229 file_path_(file_path) { 220 bytes_read_(0) {}
230 DCHECK_EQ(false, callback.is_null()); 221
222 void RunWork(PlatformFile file, int64 offset) {
223 bytes_read_ = ReadPlatformFile(file, offset, buffer_.get(), bytes_to_read_);
231 } 224 }
232 225
233 protected: 226 void Reply(const FileUtilProxy::ReadCallback& callback) {
234 virtual void RunWork() { 227 if (!callback.is_null()) {
235 if (!file_util::PathExists(file_path_)) { 228 PlatformFileError error =
236 set_error_code(PLATFORM_FILE_ERROR_NOT_FOUND); 229 (bytes_read_ < 0) ? PLATFORM_FILE_ERROR_FAILED : PLATFORM_FILE_OK;
237 return; 230 callback.Run(error, buffer_.get(), bytes_read_);
238 } 231 }
239 if (!file_util::GetFileInfo(file_path_, &file_info_))
240 set_error_code(PLATFORM_FILE_ERROR_FAILED);
241 }
242
243 virtual void RunCallback() {
244 callback_.Run(error_code(), file_info_);
245 } 232 }
246 233
247 private: 234 private:
248 FileUtilProxy::GetFileInfoCallback callback_; 235 scoped_array<char> buffer_;
249 FilePath file_path_; 236 int bytes_to_read_;
250 PlatformFileInfo file_info_; 237 int bytes_read_;
238 DISALLOW_COPY_AND_ASSIGN(ReadHelper);
251 }; 239 };
252 240
253 class RelayGetFileInfoFromPlatformFile : public MessageLoopRelay { 241 class WriteHelper {
254 public: 242 public:
255 RelayGetFileInfoFromPlatformFile( 243 WriteHelper(const char* buffer, int bytes_to_write)
256 PlatformFile file, 244 : buffer_(new char[bytes_to_write]),
257 const FileUtilProxy::GetFileInfoCallback& callback)
258 : callback_(callback),
259 file_(file) {
260 DCHECK_EQ(false, callback.is_null());
261 }
262
263 protected:
264 virtual void RunWork() {
265 if (!GetPlatformFileInfo(file_, &file_info_))
266 set_error_code(PLATFORM_FILE_ERROR_FAILED);
267 }
268
269 virtual void RunCallback() {
270 callback_.Run(error_code(), file_info_);
271 }
272
273 private:
274 FileUtilProxy::GetFileInfoCallback callback_;
275 PlatformFile file_;
276 PlatformFileInfo file_info_;
277 };
278
279 class RelayRead : public MessageLoopRelay {
280 public:
281 RelayRead(PlatformFile file,
282 int64 offset,
283 int bytes_to_read,
284 const FileUtilProxy::ReadCallback& callback)
285 : file_(file),
286 offset_(offset),
287 buffer_(new char[bytes_to_read]),
288 bytes_to_read_(bytes_to_read),
289 callback_(callback),
290 bytes_read_(0) {
291 }
292
293 protected:
294 virtual void RunWork() {
295 bytes_read_ = ReadPlatformFile(file_, offset_, buffer_.get(),
296 bytes_to_read_);
297 if (bytes_read_ < 0)
298 set_error_code(PLATFORM_FILE_ERROR_FAILED);
299 }
300
301 virtual void RunCallback() {
302 if (!callback_.is_null())
303 callback_.Run(error_code(), buffer_.get(), bytes_read_);
304 }
305
306 private:
307 PlatformFile file_;
308 int64 offset_;
309 scoped_array<char> buffer_;
310 int bytes_to_read_;
311 FileUtilProxy::ReadCallback callback_;
312 int bytes_read_;
313 };
314
315 class RelayWrite : public MessageLoopRelay {
316 public:
317 RelayWrite(PlatformFile file,
318 int64 offset,
319 const char* buffer,
320 int bytes_to_write,
321 const FileUtilProxy::WriteCallback& callback)
322 : file_(file),
323 offset_(offset),
324 buffer_(new char[bytes_to_write]),
325 bytes_to_write_(bytes_to_write), 245 bytes_to_write_(bytes_to_write),
326 callback_(callback),
327 bytes_written_(0) { 246 bytes_written_(0) {
328 memcpy(buffer_.get(), buffer, bytes_to_write); 247 memcpy(buffer_.get(), buffer, bytes_to_write);
329 } 248 }
330 249
331 protected: 250 void RunWork(PlatformFile file, int64 offset) {
332 virtual void RunWork() { 251 bytes_written_ = WritePlatformFile(file, offset, buffer_.get(),
333 bytes_written_ = WritePlatformFile(file_, offset_, buffer_.get(), 252 bytes_to_write_);
334 bytes_to_write_);
335 if (bytes_written_ < 0)
336 set_error_code(PLATFORM_FILE_ERROR_FAILED);
337 } 253 }
338 254
339 virtual void RunCallback() { 255 void Reply(const FileUtilProxy::WriteCallback& callback) {
340 if (!callback_.is_null()) 256 if (!callback.is_null()) {
341 callback_.Run(error_code(), bytes_written_); 257 PlatformFileError error =
258 (bytes_written_ < 0) ? PLATFORM_FILE_ERROR_FAILED : PLATFORM_FILE_OK;
259 callback.Run(error, bytes_written_);
260 }
342 } 261 }
343 262
344 private: 263 private:
345 PlatformFile file_;
346 int64 offset_;
347 scoped_array<char> buffer_; 264 scoped_array<char> buffer_;
348 int bytes_to_write_; 265 int bytes_to_write_;
349 FileUtilProxy::WriteCallback callback_;
350 int bytes_written_; 266 int bytes_written_;
267 DISALLOW_COPY_AND_ASSIGN(WriteHelper);
351 }; 268 };
352 269
353 class RelayTouch : public RelayWithStatusCallback {
354 public:
355 RelayTouch(PlatformFile file,
356 const Time& last_access_time,
357 const Time& last_modified_time,
358 const FileUtilProxy::StatusCallback& callback)
359 : RelayWithStatusCallback(callback),
360 file_(file),
361 last_access_time_(last_access_time),
362 last_modified_time_(last_modified_time) {
363 }
364
365 protected:
366 virtual void RunWork() {
367 if (!TouchPlatformFile(file_, last_access_time_, last_modified_time_))
368 set_error_code(PLATFORM_FILE_ERROR_FAILED);
369 }
370
371 private:
372 PlatformFile file_;
373 Time last_access_time_;
374 Time last_modified_time_;
375 };
376
377 class RelayTouchFilePath : public RelayWithStatusCallback {
378 public:
379 RelayTouchFilePath(const FilePath& file_path,
380 const Time& last_access_time,
381 const Time& last_modified_time,
382 const FileUtilProxy::StatusCallback& callback)
383 : RelayWithStatusCallback(callback),
384 file_path_(file_path),
385 last_access_time_(last_access_time),
386 last_modified_time_(last_modified_time) {
387 }
388
389 protected:
390 virtual void RunWork() {
391 if (!file_util::TouchFile(
392 file_path_, last_access_time_, last_modified_time_))
393 set_error_code(PLATFORM_FILE_ERROR_FAILED);
394 }
395
396 private:
397 FilePath file_path_;
398 Time last_access_time_;
399 Time last_modified_time_;
400 };
401
402 class RelayTruncatePlatformFile : public RelayWithStatusCallback {
403 public:
404 RelayTruncatePlatformFile(PlatformFile file,
405 int64 length,
406 const FileUtilProxy::StatusCallback& callback)
407 : RelayWithStatusCallback(callback),
408 file_(file),
409 length_(length) {
410 }
411
412 protected:
413 virtual void RunWork() {
414 if (!TruncatePlatformFile(file_, length_))
415 set_error_code(PLATFORM_FILE_ERROR_FAILED);
416 }
417
418 private:
419 PlatformFile file_;
420 int64 length_;
421 };
422
423 class RelayTruncate : public RelayWithStatusCallback {
424 public:
425 RelayTruncate(const FilePath& path,
426 int64 length,
427 const FileUtilProxy::StatusCallback& callback)
428 : RelayWithStatusCallback(callback),
429 path_(path),
430 length_(length) {
431 }
432
433 protected:
434 virtual void RunWork() {
435 PlatformFileError error_code(PLATFORM_FILE_ERROR_FAILED);
436 PlatformFile file =
437 CreatePlatformFile(
438 path_,
439 PLATFORM_FILE_OPEN | PLATFORM_FILE_WRITE,
440 NULL,
441 &error_code);
442 if (error_code != PLATFORM_FILE_OK) {
443 set_error_code(error_code);
444 return;
445 }
446 if (!TruncatePlatformFile(file, length_))
447 set_error_code(PLATFORM_FILE_ERROR_FAILED);
448 ClosePlatformFile(file);
449 }
450
451 private:
452 FilePath path_;
453 int64 length_;
454 };
455
456 class RelayFlush : public RelayWithStatusCallback {
457 public:
458 RelayFlush(PlatformFile file,
459 const FileUtilProxy::StatusCallback& callback)
460 : RelayWithStatusCallback(callback),
461 file_(file) {
462 }
463
464 protected:
465 virtual void RunWork() {
466 if (!FlushPlatformFile(file_))
467 set_error_code(PLATFORM_FILE_ERROR_FAILED);
468 }
469
470 private:
471 PlatformFile file_;
472 };
473
474 bool Start(const tracked_objects::Location& from_here,
475 scoped_refptr<MessageLoopProxy> message_loop_proxy,
476 scoped_refptr<MessageLoopRelay> relay) {
477 return relay->Start(message_loop_proxy, from_here);
478 }
479
480 } // namespace 270 } // namespace
481 271
482 // static 272 // static
483 bool FileUtilProxy::CreateOrOpen( 273 bool FileUtilProxy::CreateOrOpen(
484 scoped_refptr<MessageLoopProxy> message_loop_proxy, 274 scoped_refptr<MessageLoopProxy> message_loop_proxy,
485 const FilePath& file_path, int file_flags, 275 const FilePath& file_path, int file_flags,
486 const CreateOrOpenCallback& callback) { 276 const CreateOrOpenCallback& callback) {
487 return Start(FROM_HERE, message_loop_proxy, new RelayCreateOrOpen( 277 CreateOrOpenHelper* helper = new CreateOrOpenHelper(message_loop_proxy);
488 message_loop_proxy, file_path, file_flags, callback)); 278 return message_loop_proxy->PostTaskAndReply(
279 FROM_HERE,
280 Bind(&CreateOrOpenHelper::RunWork, Unretained(helper),
281 file_path, file_flags),
282 Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback));
489 } 283 }
490 284
491 // static 285 // static
492 bool FileUtilProxy::CreateTemporary( 286 bool FileUtilProxy::CreateTemporary(
493 scoped_refptr<MessageLoopProxy> message_loop_proxy, 287 scoped_refptr<MessageLoopProxy> message_loop_proxy,
494 int additional_file_flags, 288 int additional_file_flags,
495 const CreateTemporaryCallback& callback) { 289 const CreateTemporaryCallback& callback) {
496 return Start(FROM_HERE, message_loop_proxy, 290 CreateTemporaryHelper* helper = new CreateTemporaryHelper(message_loop_proxy);
497 new RelayCreateTemporary(message_loop_proxy, 291 return message_loop_proxy->PostTaskAndReply(
498 additional_file_flags, 292 FROM_HERE,
499 callback)); 293 Bind(&CreateTemporaryHelper::RunWork, Unretained(helper),
294 additional_file_flags),
295 Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback));
500 } 296 }
501 297
502 // static 298 // static
503 bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy, 299 bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy,
504 PlatformFile file_handle, 300 PlatformFile file_handle,
505 const StatusCallback& callback) { 301 const StatusCallback& callback) {
506 return Start(FROM_HERE, message_loop_proxy, 302 return PostTaskAndReplyWithStatus<bool>(
507 new RelayClose(file_handle, callback)); 303 message_loop_proxy, FROM_HERE,
304 Bind(&ClosePlatformFile, file_handle), callback,
305 new PlatformFileError);
508 } 306 }
509 307
510 // Retrieves the information about a file. It is invalid to pass NULL for the 308 // Retrieves the information about a file. It is invalid to pass NULL for the
511 // callback. 309 // callback.
512 bool FileUtilProxy::GetFileInfo( 310 bool FileUtilProxy::GetFileInfo(
513 scoped_refptr<MessageLoopProxy> message_loop_proxy, 311 scoped_refptr<MessageLoopProxy> message_loop_proxy,
514 const FilePath& file_path, 312 const FilePath& file_path,
515 const GetFileInfoCallback& callback) { 313 const GetFileInfoCallback& callback) {
516 return Start(FROM_HERE, message_loop_proxy, new RelayGetFileInfo( 314 GetFileInfoHelper* helper = new GetFileInfoHelper;
517 file_path, callback)); 315 return message_loop_proxy->PostTaskAndReply(
316 FROM_HERE,
317 Bind(&GetFileInfoHelper::RunWorkForFilePath,
318 Unretained(helper), file_path),
319 Bind(&GetFileInfoHelper::Reply, Owned(helper), callback));
518 } 320 }
519 321
520 // static 322 // static
521 bool FileUtilProxy::GetFileInfoFromPlatformFile( 323 bool FileUtilProxy::GetFileInfoFromPlatformFile(
522 scoped_refptr<MessageLoopProxy> message_loop_proxy, 324 scoped_refptr<MessageLoopProxy> message_loop_proxy,
523 PlatformFile file, 325 PlatformFile file,
524 const GetFileInfoCallback& callback) { 326 const GetFileInfoCallback& callback) {
525 return Start(FROM_HERE, message_loop_proxy, 327 GetFileInfoHelper* helper = new GetFileInfoHelper;
526 new RelayGetFileInfoFromPlatformFile(file, callback)); 328 return message_loop_proxy->PostTaskAndReply(
329 FROM_HERE,
330 Bind(&GetFileInfoHelper::RunWorkForPlatformFile,
331 Unretained(helper), file),
332 Bind(&GetFileInfoHelper::Reply, Owned(helper), callback));
527 } 333 }
528 334
529 // static 335 // static
530 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, 336 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy,
531 const FilePath& file_path, 337 const FilePath& file_path,
532 bool recursive, 338 bool recursive,
533 const StatusCallback& callback) { 339 const StatusCallback& callback) {
534 return Start(FROM_HERE, message_loop_proxy, 340 return PostTaskAndReplyWithStatus<PlatformFileError>(
535 new RelayDelete(file_path, recursive, callback)); 341 message_loop_proxy, FROM_HERE,
342 Bind(&DeleteHelper, file_path, recursive), callback,
343 new PlatformFileError);
536 } 344 }
537 345
538 // static 346 // static
539 bool FileUtilProxy::RecursiveDelete( 347 bool FileUtilProxy::RecursiveDelete(
540 scoped_refptr<MessageLoopProxy> message_loop_proxy, 348 scoped_refptr<MessageLoopProxy> message_loop_proxy,
541 const FilePath& file_path, 349 const FilePath& file_path,
542 const StatusCallback& callback) { 350 const StatusCallback& callback) {
543 return Start(FROM_HERE, message_loop_proxy, 351 return PostTaskAndReplyWithStatus<PlatformFileError>(
544 new RelayDelete(file_path, true, callback)); 352 message_loop_proxy, FROM_HERE,
353 Bind(&DeleteHelper, file_path, true /* recursive */), callback,
354 new PlatformFileError);
545 } 355 }
546 356
547 // static 357 // static
548 bool FileUtilProxy::Read( 358 bool FileUtilProxy::Read(
549 scoped_refptr<MessageLoopProxy> message_loop_proxy, 359 scoped_refptr<MessageLoopProxy> message_loop_proxy,
550 PlatformFile file, 360 PlatformFile file,
551 int64 offset, 361 int64 offset,
552 int bytes_to_read, 362 int bytes_to_read,
553 const ReadCallback& callback) { 363 const ReadCallback& callback) {
554 if (bytes_to_read < 0) 364 if (bytes_to_read < 0) {
555 return false; 365 return false;
556 366 }
557 return Start(FROM_HERE, message_loop_proxy, 367 ReadHelper* helper = new ReadHelper(bytes_to_read);
558 new RelayRead(file, offset, bytes_to_read, callback)); 368 return message_loop_proxy->PostTaskAndReply(
369 FROM_HERE,
370 Bind(&ReadHelper::RunWork, Unretained(helper), file, offset),
371 Bind(&ReadHelper::Reply, Owned(helper), callback));
559 } 372 }
560 373
561 // static 374 // static
562 bool FileUtilProxy::Write( 375 bool FileUtilProxy::Write(
563 scoped_refptr<MessageLoopProxy> message_loop_proxy, 376 scoped_refptr<MessageLoopProxy> message_loop_proxy,
564 PlatformFile file, 377 PlatformFile file,
565 int64 offset, 378 int64 offset,
566 const char* buffer, 379 const char* buffer,
567 int bytes_to_write, 380 int bytes_to_write,
568 const WriteCallback& callback) { 381 const WriteCallback& callback) {
569 if (bytes_to_write <= 0) 382 if (bytes_to_write <= 0 || buffer == NULL) {
570 return false; 383 return false;
571 384 }
572 return Start(FROM_HERE, message_loop_proxy, 385 WriteHelper* helper = new WriteHelper(buffer, bytes_to_write);
573 new RelayWrite(file, offset, buffer, bytes_to_write, callback)); 386 return message_loop_proxy->PostTaskAndReply(
387 FROM_HERE,
388 Bind(&WriteHelper::RunWork, Unretained(helper), file, offset),
389 Bind(&WriteHelper::Reply, Owned(helper), callback));
574 } 390 }
575 391
576 // static 392 // static
577 bool FileUtilProxy::Touch( 393 bool FileUtilProxy::Touch(
578 scoped_refptr<MessageLoopProxy> message_loop_proxy, 394 scoped_refptr<MessageLoopProxy> message_loop_proxy,
579 PlatformFile file, 395 PlatformFile file,
580 const Time& last_access_time, 396 const Time& last_access_time,
581 const Time& last_modified_time, 397 const Time& last_modified_time,
582 const StatusCallback& callback) { 398 const StatusCallback& callback) {
583 return Start(FROM_HERE, message_loop_proxy, 399 return PostTaskAndReplyWithStatus<bool>(
584 new RelayTouch(file, last_access_time, last_modified_time, 400 message_loop_proxy, FROM_HERE,
585 callback)); 401 Bind(&TouchPlatformFile, file,
402 last_access_time, last_modified_time), callback,
403 new PlatformFileError);
586 } 404 }
587 405
588 // static 406 // static
589 bool FileUtilProxy::Touch( 407 bool FileUtilProxy::Touch(
590 scoped_refptr<MessageLoopProxy> message_loop_proxy, 408 scoped_refptr<MessageLoopProxy> message_loop_proxy,
591 const FilePath& file_path, 409 const FilePath& file_path,
592 const Time& last_access_time, 410 const Time& last_access_time,
593 const Time& last_modified_time, 411 const Time& last_modified_time,
594 const StatusCallback& callback) { 412 const StatusCallback& callback) {
595 return Start(FROM_HERE, message_loop_proxy, 413 return PostTaskAndReplyWithStatus<bool>(
596 new RelayTouchFilePath(file_path, last_access_time, 414 message_loop_proxy, FROM_HERE,
597 last_modified_time, callback)); 415 Bind(&file_util::TouchFile, file_path,
416 last_access_time, last_modified_time),
417 callback,
418 new PlatformFileError);
598 } 419 }
599 420
600 // static 421 // static
601 bool FileUtilProxy::Truncate( 422 bool FileUtilProxy::Truncate(
602 scoped_refptr<MessageLoopProxy> message_loop_proxy, 423 scoped_refptr<MessageLoopProxy> message_loop_proxy,
603 PlatformFile file, 424 PlatformFile file,
604 int64 length, 425 int64 length,
605 const StatusCallback& callback) { 426 const StatusCallback& callback) {
606 return Start(FROM_HERE, message_loop_proxy, 427 return PostTaskAndReplyWithStatus<bool>(
607 new RelayTruncatePlatformFile(file, length, callback)); 428 message_loop_proxy, FROM_HERE,
429 Bind(&TruncatePlatformFile, file, length), callback,
430 new PlatformFileError);
608 } 431 }
609 432
610 // static 433 // static
611 bool FileUtilProxy::Truncate(
612 scoped_refptr<MessageLoopProxy> message_loop_proxy,
613 const FilePath& path,
614 int64 length,
615 const StatusCallback& callback) {
616 return Start(FROM_HERE, message_loop_proxy,
617 new RelayTruncate(path, length, callback));
618 }
619
620 // static
621 bool FileUtilProxy::Flush( 434 bool FileUtilProxy::Flush(
622 scoped_refptr<MessageLoopProxy> message_loop_proxy, 435 scoped_refptr<MessageLoopProxy> message_loop_proxy,
623 PlatformFile file, 436 PlatformFile file,
624 const StatusCallback& callback) { 437 const StatusCallback& callback) {
625 return Start(FROM_HERE, message_loop_proxy, new RelayFlush(file, callback)); 438 return PostTaskAndReplyWithStatus<bool>(
439 message_loop_proxy, FROM_HERE,
440 Bind(&FlushPlatformFile, file), callback,
441 new PlatformFileError);
626 } 442 }
627 443
628 } // namespace base 444 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698