Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "webkit/fileapi/file_system_file_util_proxy.h" | |
| 6 | |
| 7 #include "base/message_loop_proxy.h" | |
| 8 #include "webkit/fileapi/file_system_context.h" | |
| 9 #include "webkit/fileapi/file_system_file_util.h" | |
| 10 #include "webkit/fileapi/file_system_operation_context.h" | |
| 11 | |
| 12 namespace { | |
| 13 | |
| 14 class MessageLoopRelay | |
| 15 : public base::RefCountedThreadSafe<MessageLoopRelay> { | |
| 16 public: | |
| 17 explicit MessageLoopRelay(fileapi::FileSystemOperationContext* context) | |
| 18 : origin_message_loop_proxy_( | |
| 19 base::MessageLoopProxy::CreateForCurrentThread()), | |
| 20 error_code_(base::PLATFORM_FILE_OK), | |
| 21 context_(context), | |
| 22 file_system_file_util_(context->file_system_file_util()) { | |
| 23 } | |
| 24 | |
| 25 bool Start(scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | |
| 26 const tracked_objects::Location& from_here) { | |
| 27 return message_loop_proxy->PostTask( | |
| 28 from_here, | |
| 29 NewRunnableMethod(this, &MessageLoopRelay::ProcessOnTargetThread)); | |
| 30 } | |
| 31 | |
| 32 protected: | |
| 33 friend class base::RefCountedThreadSafe<MessageLoopRelay>; | |
| 34 virtual ~MessageLoopRelay() {} | |
| 35 | |
| 36 // Called to perform work on the FILE thread. | |
| 37 virtual void RunWork() = 0; | |
| 38 | |
| 39 // Called to notify the callback on the origin thread. | |
| 40 virtual void RunCallback() = 0; | |
| 41 | |
| 42 void set_error_code(base::PlatformFileError error_code) { | |
| 43 error_code_ = error_code; | |
| 44 } | |
| 45 | |
| 46 base::PlatformFileError error_code() const { | |
| 47 return error_code_; | |
| 48 } | |
| 49 | |
| 50 fileapi::FileSystemOperationContext* context() { | |
| 51 return context_; | |
| 52 } | |
| 53 | |
| 54 fileapi::FileSystemFileUtil* file_system_file_util() const { | |
| 55 return file_system_file_util_; | |
|
ericu
2011/03/03 21:27:48
Why store it separately? Why not just return cont
Dai Mikurube (google.com)
2011/03/03 22:19:10
It causes Segmentation Fault. I, actually, didn't
ericu
2011/03/03 23:13:22
Ah, it's because the FileSystemOperationContext ca
| |
| 56 } | |
| 57 | |
| 58 private: | |
| 59 void ProcessOnTargetThread() { | |
| 60 RunWork(); | |
| 61 origin_message_loop_proxy_->PostTask( | |
| 62 FROM_HERE, | |
| 63 NewRunnableMethod(this, &MessageLoopRelay::RunCallback)); | |
| 64 } | |
| 65 | |
| 66 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; | |
| 67 base::PlatformFileError error_code_; | |
| 68 fileapi::FileSystemOperationContext* context_; | |
| 69 fileapi::FileSystemFileUtil* file_system_file_util_; | |
| 70 }; | |
| 71 | |
| 72 class RelayCreateOrOpen : public MessageLoopRelay { | |
| 73 public: | |
| 74 RelayCreateOrOpen( | |
| 75 fileapi::FileSystemOperationContext* context, | |
| 76 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | |
| 77 const FilePath& file_path, | |
| 78 int file_flags, | |
| 79 fileapi::FileSystemFileUtilProxy::CreateOrOpenCallback* callback) | |
| 80 : MessageLoopRelay(context), | |
| 81 message_loop_proxy_(message_loop_proxy), | |
| 82 file_path_(file_path), | |
| 83 file_flags_(file_flags), | |
| 84 callback_(callback), | |
| 85 file_handle_(base::kInvalidPlatformFileValue), | |
| 86 created_(false) { | |
| 87 DCHECK(callback); | |
| 88 } | |
| 89 | |
| 90 protected: | |
| 91 virtual ~RelayCreateOrOpen() { | |
| 92 if (file_handle_ != base::kInvalidPlatformFileValue) | |
| 93 fileapi::FileSystemFileUtilProxy::Close(context(), | |
| 94 message_loop_proxy_, file_handle_, NULL); | |
| 95 } | |
| 96 | |
| 97 virtual void RunWork() { | |
| 98 set_error_code( | |
| 99 file_system_file_util()->CreateOrOpen( | |
| 100 context(), file_path_, file_flags_, &file_handle_, &created_)); | |
| 101 } | |
| 102 | |
| 103 virtual void RunCallback() { | |
| 104 callback_->Run(error_code(), base::PassPlatformFile(&file_handle_), | |
| 105 created_); | |
| 106 delete callback_; | |
| 107 } | |
| 108 | |
| 109 private: | |
| 110 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | |
| 111 FilePath file_path_; | |
| 112 int file_flags_; | |
| 113 fileapi::FileSystemFileUtilProxy::CreateOrOpenCallback* callback_; | |
| 114 base::PlatformFile file_handle_; | |
| 115 bool created_; | |
| 116 }; | |
| 117 | |
| 118 class RelayWithStatusCallback : public MessageLoopRelay { | |
| 119 public: | |
| 120 RelayWithStatusCallback( | |
| 121 fileapi::FileSystemOperationContext* context, | |
| 122 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 123 : MessageLoopRelay(context), | |
| 124 callback_(callback) { | |
| 125 // It is OK for callback to be NULL. | |
| 126 } | |
| 127 | |
| 128 protected: | |
| 129 virtual void RunCallback() { | |
| 130 // The caller may not have been interested in the result. | |
| 131 if (callback_) { | |
| 132 callback_->Run(error_code()); | |
| 133 delete callback_; | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 private: | |
| 138 fileapi::FileSystemFileUtilProxy::StatusCallback* callback_; | |
| 139 }; | |
| 140 | |
| 141 class RelayClose : public RelayWithStatusCallback { | |
| 142 public: | |
| 143 RelayClose(fileapi::FileSystemOperationContext* context, | |
| 144 base::PlatformFile file_handle, | |
| 145 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 146 : RelayWithStatusCallback(context, callback), | |
| 147 file_handle_(file_handle) { | |
| 148 } | |
| 149 | |
| 150 protected: | |
| 151 virtual void RunWork() { | |
| 152 set_error_code( | |
| 153 file_system_file_util()->Close(context(), file_handle_)); | |
| 154 } | |
| 155 | |
| 156 private: | |
| 157 base::PlatformFile file_handle_; | |
| 158 }; | |
| 159 | |
| 160 class RelayEnsureFileExists : public MessageLoopRelay { | |
| 161 public: | |
| 162 RelayEnsureFileExists( | |
| 163 fileapi::FileSystemOperationContext* context, | |
| 164 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | |
| 165 const FilePath& file_path, | |
| 166 fileapi::FileSystemFileUtilProxy::EnsureFileExistsCallback* callback) | |
| 167 : MessageLoopRelay(context), | |
| 168 message_loop_proxy_(message_loop_proxy), | |
| 169 file_path_(file_path), | |
| 170 callback_(callback), | |
| 171 created_(false) { | |
| 172 DCHECK(callback); | |
| 173 } | |
| 174 | |
| 175 protected: | |
| 176 virtual void RunWork() { | |
| 177 set_error_code( | |
| 178 file_system_file_util()->EnsureFileExists( | |
| 179 context(), file_path_, &created_)); | |
| 180 } | |
| 181 | |
| 182 virtual void RunCallback() { | |
| 183 callback_->Run(error_code(), created_); | |
| 184 delete callback_; | |
| 185 } | |
| 186 | |
| 187 private: | |
| 188 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | |
| 189 FilePath file_path_; | |
| 190 fileapi::FileSystemFileUtilProxy::EnsureFileExistsCallback* callback_; | |
| 191 bool created_; | |
| 192 }; | |
| 193 | |
| 194 class RelayGetFileInfo : public MessageLoopRelay { | |
| 195 public: | |
| 196 RelayGetFileInfo( | |
| 197 fileapi::FileSystemOperationContext* context, | |
| 198 const FilePath& file_path, | |
| 199 fileapi::FileSystemFileUtilProxy::GetFileInfoCallback* callback) | |
| 200 : MessageLoopRelay(context), | |
| 201 callback_(callback), | |
| 202 file_path_(file_path) { | |
| 203 DCHECK(callback); | |
| 204 } | |
| 205 | |
| 206 protected: | |
| 207 virtual void RunWork() { | |
| 208 set_error_code( | |
| 209 file_system_file_util()->GetFileInfo( | |
| 210 context(), file_path_, &file_info_)); | |
| 211 } | |
| 212 | |
| 213 virtual void RunCallback() { | |
| 214 callback_->Run(error_code(), file_info_); | |
| 215 delete callback_; | |
| 216 } | |
| 217 | |
| 218 private: | |
| 219 fileapi::FileSystemFileUtilProxy::GetFileInfoCallback* callback_; | |
| 220 FilePath file_path_; | |
| 221 base::PlatformFileInfo file_info_; | |
| 222 }; | |
| 223 | |
| 224 class RelayReadDirectory : public MessageLoopRelay { | |
| 225 public: | |
| 226 RelayReadDirectory( | |
| 227 fileapi::FileSystemOperationContext* context, | |
| 228 const FilePath& file_path, | |
| 229 fileapi::FileSystemFileUtilProxy::ReadDirectoryCallback* callback) | |
| 230 : MessageLoopRelay(context), | |
| 231 callback_(callback), file_path_(file_path) { | |
| 232 DCHECK(callback); | |
| 233 } | |
| 234 | |
| 235 protected: | |
| 236 virtual void RunWork() { | |
| 237 // TODO(kkanetkar): Implement directory read in multiple chunks. | |
| 238 set_error_code( | |
| 239 file_system_file_util()->ReadDirectory( | |
| 240 context(), file_path_, &entries_)); | |
| 241 } | |
| 242 | |
| 243 virtual void RunCallback() { | |
| 244 callback_->Run(error_code(), entries_); | |
| 245 delete callback_; | |
| 246 } | |
| 247 | |
| 248 private: | |
| 249 fileapi::FileSystemFileUtilProxy::ReadDirectoryCallback* callback_; | |
| 250 FilePath file_path_; | |
| 251 std::vector<base::FileUtilProxy::Entry> entries_; | |
| 252 }; | |
| 253 | |
| 254 class RelayCreateDirectory : public RelayWithStatusCallback { | |
| 255 public: | |
| 256 RelayCreateDirectory( | |
| 257 fileapi::FileSystemOperationContext* context, | |
| 258 const FilePath& file_path, | |
| 259 bool exclusive, | |
| 260 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 261 : RelayWithStatusCallback(context, callback), | |
| 262 file_path_(file_path), | |
| 263 exclusive_(exclusive) { | |
| 264 } | |
| 265 | |
| 266 protected: | |
| 267 virtual void RunWork() { | |
| 268 set_error_code( | |
| 269 file_system_file_util()->CreateDirectory( | |
| 270 context(), file_path_, exclusive_)); | |
| 271 } | |
| 272 | |
| 273 private: | |
| 274 FilePath file_path_; | |
| 275 bool exclusive_; | |
| 276 }; | |
| 277 | |
| 278 class RelayCopy : public RelayWithStatusCallback { | |
| 279 public: | |
| 280 RelayCopy(fileapi::FileSystemOperationContext* context, | |
| 281 const FilePath& src_file_path, | |
| 282 const FilePath& dest_file_path, | |
| 283 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 284 : RelayWithStatusCallback(context, callback), | |
| 285 src_file_path_(src_file_path), | |
| 286 dest_file_path_(dest_file_path) { | |
| 287 } | |
| 288 | |
| 289 protected: | |
| 290 virtual void RunWork() { | |
| 291 set_error_code( | |
| 292 file_system_file_util()->Copy( | |
| 293 context(), src_file_path_, dest_file_path_)); | |
| 294 } | |
| 295 | |
| 296 private: | |
| 297 FilePath src_file_path_; | |
| 298 FilePath dest_file_path_; | |
| 299 }; | |
| 300 | |
| 301 class RelayMove : public RelayWithStatusCallback { | |
| 302 public: | |
| 303 RelayMove(fileapi::FileSystemOperationContext* context, | |
| 304 const FilePath& src_file_path, | |
| 305 const FilePath& dest_file_path, | |
| 306 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 307 : RelayWithStatusCallback(context, callback), | |
| 308 src_file_path_(src_file_path), | |
| 309 dest_file_path_(dest_file_path) { | |
| 310 } | |
| 311 | |
| 312 protected: | |
| 313 virtual void RunWork() { | |
| 314 set_error_code( | |
| 315 file_system_file_util()->Move( | |
| 316 context(), src_file_path_, dest_file_path_)); | |
| 317 } | |
| 318 | |
| 319 private: | |
| 320 FilePath src_file_path_; | |
| 321 FilePath dest_file_path_; | |
| 322 }; | |
| 323 | |
| 324 class RelayDelete : public RelayWithStatusCallback { | |
| 325 public: | |
| 326 RelayDelete(fileapi::FileSystemOperationContext* context, | |
| 327 const FilePath& file_path, | |
| 328 bool recursive, | |
| 329 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 330 : RelayWithStatusCallback(context, callback), | |
| 331 file_path_(file_path), | |
| 332 recursive_(recursive) { | |
| 333 } | |
| 334 | |
| 335 protected: | |
| 336 virtual void RunWork() { | |
| 337 set_error_code( | |
| 338 file_system_file_util()->Delete( | |
| 339 context(), file_path_, recursive_)); | |
| 340 } | |
| 341 | |
| 342 private: | |
| 343 FilePath file_path_; | |
| 344 bool recursive_; | |
| 345 }; | |
| 346 | |
| 347 class RelayTouchFilePath : public RelayWithStatusCallback { | |
| 348 public: | |
| 349 RelayTouchFilePath(fileapi::FileSystemOperationContext* context, | |
| 350 const FilePath& file_path, | |
| 351 const base::Time& last_access_time, | |
| 352 const base::Time& last_modified_time, | |
| 353 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 354 : RelayWithStatusCallback(context, callback), | |
| 355 file_path_(file_path), | |
| 356 last_access_time_(last_access_time), | |
| 357 last_modified_time_(last_modified_time) { | |
| 358 } | |
| 359 | |
| 360 protected: | |
| 361 virtual void RunWork() { | |
| 362 set_error_code( | |
| 363 file_system_file_util()->Touch( | |
| 364 context(), file_path_, last_access_time_, last_modified_time_)); | |
| 365 } | |
| 366 | |
| 367 private: | |
| 368 FilePath file_path_; | |
| 369 base::Time last_access_time_; | |
| 370 base::Time last_modified_time_; | |
| 371 }; | |
| 372 | |
| 373 class RelayTruncate : public RelayWithStatusCallback { | |
| 374 public: | |
| 375 RelayTruncate(fileapi::FileSystemOperationContext* context, | |
| 376 const FilePath& file_path, | |
| 377 int64 length, | |
| 378 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 379 : RelayWithStatusCallback(context, callback), | |
| 380 file_path_(file_path), | |
| 381 length_(length) { | |
| 382 } | |
| 383 | |
| 384 protected: | |
| 385 virtual void RunWork() { | |
| 386 set_error_code( | |
| 387 file_system_file_util()->Truncate(context(), file_path_, length_)); | |
| 388 } | |
| 389 | |
| 390 private: | |
| 391 FilePath file_path_; | |
| 392 int64 length_; | |
| 393 }; | |
| 394 | |
| 395 bool Start(const tracked_objects::Location& from_here, | |
| 396 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | |
| 397 scoped_refptr<MessageLoopRelay> relay) { | |
| 398 return relay->Start(message_loop_proxy, from_here); | |
| 399 } | |
| 400 | |
| 401 } // namespace | |
| 402 | |
| 403 namespace fileapi { | |
| 404 | |
| 405 // static | |
| 406 bool FileSystemFileUtilProxy::CreateOrOpen( | |
| 407 FileSystemOperationContext* context, | |
| 408 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 409 const FilePath& file_path, int file_flags, | |
| 410 CreateOrOpenCallback* callback) { | |
| 411 return Start(FROM_HERE, message_loop_proxy, new RelayCreateOrOpen(context, | |
| 412 message_loop_proxy, file_path, file_flags, callback)); | |
| 413 } | |
| 414 | |
| 415 // static | |
| 416 bool FileSystemFileUtilProxy::Close( | |
| 417 FileSystemOperationContext* context, | |
| 418 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 419 base::PlatformFile file_handle, | |
| 420 StatusCallback* callback) { | |
| 421 return Start(FROM_HERE, message_loop_proxy, | |
| 422 new RelayClose(context, file_handle, callback)); | |
| 423 } | |
| 424 | |
| 425 // static | |
| 426 bool FileSystemFileUtilProxy::EnsureFileExists( | |
| 427 FileSystemOperationContext* context, | |
| 428 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 429 const FilePath& file_path, | |
| 430 EnsureFileExistsCallback* callback) { | |
| 431 return Start(FROM_HERE, message_loop_proxy, new RelayEnsureFileExists( | |
| 432 context, message_loop_proxy, file_path, callback)); | |
| 433 } | |
| 434 | |
| 435 // Retrieves the information about a file. It is invalid to pass NULL for the | |
| 436 // callback. | |
| 437 bool FileSystemFileUtilProxy::GetFileInfo( | |
| 438 FileSystemOperationContext* context, | |
| 439 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 440 const FilePath& file_path, | |
| 441 GetFileInfoCallback* callback) { | |
| 442 return Start(FROM_HERE, message_loop_proxy, new RelayGetFileInfo(context, | |
| 443 file_path, callback)); | |
| 444 } | |
| 445 | |
| 446 // static | |
| 447 bool FileSystemFileUtilProxy::ReadDirectory( | |
| 448 FileSystemOperationContext* context, | |
| 449 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 450 const FilePath& file_path, | |
| 451 ReadDirectoryCallback* callback) { | |
| 452 return Start(FROM_HERE, message_loop_proxy, new RelayReadDirectory(context, | |
| 453 file_path, callback)); | |
| 454 } | |
| 455 | |
| 456 // static | |
| 457 bool FileSystemFileUtilProxy::CreateDirectory( | |
| 458 FileSystemOperationContext* context, | |
| 459 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 460 const FilePath& file_path, | |
| 461 bool exclusive, | |
| 462 StatusCallback* callback) { | |
| 463 return Start(FROM_HERE, message_loop_proxy, new RelayCreateDirectory( | |
| 464 context, file_path, exclusive, callback)); | |
| 465 } | |
| 466 | |
| 467 // static | |
| 468 bool FileSystemFileUtilProxy::Copy( | |
| 469 FileSystemOperationContext* context, | |
| 470 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 471 const FilePath& src_file_path, | |
| 472 const FilePath& dest_file_path, | |
| 473 StatusCallback* callback) { | |
| 474 return Start(FROM_HERE, message_loop_proxy, | |
| 475 new RelayCopy(context, src_file_path, dest_file_path, | |
| 476 callback)); | |
| 477 } | |
| 478 | |
| 479 // static | |
| 480 bool FileSystemFileUtilProxy::Move( | |
| 481 FileSystemOperationContext* context, | |
| 482 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 483 const FilePath& src_file_path, | |
| 484 const FilePath& dest_file_path, | |
| 485 StatusCallback* callback) { | |
| 486 return Start(FROM_HERE, message_loop_proxy, | |
| 487 new RelayMove(context, src_file_path, dest_file_path, | |
| 488 callback)); | |
| 489 } | |
| 490 | |
| 491 // static | |
| 492 bool FileSystemFileUtilProxy::Delete( | |
| 493 FileSystemOperationContext* context, | |
| 494 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 495 const FilePath& file_path, | |
| 496 bool recursive, | |
| 497 StatusCallback* callback) { | |
| 498 return Start(FROM_HERE, message_loop_proxy, | |
| 499 new RelayDelete(context, file_path, recursive, callback)); | |
| 500 } | |
| 501 | |
| 502 // static | |
| 503 bool FileSystemFileUtilProxy::Touch( | |
| 504 FileSystemOperationContext* context, | |
| 505 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 506 const FilePath& file_path, | |
| 507 const base::Time& last_access_time, | |
| 508 const base::Time& last_modified_time, | |
| 509 StatusCallback* callback) { | |
| 510 return Start(FROM_HERE, message_loop_proxy, | |
| 511 new RelayTouchFilePath(context, file_path, last_access_time, | |
| 512 last_modified_time, callback)); | |
| 513 } | |
| 514 | |
| 515 // static | |
| 516 bool FileSystemFileUtilProxy::Truncate( | |
| 517 FileSystemOperationContext* context, | |
| 518 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 519 const FilePath& path, | |
| 520 int64 length, | |
| 521 StatusCallback* callback) { | |
| 522 return Start(FROM_HERE, message_loop_proxy, | |
| 523 new RelayTruncate(context, path, length, callback)); | |
| 524 } | |
| 525 | |
| 526 } // namespace fileapi | |
| OLD | NEW |