| 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 <dirent.h> | 7 #include <dirent.h> |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <fcntl.h> | 9 #include <fcntl.h> |
| 10 #include <fnmatch.h> | 10 #include <fnmatch.h> |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "base/eintr_wrapper.h" | 28 #include "base/eintr_wrapper.h" |
| 29 #include "base/file_path.h" | 29 #include "base/file_path.h" |
| 30 #include "base/lock.h" | 30 #include "base/lock.h" |
| 31 #include "base/logging.h" | 31 #include "base/logging.h" |
| 32 #include "base/scoped_ptr.h" | 32 #include "base/scoped_ptr.h" |
| 33 #include "base/singleton.h" | 33 #include "base/singleton.h" |
| 34 #include "base/string_util.h" | 34 #include "base/string_util.h" |
| 35 #include "base/sys_string_conversions.h" | 35 #include "base/sys_string_conversions.h" |
| 36 #include "base/time.h" | 36 #include "base/time.h" |
| 37 #include "base/utf_string_conversions.h" | 37 #include "base/utf_string_conversions.h" |
| 38 #include "unicode/coll.h" | |
| 39 | |
| 40 | |
| 41 namespace { | |
| 42 | |
| 43 class LocaleAwareComparator { | |
| 44 public: | |
| 45 LocaleAwareComparator() { | |
| 46 UErrorCode error_code = U_ZERO_ERROR; | |
| 47 // Use the default collator. The default locale should have been properly | |
| 48 // set by the time this constructor is called. | |
| 49 collator_.reset(icu::Collator::createInstance(error_code)); | |
| 50 DCHECK(U_SUCCESS(error_code)); | |
| 51 // Make it case-sensitive. | |
| 52 collator_->setStrength(icu::Collator::TERTIARY); | |
| 53 // Note: We do not set UCOL_NORMALIZATION_MODE attribute. In other words, we | |
| 54 // do not pay performance penalty to guarantee sort order correctness for | |
| 55 // non-FCD (http://unicode.org/notes/tn5/#FCD) file names. This should be a | |
| 56 // reasonable tradeoff because such file names should be rare and the sort | |
| 57 // order doesn't change much anyway. | |
| 58 } | |
| 59 | |
| 60 // Note: A similar function is available in l10n_util. | |
| 61 // We cannot use it because base should not depend on l10n_util. | |
| 62 // TODO(yuzo): Move some of l10n_util to base. | |
| 63 int Compare(const string16& a, const string16& b) { | |
| 64 // We are not sure if Collator::compare is thread-safe. | |
| 65 // Use an AutoLock just in case. | |
| 66 AutoLock auto_lock(lock_); | |
| 67 | |
| 68 UErrorCode error_code = U_ZERO_ERROR; | |
| 69 UCollationResult result = collator_->compare( | |
| 70 static_cast<const UChar*>(a.c_str()), | |
| 71 static_cast<int>(a.length()), | |
| 72 static_cast<const UChar*>(b.c_str()), | |
| 73 static_cast<int>(b.length()), | |
| 74 error_code); | |
| 75 DCHECK(U_SUCCESS(error_code)); | |
| 76 return result; | |
| 77 } | |
| 78 | |
| 79 private: | |
| 80 scoped_ptr<icu::Collator> collator_; | |
| 81 Lock lock_; | |
| 82 friend struct DefaultSingletonTraits<LocaleAwareComparator>; | |
| 83 | |
| 84 DISALLOW_COPY_AND_ASSIGN(LocaleAwareComparator); | |
| 85 }; | |
| 86 | |
| 87 } // namespace | |
| 88 | 38 |
| 89 namespace file_util { | 39 namespace file_util { |
| 90 | 40 |
| 91 #if defined(OS_FREEBSD) || \ | 41 #if defined(OS_FREEBSD) || \ |
| 92 (defined(OS_MACOSX) && \ | 42 (defined(OS_MACOSX) && \ |
| 93 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) | 43 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) |
| 94 typedef struct stat stat_wrapper_t; | 44 typedef struct stat stat_wrapper_t; |
| 95 static int CallStat(const char *path, stat_wrapper_t *sb) { | 45 static int CallStat(const char *path, stat_wrapper_t *sb) { |
| 96 return stat(path, sb); | 46 return stat(path, sb); |
| 97 } | 47 } |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 return FilePath(); | 566 return FilePath(); |
| 617 | 567 |
| 618 root_path_ = pending_paths_.top(); | 568 root_path_ = pending_paths_.top(); |
| 619 root_path_ = root_path_.StripTrailingSeparators(); | 569 root_path_ = root_path_.StripTrailingSeparators(); |
| 620 pending_paths_.pop(); | 570 pending_paths_.pop(); |
| 621 | 571 |
| 622 std::vector<DirectoryEntryInfo> entries; | 572 std::vector<DirectoryEntryInfo> entries; |
| 623 if (!ReadDirectory(&entries, root_path_, file_type_ & SHOW_SYM_LINKS)) | 573 if (!ReadDirectory(&entries, root_path_, file_type_ & SHOW_SYM_LINKS)) |
| 624 continue; | 574 continue; |
| 625 | 575 |
| 626 // The API says that order is not guaranteed, but order affects UX | |
| 627 std::sort(entries.begin(), entries.end(), CompareFiles); | |
| 628 | |
| 629 directory_entries_.clear(); | 576 directory_entries_.clear(); |
| 630 current_directory_entry_ = 0; | 577 current_directory_entry_ = 0; |
| 631 for (std::vector<DirectoryEntryInfo>::const_iterator | 578 for (std::vector<DirectoryEntryInfo>::const_iterator |
| 632 i = entries.begin(); i != entries.end(); ++i) { | 579 i = entries.begin(); i != entries.end(); ++i) { |
| 633 FilePath full_path = root_path_.Append(i->filename); | 580 FilePath full_path = root_path_.Append(i->filename); |
| 634 if (ShouldSkip(full_path)) | 581 if (ShouldSkip(full_path)) |
| 635 continue; | 582 continue; |
| 636 | 583 |
| 637 if (pattern_.value().size() && | 584 if (pattern_.value().size() && |
| 638 fnmatch(pattern_.value().c_str(), full_path.value().c_str(), | 585 fnmatch(pattern_.value().c_str(), full_path.value().c_str(), |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 } | 631 } |
| 685 memset(&info.stat, 0, sizeof(info.stat)); | 632 memset(&info.stat, 0, sizeof(info.stat)); |
| 686 } | 633 } |
| 687 entries->push_back(info); | 634 entries->push_back(info); |
| 688 } | 635 } |
| 689 | 636 |
| 690 closedir(dir); | 637 closedir(dir); |
| 691 return true; | 638 return true; |
| 692 } | 639 } |
| 693 | 640 |
| 694 bool FileEnumerator::CompareFiles(const DirectoryEntryInfo& a, | |
| 695 const DirectoryEntryInfo& b) { | |
| 696 // Order lexicographically with directories before other files. | |
| 697 if (S_ISDIR(a.stat.st_mode) != S_ISDIR(b.stat.st_mode)) | |
| 698 return S_ISDIR(a.stat.st_mode); | |
| 699 | |
| 700 // On linux, the file system encoding is not defined. We assume | |
| 701 // SysNativeMBToWide takes care of it. | |
| 702 // | |
| 703 // ICU's collator can take strings in OS native encoding. But we convert the | |
| 704 // strings to UTF-16 ourselves to ensure conversion consistency. | |
| 705 // TODO(yuzo): Perhaps we should define SysNativeMBToUTF16? | |
| 706 return Singleton<LocaleAwareComparator>()->Compare( | |
| 707 WideToUTF16(base::SysNativeMBToWide(a.filename.value().c_str())), | |
| 708 WideToUTF16(base::SysNativeMBToWide(b.filename.value().c_str()))) < 0; | |
| 709 } | |
| 710 | |
| 711 /////////////////////////////////////////////// | 641 /////////////////////////////////////////////// |
| 712 // MemoryMappedFile | 642 // MemoryMappedFile |
| 713 | 643 |
| 714 MemoryMappedFile::MemoryMappedFile() | 644 MemoryMappedFile::MemoryMappedFile() |
| 715 : file_(-1), | 645 : file_(-1), |
| 716 data_(NULL), | 646 data_(NULL), |
| 717 length_(0) { | 647 length_(0) { |
| 718 } | 648 } |
| 719 | 649 |
| 720 bool MemoryMappedFile::MapFileToMemory(const FilePath& file_name) { | 650 bool MemoryMappedFile::MapFileToMemory(const FilePath& file_name) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 745 munmap(data_, length_); | 675 munmap(data_, length_); |
| 746 if (file_ != -1) | 676 if (file_ != -1) |
| 747 close(file_); | 677 close(file_); |
| 748 | 678 |
| 749 data_ = NULL; | 679 data_ = NULL; |
| 750 length_ = 0; | 680 length_ = 0; |
| 751 file_ = -1; | 681 file_ = -1; |
| 752 } | 682 } |
| 753 | 683 |
| 754 } // namespace file_util | 684 } // namespace file_util |
| OLD | NEW |