OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 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/file_util.h" | |
8 #include "base/message_loop_proxy.h" | 7 #include "base/message_loop_proxy.h" |
9 | 8 |
10 // TODO(jianli): Move the code from anonymous namespace to base namespace so | 9 // TODO(jianli): Move the code from anonymous namespace to base namespace so |
11 // that all of the base:: prefixes would be unnecessary. | 10 // that all of the base:: prefixes would be unnecessary. |
12 namespace { | 11 namespace { |
13 | 12 |
14 class MessageLoopRelay | 13 class MessageLoopRelay |
15 : public base::RefCountedThreadSafe<MessageLoopRelay> { | 14 : public base::RefCountedThreadSafe<MessageLoopRelay> { |
16 public: | 15 public: |
17 MessageLoopRelay() | 16 MessageLoopRelay() |
18 : origin_message_loop_proxy_( | 17 : origin_message_loop_proxy_( |
19 base::MessageLoopProxy::CreateForCurrentThread()), | 18 base::MessageLoopProxy::CreateForCurrentThread()), |
20 error_code_(base::PLATFORM_FILE_OK) { | 19 error_code_(base::PLATFORM_FILE_OK) { |
21 } | 20 } |
22 | 21 |
23 bool Start(scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | 22 bool Start(scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
24 const tracked_objects::Location& from_here) { | 23 const tracked_objects::Location& from_here) { |
25 return message_loop_proxy->PostTask( | 24 return message_loop_proxy->PostTask( |
26 from_here, | 25 from_here, |
27 NewRunnableMethod(this, &MessageLoopRelay::ProcessOnTargetThread)); | 26 NewRunnableMethod(this, &MessageLoopRelay::ProcessOnTargetThread)); |
28 } | 27 } |
29 | 28 |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 RelayDelete(const FilePath& file_path, | 192 RelayDelete(const FilePath& file_path, |
194 bool recursive, | 193 bool recursive, |
195 base::FileUtilProxy::StatusCallback* callback) | 194 base::FileUtilProxy::StatusCallback* callback) |
196 : RelayWithStatusCallback(callback), | 195 : RelayWithStatusCallback(callback), |
197 file_path_(file_path), | 196 file_path_(file_path), |
198 recursive_(recursive) { | 197 recursive_(recursive) { |
199 } | 198 } |
200 | 199 |
201 protected: | 200 protected: |
202 virtual void RunWork() { | 201 virtual void RunWork() { |
203 if (!file_util::Delete(file_path_, recursive_)) | 202 if (!file_util::PathExists(file_path_)) { |
| 203 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |
| 204 return; |
| 205 } |
| 206 if (!file_util::Delete(file_path_, recursive_)) { |
| 207 if (!recursive_ && !file_util::IsDirectoryEmpty(file_path_)) { |
| 208 set_error_code(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); |
| 209 return; |
| 210 } |
204 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | 211 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); |
| 212 } |
205 } | 213 } |
206 | 214 |
207 private: | 215 private: |
208 FilePath file_path_; | 216 FilePath file_path_; |
209 bool recursive_; | 217 bool recursive_; |
210 }; | 218 }; |
211 | 219 |
| 220 class RelayCopy : public RelayWithStatusCallback { |
| 221 public: |
| 222 RelayCopy(const FilePath& src_file_path, |
| 223 const FilePath& dest_file_path, |
| 224 base::FileUtilProxy::StatusCallback* callback) |
| 225 : RelayWithStatusCallback(callback), |
| 226 src_file_path_(src_file_path), |
| 227 dest_file_path_(dest_file_path) { |
| 228 } |
| 229 |
| 230 protected: |
| 231 virtual void RunWork() { |
| 232 bool dest_path_exists = file_util::PathExists(dest_file_path_); |
| 233 if (!dest_path_exists && |
| 234 !file_util::DirectoryExists(dest_file_path_.DirName())) { |
| 235 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |
| 236 return; |
| 237 } |
| 238 // |src_file_path| exists and is a directory. |
| 239 // |dest_file_path| exists and is a file. |
| 240 if (file_util::DirectoryExists(src_file_path_) && |
| 241 dest_path_exists && !file_util::DirectoryExists(dest_file_path_)) { |
| 242 set_error_code(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY); |
| 243 return; |
| 244 } |
| 245 if (file_util::ContainsPath(src_file_path_, dest_file_path_)) { |
| 246 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); |
| 247 return; |
| 248 } |
| 249 if (!file_util::CopyDirectory(src_file_path_, dest_file_path_, |
| 250 true /* recursive */)) { |
| 251 if (!file_util::PathExists(src_file_path_)) { |
| 252 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |
| 253 return; |
| 254 } |
| 255 if (src_file_path_.value() == dest_file_path_.value()) { |
| 256 set_error_code(base::PLATFORM_FILE_ERROR_EXISTS); |
| 257 return; |
| 258 } |
| 259 // Something else went wrong. |
| 260 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); |
| 261 } |
| 262 } |
| 263 |
| 264 private: |
| 265 FilePath src_file_path_; |
| 266 FilePath dest_file_path_; |
| 267 }; |
| 268 |
| 269 class RelayMove : public RelayWithStatusCallback { |
| 270 public: |
| 271 RelayMove(const FilePath& src_file_path, |
| 272 const FilePath& dest_file_path, |
| 273 base::FileUtilProxy::StatusCallback* callback) |
| 274 : RelayWithStatusCallback(callback), |
| 275 src_file_path_(src_file_path), |
| 276 dest_file_path_(dest_file_path) { |
| 277 } |
| 278 |
| 279 protected: |
| 280 virtual void RunWork() { |
| 281 bool dest_path_exists = file_util::PathExists(dest_file_path_); |
| 282 if (!dest_path_exists && |
| 283 !file_util::DirectoryExists(dest_file_path_.DirName())) { |
| 284 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |
| 285 return; |
| 286 } |
| 287 // |src_file_path| exists and is a directory. |
| 288 // |dest_file_path| exists and is a file. |
| 289 if (file_util::DirectoryExists(src_file_path_) && |
| 290 dest_path_exists && |
| 291 !file_util::DirectoryExists(dest_file_path_)) { |
| 292 set_error_code(base::PLATFORM_FILE_ERROR_EXISTS); |
| 293 return; |
| 294 } |
| 295 if (file_util::ContainsPath(src_file_path_, dest_file_path_)) { |
| 296 set_error_code(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); |
| 297 return; |
| 298 } |
| 299 if (!file_util::Move(src_file_path_, dest_file_path_)) { |
| 300 if (!file_util::PathExists(src_file_path_)) { |
| 301 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |
| 302 return; |
| 303 } |
| 304 if (src_file_path_.value() == dest_file_path_.value()) { |
| 305 set_error_code(base::PLATFORM_FILE_ERROR_EXISTS); |
| 306 return; |
| 307 } |
| 308 // Something else went wrong. |
| 309 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); |
| 310 } |
| 311 } |
| 312 |
| 313 private: |
| 314 FilePath src_file_path_; |
| 315 FilePath dest_file_path_; |
| 316 }; |
| 317 |
| 318 class RelayCreateDirectory : public RelayWithStatusCallback { |
| 319 public: |
| 320 RelayCreateDirectory( |
| 321 const FilePath& file_path, |
| 322 bool exclusive, |
| 323 base::FileUtilProxy::StatusCallback* callback) |
| 324 : RelayWithStatusCallback(callback), |
| 325 file_path_(file_path), |
| 326 exclusive_(exclusive) { |
| 327 } |
| 328 |
| 329 protected: |
| 330 virtual void RunWork() { |
| 331 bool path_exists = file_util::PathExists(file_path_); |
| 332 // If parent dir of file doesn't exist. |
| 333 if (!file_util::PathExists(file_path_.DirName())) { |
| 334 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |
| 335 return; |
| 336 } |
| 337 if (exclusive_ && path_exists) { |
| 338 set_error_code(base::PLATFORM_FILE_ERROR_EXISTS); |
| 339 return; |
| 340 } |
| 341 // If file exists at the path. |
| 342 if (path_exists && !file_util::DirectoryExists(file_path_)) { |
| 343 set_error_code(base::PLATFORM_FILE_ERROR_EXISTS); |
| 344 return; |
| 345 } |
| 346 if (!file_util::CreateDirectory(file_path_)) |
| 347 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); |
| 348 } |
| 349 |
| 350 private: |
| 351 FilePath file_path_; |
| 352 bool exclusive_; |
| 353 }; |
| 354 |
| 355 class RelayReadDirectory : public MessageLoopRelay { |
| 356 public: |
| 357 RelayReadDirectory(const FilePath& file_path, |
| 358 base::FileUtilProxy::ReadDirectoryCallback* callback) |
| 359 : callback_(callback), file_path_(file_path) { |
| 360 DCHECK(callback); |
| 361 } |
| 362 |
| 363 protected: |
| 364 virtual void RunWork() { |
| 365 // TODO(kkanetkar): Implement directory read in multiple chunks. |
| 366 if (!file_util::DirectoryExists(file_path_)) { |
| 367 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |
| 368 return; |
| 369 } |
| 370 |
| 371 file_util::FileEnumerator file_enum( |
| 372 file_path_, false, static_cast<file_util::FileEnumerator::FILE_TYPE>( |
| 373 file_util::FileEnumerator::FILES | |
| 374 file_util::FileEnumerator::DIRECTORIES)); |
| 375 FilePath current; |
| 376 while (!(current = file_enum.Next()).empty()) { |
| 377 base::file_util_proxy::Entry entry; |
| 378 file_util::FileEnumerator::FindInfo info; |
| 379 file_enum.GetFindInfo(&info); |
| 380 entry.isDirectory = file_enum.IsDirectory(info); |
| 381 // This will just give the entry's name instead of entire path |
| 382 // if we use current.value(). |
| 383 entry.name = file_util::FileEnumerator::GetFilename(info).value(); |
| 384 entries_.push_back(entry); |
| 385 } |
| 386 } |
| 387 |
| 388 virtual void RunCallback() { |
| 389 callback_->Run(error_code(), entries_); |
| 390 delete callback_; |
| 391 } |
| 392 |
| 393 private: |
| 394 base::FileUtilProxy::ReadDirectoryCallback* callback_; |
| 395 FilePath file_path_; |
| 396 std::vector<base::file_util_proxy::Entry> entries_; |
| 397 }; |
| 398 |
212 class RelayGetFileInfo : public MessageLoopRelay { | 399 class RelayGetFileInfo : public MessageLoopRelay { |
213 public: | 400 public: |
214 RelayGetFileInfo(const FilePath& file_path, | 401 RelayGetFileInfo(const FilePath& file_path, |
215 base::FileUtilProxy::GetFileInfoCallback* callback) | 402 base::FileUtilProxy::GetFileInfoCallback* callback) |
216 : callback_(callback), | 403 : callback_(callback), |
217 file_path_(file_path) { | 404 file_path_(file_path) { |
218 DCHECK(callback); | 405 DCHECK(callback); |
219 } | 406 } |
220 | 407 |
221 protected: | 408 protected: |
222 virtual void RunWork() { | 409 virtual void RunWork() { |
| 410 if (!file_util::PathExists(file_path_)) { |
| 411 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |
| 412 return; |
| 413 } |
223 if (!file_util::GetFileInfo(file_path_, &file_info_)) | 414 if (!file_util::GetFileInfo(file_path_, &file_info_)) |
224 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | 415 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); |
225 } | 416 } |
226 | 417 |
227 virtual void RunCallback() { | 418 virtual void RunCallback() { |
228 callback_->Run(error_code(), file_info_); | 419 callback_->Run(error_code(), file_info_); |
229 delete callback_; | 420 delete callback_; |
230 } | 421 } |
231 | 422 |
232 private: | 423 private: |
(...skipping 23 matching lines...) Expand all Loading... |
256 | 447 |
257 // static | 448 // static |
258 bool FileUtilProxy::CreateTemporary( | 449 bool FileUtilProxy::CreateTemporary( |
259 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 450 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
260 CreateTemporaryCallback* callback) { | 451 CreateTemporaryCallback* callback) { |
261 return Start(FROM_HERE, message_loop_proxy, | 452 return Start(FROM_HERE, message_loop_proxy, |
262 new RelayCreateTemporary(message_loop_proxy, callback)); | 453 new RelayCreateTemporary(message_loop_proxy, callback)); |
263 } | 454 } |
264 | 455 |
265 // static | 456 // static |
| 457 bool FileUtilProxy::CreateDirectory( |
| 458 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 459 const FilePath& file_path, |
| 460 bool exclusive, |
| 461 StatusCallback* callback) { |
| 462 return Start(FROM_HERE, message_loop_proxy, new RelayCreateDirectory( |
| 463 file_path, exclusive, callback)); |
| 464 } |
| 465 |
| 466 // static |
266 bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy, | 467 bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy, |
267 base::PlatformFile file_handle, | 468 base::PlatformFile file_handle, |
268 StatusCallback* callback) { | 469 StatusCallback* callback) { |
269 return Start(FROM_HERE, message_loop_proxy, | 470 return Start(FROM_HERE, message_loop_proxy, |
270 new RelayClose(file_handle, callback)); | 471 new RelayClose(file_handle, callback)); |
271 } | 472 } |
272 | 473 |
273 // static | 474 // static |
274 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, | 475 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, |
275 const FilePath& file_path, | 476 const FilePath& file_path, |
276 StatusCallback* callback) { | 477 StatusCallback* callback) { |
277 return Start(FROM_HERE, message_loop_proxy, | 478 return Start(FROM_HERE, message_loop_proxy, |
278 new RelayDelete(file_path, false, callback)); | 479 new RelayDelete(file_path, false, callback)); |
279 } | 480 } |
280 | 481 |
281 // static | 482 // static |
| 483 bool FileUtilProxy::Copy(scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 484 const FilePath& src_file_path, |
| 485 const FilePath& dest_file_path, |
| 486 StatusCallback* callback) { |
| 487 return Start(FROM_HERE, message_loop_proxy, |
| 488 new RelayCopy(src_file_path, dest_file_path, callback)); |
| 489 } |
| 490 |
| 491 // static |
| 492 bool FileUtilProxy::Move(scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 493 const FilePath& src_file_path, |
| 494 const FilePath& dest_file_path, |
| 495 StatusCallback* callback) { |
| 496 return Start(FROM_HERE, message_loop_proxy, |
| 497 new RelayMove(src_file_path, dest_file_path, callback)); |
| 498 } |
| 499 |
| 500 // static |
| 501 bool FileUtilProxy::ReadDirectory( |
| 502 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 503 const FilePath& file_path, |
| 504 ReadDirectoryCallback* callback) { |
| 505 return Start(FROM_HERE, message_loop_proxy, new RelayReadDirectory( |
| 506 file_path, callback)); |
| 507 } |
| 508 |
| 509 // Retrieves the information about a file. It is invalid to pass NULL for the |
| 510 // callback. |
| 511 bool FileUtilProxy::GetFileInfo( |
| 512 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 513 const FilePath& file_path, |
| 514 GetFileInfoCallback* callback) { |
| 515 return Start(FROM_HERE, message_loop_proxy, new RelayGetFileInfo( |
| 516 file_path, callback)); |
| 517 } |
| 518 |
| 519 // static |
282 bool FileUtilProxy::RecursiveDelete( | 520 bool FileUtilProxy::RecursiveDelete( |
283 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 521 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
284 const FilePath& file_path, | 522 const FilePath& file_path, |
285 StatusCallback* callback) { | 523 StatusCallback* callback) { |
286 return Start(FROM_HERE, message_loop_proxy, | 524 return Start(FROM_HERE, message_loop_proxy, |
287 new RelayDelete(file_path, true, callback)); | 525 new RelayDelete(file_path, true, callback)); |
288 } | 526 } |
289 | 527 |
290 // static | 528 } // namespace base |
291 bool FileUtilProxy::GetFileInfo( | |
292 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
293 const FilePath& file_path, | |
294 GetFileInfoCallback* callback) { | |
295 return Start(FROM_HERE, message_loop_proxy, | |
296 new RelayGetFileInfo(file_path, callback)); | |
297 } | |
298 | |
299 } // namespace base | |
OLD | NEW |