| OLD | NEW | 
|---|
| 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 #include "base/task_runner_util.h" | 
| 11 | 12 | 
| 12 namespace base { | 13 namespace base { | 
| 13 | 14 | 
| 14 namespace { | 15 namespace { | 
| 15 | 16 | 
| 16 // Helper templates to call file_util or base::PlatformFile methods | 17 void CallWithTranslatedParameter(const FileUtilProxy::StatusCallback& callback, | 
| 17 // and reply with the returned value. | 18                                  bool value) { | 
| 18 // | 19   DCHECK(!callback.is_null()); | 
| 19 // Typically when you have these methods: | 20   callback.Run(value ? PLATFORM_FILE_OK : PLATFORM_FILE_ERROR_FAILED); | 
| 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 //      RelayHelper(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, 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 |  | 
| 75 template <typename R> |  | 
| 76 void ReplyAdapter(const Callback<void(R)>& callback, R* result) { |  | 
| 77   DCHECK(result); |  | 
| 78   if (!callback.is_null()) |  | 
| 79     callback.Run(*result); |  | 
| 80 } |  | 
| 81 |  | 
| 82 template <typename R, typename OWNED> |  | 
| 83 Closure ReplyHelper(const Callback<void(R)>& callback, OWNED result) { |  | 
| 84   return Bind(&ReplyAdapter<R>, callback, result); |  | 
| 85 } |  | 
| 86 |  | 
| 87 // Putting everything together. |  | 
| 88 template <typename R1, typename R2> |  | 
| 89 bool PostTaskAndReplyWithStatus( |  | 
| 90     const scoped_refptr<MessageLoopProxy>& message_loop_proxy, |  | 
| 91     const tracked_objects::Location& from_here, |  | 
| 92     const Callback<R1(void)>& file_util_work, |  | 
| 93     const Callback<void(R2)>& callback, |  | 
| 94     R2* result) { |  | 
| 95   return message_loop_proxy->PostTaskAndReply( |  | 
| 96       from_here, |  | 
| 97       ReturnAsParam<R1>(file_util_work, result), |  | 
| 98       ReplyHelper(callback, Owned(result))); |  | 
| 99 } | 21 } | 
| 100 | 22 | 
| 101 // Helper classes or routines for individual methods. | 23 // Helper classes or routines for individual methods. | 
| 102 class CreateOrOpenHelper { | 24 class CreateOrOpenHelper { | 
| 103  public: | 25  public: | 
| 104   CreateOrOpenHelper(MessageLoopProxy* message_loop_proxy, | 26   CreateOrOpenHelper(MessageLoopProxy* message_loop_proxy, | 
| 105                      const FileUtilProxy::CloseTask& close_task) | 27                      const FileUtilProxy::CloseTask& close_task) | 
| 106       : message_loop_proxy_(message_loop_proxy), | 28       : message_loop_proxy_(message_loop_proxy), | 
| 107         close_task_(close_task), | 29         close_task_(close_task), | 
| 108         file_handle_(kInvalidPlatformFileValue), | 30         file_handle_(kInvalidPlatformFileValue), | 
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 312       callback); | 234       callback); | 
| 313 } | 235 } | 
| 314 | 236 | 
| 315 // static | 237 // static | 
| 316 bool FileUtilProxy::CreateTemporary( | 238 bool FileUtilProxy::CreateTemporary( | 
| 317     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 239     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 318     int additional_file_flags, | 240     int additional_file_flags, | 
| 319     const CreateTemporaryCallback& callback) { | 241     const CreateTemporaryCallback& callback) { | 
| 320   CreateTemporaryHelper* helper = new CreateTemporaryHelper(message_loop_proxy); | 242   CreateTemporaryHelper* helper = new CreateTemporaryHelper(message_loop_proxy); | 
| 321   return message_loop_proxy->PostTaskAndReply( | 243   return message_loop_proxy->PostTaskAndReply( | 
| 322         FROM_HERE, | 244       FROM_HERE, | 
| 323         Bind(&CreateTemporaryHelper::RunWork, Unretained(helper), | 245       Bind(&CreateTemporaryHelper::RunWork, Unretained(helper), | 
| 324              additional_file_flags), | 246            additional_file_flags), | 
| 325         Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback)); | 247       Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback)); | 
| 326 } | 248 } | 
| 327 | 249 | 
| 328 // static | 250 // static | 
| 329 bool FileUtilProxy::Close( | 251 bool FileUtilProxy::Close( | 
| 330     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 252     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 331     base::PlatformFile file_handle, | 253     base::PlatformFile file_handle, | 
| 332     const StatusCallback& callback) { | 254     const StatusCallback& callback) { | 
| 333   return RelayClose( | 255   return RelayClose( | 
| 334       message_loop_proxy, | 256       message_loop_proxy, | 
| 335       base::Bind(&CloseAdapter), | 257       base::Bind(&CloseAdapter), | 
| 336       file_handle, callback); | 258       file_handle, callback); | 
| 337 } | 259 } | 
| 338 | 260 | 
| 339 // Retrieves the information about a file. It is invalid to pass NULL for the | 261 // Retrieves the information about a file. It is invalid to pass NULL for the | 
| 340 // callback. | 262 // callback. | 
| 341 bool FileUtilProxy::GetFileInfo( | 263 bool FileUtilProxy::GetFileInfo( | 
| 342     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 264     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 343     const FilePath& file_path, | 265     const FilePath& file_path, | 
| 344     const GetFileInfoCallback& callback) { | 266     const GetFileInfoCallback& callback) { | 
| 345   GetFileInfoHelper* helper = new GetFileInfoHelper; | 267   GetFileInfoHelper* helper = new GetFileInfoHelper; | 
| 346   return message_loop_proxy->PostTaskAndReply( | 268   return message_loop_proxy->PostTaskAndReply( | 
| 347         FROM_HERE, | 269       FROM_HERE, | 
| 348         Bind(&GetFileInfoHelper::RunWorkForFilePath, | 270       Bind(&GetFileInfoHelper::RunWorkForFilePath, | 
| 349              Unretained(helper), file_path), | 271            Unretained(helper), file_path), | 
| 350         Bind(&GetFileInfoHelper::Reply, Owned(helper), callback)); | 272       Bind(&GetFileInfoHelper::Reply, Owned(helper), callback)); | 
| 351 } | 273 } | 
| 352 | 274 | 
| 353 // static | 275 // static | 
| 354 bool FileUtilProxy::GetFileInfoFromPlatformFile( | 276 bool FileUtilProxy::GetFileInfoFromPlatformFile( | 
| 355     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 277     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 356     PlatformFile file, | 278     PlatformFile file, | 
| 357     const GetFileInfoCallback& callback) { | 279     const GetFileInfoCallback& callback) { | 
| 358   GetFileInfoHelper* helper = new GetFileInfoHelper; | 280   GetFileInfoHelper* helper = new GetFileInfoHelper; | 
| 359   return message_loop_proxy->PostTaskAndReply( | 281   return message_loop_proxy->PostTaskAndReply( | 
| 360         FROM_HERE, | 282       FROM_HERE, | 
| 361         Bind(&GetFileInfoHelper::RunWorkForPlatformFile, | 283       Bind(&GetFileInfoHelper::RunWorkForPlatformFile, | 
| 362              Unretained(helper), file), | 284            Unretained(helper), file), | 
| 363         Bind(&GetFileInfoHelper::Reply, Owned(helper), callback)); | 285       Bind(&GetFileInfoHelper::Reply, Owned(helper), callback)); | 
| 364 } | 286 } | 
| 365 | 287 | 
| 366 // static | 288 // static | 
| 367 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, | 289 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 368                            const FilePath& file_path, | 290                            const FilePath& file_path, | 
| 369                            bool recursive, | 291                            bool recursive, | 
| 370                            const StatusCallback& callback) { | 292                            const StatusCallback& callback) { | 
| 371   return RelayFileTask( | 293   return RelayFileTask( | 
| 372       message_loop_proxy, FROM_HERE, | 294       message_loop_proxy, FROM_HERE, | 
| 373       Bind(&DeleteAdapter, file_path, recursive), | 295       Bind(&DeleteAdapter, file_path, recursive), | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 390     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 312     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 391     PlatformFile file, | 313     PlatformFile file, | 
| 392     int64 offset, | 314     int64 offset, | 
| 393     int bytes_to_read, | 315     int bytes_to_read, | 
| 394     const ReadCallback& callback) { | 316     const ReadCallback& callback) { | 
| 395   if (bytes_to_read < 0) { | 317   if (bytes_to_read < 0) { | 
| 396     return false; | 318     return false; | 
| 397   } | 319   } | 
| 398   ReadHelper* helper = new ReadHelper(bytes_to_read); | 320   ReadHelper* helper = new ReadHelper(bytes_to_read); | 
| 399   return message_loop_proxy->PostTaskAndReply( | 321   return message_loop_proxy->PostTaskAndReply( | 
| 400         FROM_HERE, | 322       FROM_HERE, | 
| 401         Bind(&ReadHelper::RunWork, Unretained(helper), file, offset), | 323       Bind(&ReadHelper::RunWork, Unretained(helper), file, offset), | 
| 402         Bind(&ReadHelper::Reply, Owned(helper), callback)); | 324       Bind(&ReadHelper::Reply, Owned(helper), callback)); | 
| 403 } | 325 } | 
| 404 | 326 | 
| 405 // static | 327 // static | 
| 406 bool FileUtilProxy::Write( | 328 bool FileUtilProxy::Write( | 
| 407     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 329     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 408     PlatformFile file, | 330     PlatformFile file, | 
| 409     int64 offset, | 331     int64 offset, | 
| 410     const char* buffer, | 332     const char* buffer, | 
| 411     int bytes_to_write, | 333     int bytes_to_write, | 
| 412     const WriteCallback& callback) { | 334     const WriteCallback& callback) { | 
| 413   if (bytes_to_write <= 0 || buffer == NULL) { | 335   if (bytes_to_write <= 0 || buffer == NULL) { | 
| 414     return false; | 336     return false; | 
| 415   } | 337   } | 
| 416   WriteHelper* helper = new WriteHelper(buffer, bytes_to_write); | 338   WriteHelper* helper = new WriteHelper(buffer, bytes_to_write); | 
| 417   return message_loop_proxy->PostTaskAndReply( | 339   return message_loop_proxy->PostTaskAndReply( | 
| 418         FROM_HERE, | 340       FROM_HERE, | 
| 419         Bind(&WriteHelper::RunWork, Unretained(helper), file, offset), | 341       Bind(&WriteHelper::RunWork, Unretained(helper), file, offset), | 
| 420         Bind(&WriteHelper::Reply, Owned(helper), callback)); | 342       Bind(&WriteHelper::Reply, Owned(helper), callback)); | 
| 421 } | 343 } | 
| 422 | 344 | 
| 423 // static | 345 // static | 
| 424 bool FileUtilProxy::Touch( | 346 bool FileUtilProxy::Touch( | 
| 425     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 347     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 426     PlatformFile file, | 348     PlatformFile file, | 
| 427     const Time& last_access_time, | 349     const Time& last_access_time, | 
| 428     const Time& last_modified_time, | 350     const Time& last_modified_time, | 
| 429     const StatusCallback& callback) { | 351     const StatusCallback& callback) { | 
| 430   return PostTaskAndReplyWithStatus<bool>( | 352   return base::PostTaskAndReplyWithResult( | 
| 431       message_loop_proxy, FROM_HERE, | 353       message_loop_proxy, | 
|  | 354       FROM_HERE, | 
| 432       Bind(&TouchPlatformFile, file, | 355       Bind(&TouchPlatformFile, file, | 
| 433            last_access_time, last_modified_time), callback, | 356            last_access_time, last_modified_time), | 
| 434       new PlatformFileError); | 357       Bind(&CallWithTranslatedParameter, callback)); | 
| 435 } | 358 } | 
| 436 | 359 | 
| 437 // static | 360 // static | 
| 438 bool FileUtilProxy::Touch( | 361 bool FileUtilProxy::Touch( | 
| 439     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 362     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 440     const FilePath& file_path, | 363     const FilePath& file_path, | 
| 441     const Time& last_access_time, | 364     const Time& last_access_time, | 
| 442     const Time& last_modified_time, | 365     const Time& last_modified_time, | 
| 443     const StatusCallback& callback) { | 366     const StatusCallback& callback) { | 
| 444   return PostTaskAndReplyWithStatus<bool>( | 367   return base::PostTaskAndReplyWithResult( | 
| 445       message_loop_proxy, FROM_HERE, | 368       message_loop_proxy, | 
|  | 369       FROM_HERE, | 
| 446       Bind(&file_util::TouchFile, file_path, | 370       Bind(&file_util::TouchFile, file_path, | 
| 447            last_access_time, last_modified_time), | 371            last_access_time, last_modified_time), | 
| 448       callback, | 372       Bind(&CallWithTranslatedParameter, callback)); | 
| 449       new PlatformFileError); |  | 
| 450 } | 373 } | 
| 451 | 374 | 
| 452 // static | 375 // static | 
| 453 bool FileUtilProxy::Truncate( | 376 bool FileUtilProxy::Truncate( | 
| 454     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 377     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 455     PlatformFile file, | 378     PlatformFile file, | 
| 456     int64 length, | 379     int64 length, | 
| 457     const StatusCallback& callback) { | 380     const StatusCallback& callback) { | 
| 458   return PostTaskAndReplyWithStatus<bool>( | 381   return base::PostTaskAndReplyWithResult( | 
| 459       message_loop_proxy, FROM_HERE, | 382       message_loop_proxy, | 
| 460       Bind(&TruncatePlatformFile, file, length), callback, | 383       FROM_HERE, | 
| 461       new PlatformFileError); | 384       Bind(&TruncatePlatformFile, file, length), | 
|  | 385       Bind(&CallWithTranslatedParameter, callback)); | 
| 462 } | 386 } | 
| 463 | 387 | 
| 464 // static | 388 // static | 
| 465 bool FileUtilProxy::Flush( | 389 bool FileUtilProxy::Flush( | 
| 466     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 390     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 467     PlatformFile file, | 391     PlatformFile file, | 
| 468     const StatusCallback& callback) { | 392     const StatusCallback& callback) { | 
| 469   return PostTaskAndReplyWithStatus<bool>( | 393   return base::PostTaskAndReplyWithResult( | 
| 470       message_loop_proxy, FROM_HERE, | 394       message_loop_proxy, | 
| 471       Bind(&FlushPlatformFile, file), callback, | 395       FROM_HERE, | 
| 472       new PlatformFileError); | 396       Bind(&FlushPlatformFile, file), | 
|  | 397       Bind(&CallWithTranslatedParameter, callback)); | 
| 473 } | 398 } | 
| 474 | 399 | 
| 475 // static | 400 // static | 
| 476 bool FileUtilProxy::RelayFileTask( | 401 bool FileUtilProxy::RelayFileTask( | 
| 477     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 402     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 478     const tracked_objects::Location& from_here, | 403     const tracked_objects::Location& from_here, | 
| 479     const FileTask& file_task, | 404     const FileTask& file_task, | 
| 480     const StatusCallback& callback) { | 405     const StatusCallback& callback) { | 
| 481   PlatformFileError* result = new PlatformFileError; | 406   return base::PostTaskAndReplyWithResult( | 
| 482   return message_loop_proxy->PostTaskAndReply( | 407       message_loop_proxy, from_here, file_task, callback); | 
| 483       from_here, |  | 
| 484       ReturnAsParam(file_task, result), |  | 
| 485       ReplyHelper(callback, Owned(result))); |  | 
| 486 } | 408 } | 
| 487 | 409 | 
| 488 // static | 410 // static | 
| 489 bool FileUtilProxy::RelayCreateOrOpen( | 411 bool FileUtilProxy::RelayCreateOrOpen( | 
| 490     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 412     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 491     const CreateOrOpenTask& open_task, | 413     const CreateOrOpenTask& open_task, | 
| 492     const CloseTask& close_task, | 414     const CloseTask& close_task, | 
| 493     const CreateOrOpenCallback& callback) { | 415     const CreateOrOpenCallback& callback) { | 
| 494   CreateOrOpenHelper* helper = new CreateOrOpenHelper( | 416   CreateOrOpenHelper* helper = new CreateOrOpenHelper( | 
| 495       message_loop_proxy, close_task); | 417       message_loop_proxy, close_task); | 
| 496   return message_loop_proxy->PostTaskAndReply( | 418   return message_loop_proxy->PostTaskAndReply( | 
| 497         FROM_HERE, | 419       FROM_HERE, | 
| 498         Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), open_task), | 420       Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), open_task), | 
| 499         Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback)); | 421       Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback)); | 
| 500 } | 422 } | 
| 501 | 423 | 
| 502 // static | 424 // static | 
| 503 bool FileUtilProxy::RelayClose( | 425 bool FileUtilProxy::RelayClose( | 
| 504     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 426     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
| 505     const CloseTask& close_task, | 427     const CloseTask& close_task, | 
| 506     PlatformFile file_handle, | 428     PlatformFile file_handle, | 
| 507     const StatusCallback& callback) { | 429     const StatusCallback& callback) { | 
| 508   PlatformFileError* result = new PlatformFileError; | 430   return base::PostTaskAndReplyWithResult( | 
| 509   return message_loop_proxy->PostTaskAndReply( | 431       message_loop_proxy, FROM_HERE, Bind(close_task, file_handle), callback); | 
| 510       FROM_HERE, |  | 
| 511       ReturnAsParam(close_task, file_handle, result), |  | 
| 512       ReplyHelper(callback, Owned(result))); |  | 
| 513 } | 432 } | 
| 514 | 433 | 
| 515 }  // namespace base | 434 }  // namespace base | 
| OLD | NEW | 
|---|