OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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.h" | 5 #include "base/file_util.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <fnmatch.h> | 9 #include <fnmatch.h> |
10 #include <fts.h> | 10 #include <fts.h> |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 *dir = FilePath(system_buffer); | 371 *dir = FilePath(system_buffer); |
372 return true; | 372 return true; |
373 } | 373 } |
374 | 374 |
375 // Sets the current working directory for the process. | 375 // Sets the current working directory for the process. |
376 bool SetCurrentDirectory(const FilePath& path) { | 376 bool SetCurrentDirectory(const FilePath& path) { |
377 int ret = chdir(path.value().c_str()); | 377 int ret = chdir(path.value().c_str()); |
378 return !ret; | 378 return !ret; |
379 } | 379 } |
380 | 380 |
381 FileEnumerator::FileEnumerator(const std::wstring& root_path, | 381 FileEnumerator::FileEnumerator(const FilePath& root_path, |
382 bool recursive, | 382 bool recursive, |
383 FileEnumerator::FILE_TYPE file_type) | 383 FileEnumerator::FILE_TYPE file_type) |
384 : recursive_(recursive), | 384 : recursive_(recursive), |
385 file_type_(file_type), | 385 file_type_(file_type), |
386 is_in_find_op_(false), | 386 is_in_find_op_(false), |
387 fts_(NULL) { | 387 fts_(NULL) { |
388 pending_paths_.push(root_path); | 388 pending_paths_.push(root_path); |
389 } | 389 } |
390 | 390 |
391 FileEnumerator::FileEnumerator(const std::wstring& root_path, | 391 FileEnumerator::FileEnumerator(const FilePath& root_path, |
392 bool recursive, | 392 bool recursive, |
393 FileEnumerator::FILE_TYPE file_type, | 393 FileEnumerator::FILE_TYPE file_type, |
394 const std::wstring& pattern) | 394 const FilePath::StringType& pattern) |
395 : recursive_(recursive), | 395 : recursive_(recursive), |
396 file_type_(file_type), | 396 file_type_(file_type), |
397 pattern_(root_path), | 397 pattern_(root_path.value()), |
398 is_in_find_op_(false), | 398 is_in_find_op_(false), |
399 fts_(NULL) { | 399 fts_(NULL) { |
400 // The Windows version of this code only matches against items in the top-most | 400 // The Windows version of this code only matches against items in the top-most |
401 // directory, and we're comparing fnmatch against full paths, so this is the | 401 // directory, and we're comparing fnmatch against full paths, so this is the |
402 // easiest way to get the right pattern. | 402 // easiest way to get the right pattern. |
403 AppendToPath(&pattern_, pattern); | 403 pattern_ = pattern_.Append(pattern); |
404 pending_paths_.push(root_path); | 404 pending_paths_.push(root_path); |
405 } | 405 } |
406 | 406 |
407 FileEnumerator::~FileEnumerator() { | 407 FileEnumerator::~FileEnumerator() { |
408 if (fts_) | 408 if (fts_) |
409 fts_close(fts_); | 409 fts_close(fts_); |
410 } | 410 } |
411 | 411 |
412 void FileEnumerator::GetFindInfo(FindInfo* info) { | 412 void FileEnumerator::GetFindInfo(FindInfo* info) { |
413 DCHECK(info); | 413 DCHECK(info); |
414 | 414 |
415 if (!is_in_find_op_) | 415 if (!is_in_find_op_) |
416 return; | 416 return; |
417 | 417 |
418 memcpy(&(info->stat), fts_ent_->fts_statp, sizeof(info->stat)); | 418 memcpy(&(info->stat), fts_ent_->fts_statp, sizeof(info->stat)); |
419 info->filename.assign(fts_ent_->fts_name); | 419 info->filename.assign(fts_ent_->fts_name); |
420 } | 420 } |
421 | 421 |
422 // As it stands, this method calls itself recursively when the next item of | 422 // As it stands, this method calls itself recursively when the next item of |
423 // the fts enumeration doesn't match (type, pattern, etc.). In the case of | 423 // the fts enumeration doesn't match (type, pattern, etc.). In the case of |
424 // large directories with many files this can be quite deep. | 424 // large directories with many files this can be quite deep. |
425 // TODO(erikkay) - get rid of this recursive pattern | 425 // TODO(erikkay) - get rid of this recursive pattern |
426 std::wstring FileEnumerator::Next() { | 426 FilePath FileEnumerator::Next() { |
427 if (!is_in_find_op_) { | 427 if (!is_in_find_op_) { |
428 if (pending_paths_.empty()) | 428 if (pending_paths_.empty()) |
429 return std::wstring(); | 429 return FilePath(); |
430 | 430 |
431 // The last find FindFirstFile operation is done, prepare a new one. | 431 // The last find FindFirstFile operation is done, prepare a new one. |
432 root_path_ = pending_paths_.top(); | 432 root_path_ = pending_paths_.top(); |
433 TrimTrailingSeparator(&root_path_); | 433 root_path_ = root_path_.StripTrailingSeparators(); |
434 pending_paths_.pop(); | 434 pending_paths_.pop(); |
435 | 435 |
436 // Start a new find operation. | 436 // Start a new find operation. |
437 int ftsflags = FTS_LOGICAL; | 437 int ftsflags = FTS_LOGICAL; |
438 char top_dir[PATH_MAX]; | 438 char top_dir[PATH_MAX]; |
439 base::strlcpy(top_dir, WideToUTF8(root_path_).c_str(), sizeof(top_dir)); | 439 base::strlcpy(top_dir, root_path_.value().c_str(), sizeof(top_dir)); |
440 char* dir_list[2] = { top_dir, NULL }; | 440 char* dir_list[2] = { top_dir, NULL }; |
441 fts_ = fts_open(dir_list, ftsflags, NULL); | 441 fts_ = fts_open(dir_list, ftsflags, NULL); |
442 if (!fts_) | 442 if (!fts_) |
443 return Next(); | 443 return Next(); |
444 is_in_find_op_ = true; | 444 is_in_find_op_ = true; |
445 } | 445 } |
446 | 446 |
447 fts_ent_ = fts_read(fts_); | 447 fts_ent_ = fts_read(fts_); |
448 if (fts_ent_ == NULL) { | 448 if (fts_ent_ == NULL) { |
449 fts_close(fts_); | 449 fts_close(fts_); |
450 fts_ = NULL; | 450 fts_ = NULL; |
451 is_in_find_op_ = false; | 451 is_in_find_op_ = false; |
452 return Next(); | 452 return Next(); |
453 } | 453 } |
454 | 454 |
455 // Level 0 is the top, which is always skipped. | 455 // Level 0 is the top, which is always skipped. |
456 if (fts_ent_->fts_level == 0) | 456 if (fts_ent_->fts_level == 0) |
457 return Next(); | 457 return Next(); |
458 | 458 |
459 // Patterns are only matched on the items in the top-most directory. | 459 // Patterns are only matched on the items in the top-most directory. |
460 // (see Windows implementation) | 460 // (see Windows implementation) |
461 if (fts_ent_->fts_level == 1 && pattern_.length() > 0) { | 461 if (fts_ent_->fts_level == 1 && pattern_.value().length() > 0) { |
462 if (fnmatch(WideToUTF8(pattern_).c_str(), fts_ent_->fts_path, 0) != 0) { | 462 if (fnmatch(pattern_.value().c_str(), fts_ent_->fts_path, 0) != 0) { |
463 if (fts_ent_->fts_info == FTS_D) | 463 if (fts_ent_->fts_info == FTS_D) |
464 fts_set(fts_, fts_ent_, FTS_SKIP); | 464 fts_set(fts_, fts_ent_, FTS_SKIP); |
465 return Next(); | 465 return Next(); |
466 } | 466 } |
467 } | 467 } |
468 | 468 |
469 std::wstring cur_file(UTF8ToWide(fts_ent_->fts_path)); | 469 FilePath cur_file(fts_ent_->fts_path); |
470 if (fts_ent_->fts_info == FTS_D) { | 470 if (fts_ent_->fts_info == FTS_D) { |
471 // If not recursive, then prune children. | 471 // If not recursive, then prune children. |
472 if (!recursive_) | 472 if (!recursive_) |
473 fts_set(fts_, fts_ent_, FTS_SKIP); | 473 fts_set(fts_, fts_ent_, FTS_SKIP); |
474 return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next(); | 474 return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next(); |
475 } else if (fts_ent_->fts_info == FTS_F) { | 475 } else if (fts_ent_->fts_info == FTS_F) { |
476 return (file_type_ & FileEnumerator::FILES) ? cur_file : Next(); | 476 return (file_type_ & FileEnumerator::FILES) ? cur_file : Next(); |
477 } | 477 } |
478 // TODO(erikkay) - verify that the other fts_info types aren't interesting | 478 // TODO(erikkay) - verify that the other fts_info types aren't interesting |
479 return Next(); | 479 return Next(); |
480 } | 480 } |
481 | 481 |
482 | 482 |
483 } // namespace file_util | 483 } // namespace file_util |
OLD | NEW |