Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: base/file_util_posix.cc

Issue 149449: Fix: Linux file:// listings are sorted but not fully internationalized... (Closed) Base URL: svn://chrome-svn.corp.google.com/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
11 #include <fts.h> 11 #include <fts.h>
12 #include <libgen.h> 12 #include <libgen.h>
13 #include <stdio.h> 13 #include <stdio.h>
14 #include <string.h> 14 #include <string.h>
15 #include <sys/errno.h> 15 #include <sys/errno.h>
16 #include <sys/mman.h> 16 #include <sys/mman.h>
17 #include <sys/stat.h> 17 #include <sys/stat.h>
18 #include <sys/types.h> 18 #include <sys/types.h>
19 #include <time.h> 19 #include <time.h>
20 #include <unistd.h> 20 #include <unistd.h>
21 21
22 #include <fstream> 22 #include <fstream>
23 23
24 #include "base/basictypes.h" 24 #include "base/basictypes.h"
25 #include "base/eintr_wrapper.h" 25 #include "base/eintr_wrapper.h"
26 #include "base/file_path.h" 26 #include "base/file_path.h"
27 #include "base/lock.h"
27 #include "base/logging.h" 28 #include "base/logging.h"
29 #include "base/scoped_ptr.h"
30 #include "base/singleton.h"
28 #include "base/string_util.h" 31 #include "base/string_util.h"
32 #include "base/sys_string_conversions.h"
29 #include "base/time.h" 33 #include "base/time.h"
34 #include "unicode/coll.h"
30 35
31 namespace { 36 namespace {
32 37
33 bool IsDirectory(const FTSENT* file) { 38 bool IsDirectory(const FTSENT* file) {
34 switch (file->fts_info) { 39 switch (file->fts_info) {
35 case FTS_D: 40 case FTS_D:
36 case FTS_DC: 41 case FTS_DC:
37 case FTS_DNR: 42 case FTS_DNR:
38 case FTS_DOT: 43 case FTS_DOT:
39 case FTS_DP: 44 case FTS_DP:
40 return true; 45 return true;
41 default: 46 default:
42 return false; 47 return false;
43 } 48 }
44 } 49 }
45 50
51 class LocaleAwareComparator {
52 public:
53 LocaleAwareComparator() {
54 UErrorCode error_code = U_ZERO_ERROR;
55 // Use the default collator. The default locale should have been properly
56 // set by the time this constructor is called.
57 collator_.reset(Collator::createInstance(error_code));
58 DCHECK(U_SUCCESS(error_code));
59 // Make it case-sensitive.
60 collator_->setStrength(Collator::TERTIARY);
61 // Note: We do not set UCOL_NORMALIZATION_MODE attribute. In other words, we
62 // do not pay performance penalty to guarantee sort order correctness for
63 // non-FCD (http://unicode.org/notes/tn5/#FCD) file names. This should be a
64 // reasonable tradeoff because such file names should be rare and the sort
65 // order doesn't change much anyway.
66 }
67
68 // Note: A similar function is available in l10n_util.
69 // We cannot use it because base should not depend on l10n_util.
70 // TODO(yuzo): Move some of l10n_util to base.
71 int Compare(const string16& a, const string16& b) {
72 // We are not sure if Collator::compare is thread-safe.
73 // Use an AutoLock just in case.
74 AutoLock auto_lock(lock_);
75
76 UErrorCode error_code = U_ZERO_ERROR;
77 UCollationResult result = collator_->compare(
78 static_cast<const UChar*>(a.c_str()),
79 static_cast<int>(a.length()),
80 static_cast<const UChar*>(b.c_str()),
81 static_cast<int>(b.length()),
82 error_code);
83 DCHECK(U_SUCCESS(error_code));
84 return result;
85 }
86
87 private:
88 scoped_ptr<Collator> collator_;
89 Lock lock_;
90 friend struct DefaultSingletonTraits<LocaleAwareComparator>;
91
92 DISALLOW_COPY_AND_ASSIGN(LocaleAwareComparator);
93 };
94
95 int CompareFiles(const FTSENT** a, const FTSENT** b) {
96 // Order lexicographically with directories before other files.
97 const bool a_is_dir = IsDirectory(*a);
98 const bool b_is_dir = IsDirectory(*b);
99 if (a_is_dir != b_is_dir)
100 return a_is_dir ? -1 : 1;
101
102 // On linux, the file system encoding is not defined. We assume
103 // SysNativeMBToWide takes care of it.
104 //
105 // ICU's collator can take strings in OS native encoding. But we convert the
106 // strings to UTF-16 ourselves to ensure conversion consistency.
107 // TODO(yuzo): Perhaps we should define SysNativeMBToUTF16?
108 return Singleton<LocaleAwareComparator>()->Compare(
109 WideToUTF16(base::SysNativeMBToWide((*a)->fts_name)),
110 WideToUTF16(base::SysNativeMBToWide((*b)->fts_name)));
111 }
112
46 } // namespace 113 } // namespace
47 114
48 namespace file_util { 115 namespace file_util {
49 116
50 #if defined(GOOGLE_CHROME_BUILD) 117 #if defined(GOOGLE_CHROME_BUILD)
51 static const char* kTempFileName = "com.google.chrome.XXXXXX"; 118 static const char* kTempFileName = "com.google.chrome.XXXXXX";
52 #else 119 #else
53 static const char* kTempFileName = "org.chromium.XXXXXX"; 120 static const char* kTempFileName = "org.chromium.XXXXXX";
54 #endif 121 #endif
55 122
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 void FileEnumerator::GetFindInfo(FindInfo* info) { 636 void FileEnumerator::GetFindInfo(FindInfo* info) {
570 DCHECK(info); 637 DCHECK(info);
571 638
572 if (!is_in_find_op_) 639 if (!is_in_find_op_)
573 return; 640 return;
574 641
575 memcpy(&(info->stat), fts_ent_->fts_statp, sizeof(info->stat)); 642 memcpy(&(info->stat), fts_ent_->fts_statp, sizeof(info->stat));
576 info->filename.assign(fts_ent_->fts_name); 643 info->filename.assign(fts_ent_->fts_name);
577 } 644 }
578 645
579 int CompareFiles(const FTSENT** a, const FTSENT** b) {
580 // Order lexicographically with directories before other files.
581 const bool a_is_dir = IsDirectory(*a);
582 const bool b_is_dir = IsDirectory(*b);
583 if (a_is_dir != b_is_dir)
584 return a_is_dir ? -1 : 1;
585
586 // TODO(yuzo): make this internationalized when encoding detection function
587 // becomes available.
588 return base::strcasecmp((*a)->fts_name, (*b)->fts_name);
589 }
590
591 // As it stands, this method calls itself recursively when the next item of 646 // As it stands, this method calls itself recursively when the next item of
592 // the fts enumeration doesn't match (type, pattern, etc.). In the case of 647 // the fts enumeration doesn't match (type, pattern, etc.). In the case of
593 // large directories with many files this can be quite deep. 648 // large directories with many files this can be quite deep.
594 // TODO(erikkay) - get rid of this recursive pattern 649 // TODO(erikkay) - get rid of this recursive pattern
595 FilePath FileEnumerator::Next() { 650 FilePath FileEnumerator::Next() {
596 if (!is_in_find_op_) { 651 if (!is_in_find_op_) {
597 if (pending_paths_.empty()) 652 if (pending_paths_.empty())
598 return FilePath(); 653 return FilePath();
599 654
600 // The last find FindFirstFile operation is done, prepare a new one. 655 // The last find FindFirstFile operation is done, prepare a new one.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 munmap(data_, length_); 748 munmap(data_, length_);
694 if (file_ != -1) 749 if (file_ != -1)
695 close(file_); 750 close(file_);
696 751
697 data_ = NULL; 752 data_ = NULL;
698 length_ = 0; 753 length_ = 0;
699 file_ = -1; 754 file_ = -1;
700 } 755 }
701 756
702 } // namespace file_util 757 } // namespace file_util
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698