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

Side by Side Diff: base/file_path.cc

Issue 3018011: POSIX: treat multiple extensions like .tar.gz as a single extension. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: more review comments Created 10 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 | base/file_path_unittest.cc » ('j') | 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) 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_path.h" 5 #include "base/file_path.h"
6 6
7 #if defined(OS_MACOSX) 7 #if defined(OS_MACOSX)
8 #include <CoreServices/CoreServices.h> 8 #include <CoreServices/CoreServices.h>
9 #endif 9 #endif
10 10
(...skipping 18 matching lines...) Expand all
29 const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("\\/"); 29 const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("\\/");
30 #else // FILE_PATH_USES_WIN_SEPARATORS 30 #else // FILE_PATH_USES_WIN_SEPARATORS
31 const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("/"); 31 const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("/");
32 #endif // FILE_PATH_USES_WIN_SEPARATORS 32 #endif // FILE_PATH_USES_WIN_SEPARATORS
33 33
34 const FilePath::CharType FilePath::kCurrentDirectory[] = FILE_PATH_LITERAL("."); 34 const FilePath::CharType FilePath::kCurrentDirectory[] = FILE_PATH_LITERAL(".");
35 const FilePath::CharType FilePath::kParentDirectory[] = FILE_PATH_LITERAL(".."); 35 const FilePath::CharType FilePath::kParentDirectory[] = FILE_PATH_LITERAL("..");
36 36
37 const FilePath::CharType FilePath::kExtensionSeparator = FILE_PATH_LITERAL('.'); 37 const FilePath::CharType FilePath::kExtensionSeparator = FILE_PATH_LITERAL('.');
38 38
39 typedef FilePath::StringType StringType;
39 40
40 namespace { 41 namespace {
41 42
43 const char* kCommonDoubleExtensions[] = { "gz", "z", "bz2" };
44
42 // If this FilePath contains a drive letter specification, returns the 45 // If this FilePath contains a drive letter specification, returns the
43 // position of the last character of the drive letter specification, 46 // position of the last character of the drive letter specification,
44 // otherwise returns npos. This can only be true on Windows, when a pathname 47 // otherwise returns npos. This can only be true on Windows, when a pathname
45 // begins with a letter followed by a colon. On other platforms, this always 48 // begins with a letter followed by a colon. On other platforms, this always
46 // returns npos. 49 // returns npos.
47 FilePath::StringType::size_type FindDriveLetter( 50 StringType::size_type FindDriveLetter(const StringType& path) {
48 const FilePath::StringType& path) {
49 #if defined(FILE_PATH_USES_DRIVE_LETTERS) 51 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
50 // This is dependent on an ASCII-based character set, but that's a 52 // This is dependent on an ASCII-based character set, but that's a
51 // reasonable assumption. iswalpha can be too inclusive here. 53 // reasonable assumption. iswalpha can be too inclusive here.
52 if (path.length() >= 2 && path[1] == L':' && 54 if (path.length() >= 2 && path[1] == L':' &&
53 ((path[0] >= L'A' && path[0] <= L'Z') || 55 ((path[0] >= L'A' && path[0] <= L'Z') ||
54 (path[0] >= L'a' && path[0] <= L'z'))) { 56 (path[0] >= L'a' && path[0] <= L'z'))) {
55 return 1; 57 return 1;
56 } 58 }
57 #endif // FILE_PATH_USES_DRIVE_LETTERS 59 #endif // FILE_PATH_USES_DRIVE_LETTERS
58 return FilePath::StringType::npos; 60 return StringType::npos;
59 } 61 }
60 62
61
62 #if defined(FILE_PATH_USES_DRIVE_LETTERS) 63 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
63 bool EqualDriveLetterCaseInsensitive(const FilePath::StringType a, 64 bool EqualDriveLetterCaseInsensitive(const StringType a,
64 const FilePath::StringType b) { 65 const StringType b) {
65 size_t a_letter_pos = FindDriveLetter(a); 66 size_t a_letter_pos = FindDriveLetter(a);
66 size_t b_letter_pos = FindDriveLetter(b); 67 size_t b_letter_pos = FindDriveLetter(b);
67 68
68 if ((a_letter_pos == FilePath::StringType::npos) || 69 if (a_letter_pos == StringType::npos || b_letter_pos == StringType::npos)
69 (b_letter_pos == FilePath::StringType::npos))
70 return a == b; 70 return a == b;
71 71
72 FilePath::StringType a_letter(a.substr(0, a_letter_pos + 1)); 72 StringType a_letter(a.substr(0, a_letter_pos + 1));
73 FilePath::StringType b_letter(b.substr(0, b_letter_pos + 1)); 73 StringType b_letter(b.substr(0, b_letter_pos + 1));
74 if (!StartsWith(a_letter, b_letter, false)) 74 if (!StartsWith(a_letter, b_letter, false))
75 return false; 75 return false;
76 76
77 FilePath::StringType a_rest(a.substr(a_letter_pos + 1)); 77 StringType a_rest(a.substr(a_letter_pos + 1));
78 FilePath::StringType b_rest(b.substr(b_letter_pos + 1)); 78 StringType b_rest(b.substr(b_letter_pos + 1));
79 return a_rest == b_rest; 79 return a_rest == b_rest;
80 } 80 }
81 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS) 81 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS)
82 82
83 bool IsPathAbsolute(const FilePath::StringType& path) { 83 bool IsPathAbsolute(const StringType& path) {
84 #if defined(FILE_PATH_USES_DRIVE_LETTERS) 84 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
85 FilePath::StringType::size_type letter = FindDriveLetter(path); 85 StringType::size_type letter = FindDriveLetter(path);
86 if (letter != FilePath::StringType::npos) { 86 if (letter != StringType::npos) {
87 // Look for a separator right after the drive specification. 87 // Look for a separator right after the drive specification.
88 return path.length() > letter + 1 && 88 return path.length() > letter + 1 &&
89 FilePath::IsSeparator(path[letter + 1]); 89 FilePath::IsSeparator(path[letter + 1]);
90 } 90 }
91 // Look for a pair of leading separators. 91 // Look for a pair of leading separators.
92 return path.length() > 1 && 92 return path.length() > 1 &&
93 FilePath::IsSeparator(path[0]) && FilePath::IsSeparator(path[1]); 93 FilePath::IsSeparator(path[0]) && FilePath::IsSeparator(path[1]);
94 #else // FILE_PATH_USES_DRIVE_LETTERS 94 #else // FILE_PATH_USES_DRIVE_LETTERS
95 // Look for a separator in the first position. 95 // Look for a separator in the first position.
96 return path.length() > 0 && FilePath::IsSeparator(path[0]); 96 return path.length() > 0 && FilePath::IsSeparator(path[0]);
97 #endif // FILE_PATH_USES_DRIVE_LETTERS 97 #endif // FILE_PATH_USES_DRIVE_LETTERS
98 } 98 }
99 99
100 bool AreAllSeparators(const FilePath::StringType& input) { 100 bool AreAllSeparators(const StringType& input) {
101 for (FilePath::StringType::const_iterator it = input.begin(); 101 for (StringType::const_iterator it = input.begin();
102 it != input.end(); ++it) { 102 it != input.end(); ++it) {
103 if (!FilePath::IsSeparator(*it)) 103 if (!FilePath::IsSeparator(*it))
104 return false; 104 return false;
105 } 105 }
106 106
107 return true; 107 return true;
108 } 108 }
109 109
110 // Find the position of the '.' that separates the extension from the rest
111 // of the file name. The position is relative to BaseName(), not value().
112 // This allows a second extension component of up to 4 characters when the
113 // rightmost extension component is a common double extension (gz, bz2, Z).
114 // For example, foo.tar.gz or foo.tar.Z would have extension components of
115 // '.tar.gz' and '.tar.Z' respectively. Returns npos if it can't find an
116 // extension.
117 StringType::size_type ExtensionSeparatorPosition(const StringType& path) {
118 // Special case "." and ".."
119 if (path == FilePath::kCurrentDirectory || path == FilePath::kParentDirectory)
120 return StringType::npos;
121
122 const StringType::size_type last_dot =
123 path.rfind(FilePath::kExtensionSeparator);
124
125 // No extension, or the extension is the whole filename.
126 if (last_dot == StringType::npos || last_dot == 0U)
127 return last_dot;
128
129 // Special case .<extension1>.<extension2>, but only if the final extension
130 // is one of a few common double extensions.
131 StringType extension(path, last_dot + 1);
132 bool is_common_double_extension = false;
133 for (size_t i = 0; i < arraysize(kCommonDoubleExtensions); ++i) {
134 if (LowerCaseEqualsASCII(extension, kCommonDoubleExtensions[i]))
135 is_common_double_extension = true;
136 }
137 if (!is_common_double_extension)
138 return last_dot;
139
140 // Check that <extension1> is 1-4 characters, otherwise fall back to
141 // <extension2>.
142 const StringType::size_type penultimate_dot =
143 path.rfind(FilePath::kExtensionSeparator, last_dot - 1);
144 const StringType::size_type last_separator =
145 path.find_last_of(FilePath::kSeparators, last_dot - 1,
146 arraysize(FilePath::kSeparators) - 1);
147 if (penultimate_dot != StringType::npos &&
148 (last_separator == StringType::npos ||
149 penultimate_dot > last_separator) &&
150 last_dot - penultimate_dot <= 5U &&
151 last_dot - penultimate_dot > 1U) {
152 return penultimate_dot;
153 }
154
155 return last_dot;
156 }
157
110 } // namespace 158 } // namespace
111 159
112 FilePath::FilePath() { 160 FilePath::FilePath() {
113 } 161 }
114 162
115 FilePath::FilePath(const FilePath& that) : path_(that.path_) { 163 FilePath::FilePath(const FilePath& that) : path_(that.path_) {
116 } 164 }
117 165
118 FilePath::FilePath(const StringType& path) : path_(path) { 166 FilePath::FilePath(const StringType& path) : path_(path) {
119 } 167 }
120 168
121 FilePath::~FilePath() { 169 FilePath::~FilePath() {
122 } 170 }
123 171
124 FilePath& FilePath::operator=(const FilePath& that) { 172 FilePath& FilePath::operator=(const FilePath& that) {
125 path_ = that.path_; 173 path_ = that.path_;
126 return *this; 174 return *this;
127 } 175 }
128 176
129 bool FilePath::IsSeparator(CharType character) { 177 bool FilePath::IsSeparator(CharType character) {
130 for (size_t i = 0; i < arraysize(kSeparators) - 1; ++i) { 178 for (size_t i = 0; i < arraysize(kSeparators) - 1; ++i) {
131 if (character == kSeparators[i]) { 179 if (character == kSeparators[i]) {
132 return true; 180 return true;
133 } 181 }
134 } 182 }
135 183
136 return false; 184 return false;
137 } 185 }
138 186
139 void FilePath::GetComponents(std::vector<FilePath::StringType>* components) 187 void FilePath::GetComponents(std::vector<StringType>* components) const {
140 const {
141 DCHECK(components); 188 DCHECK(components);
142 if (!components) 189 if (!components)
143 return; 190 return;
144 components->clear(); 191 components->clear();
145 if (value().empty()) 192 if (value().empty())
146 return; 193 return;
147 194
148 std::vector<FilePath::StringType> ret_val; 195 std::vector<StringType> ret_val;
149 FilePath current = *this; 196 FilePath current = *this;
150 FilePath base; 197 FilePath base;
151 198
152 // Capture path components. 199 // Capture path components.
153 while (current != current.DirName()) { 200 while (current != current.DirName()) {
154 base = current.BaseName(); 201 base = current.BaseName();
155 if (!AreAllSeparators(base.value())) 202 if (!AreAllSeparators(base.value()))
156 ret_val.push_back(base.value()); 203 ret_val.push_back(base.value());
157 current = current.DirName(); 204 current = current.DirName();
158 } 205 }
159 206
160 // Capture root, if any. 207 // Capture root, if any.
161 base = current.BaseName(); 208 base = current.BaseName();
162 if (!base.value().empty() && base.value() != kCurrentDirectory) 209 if (!base.value().empty() && base.value() != kCurrentDirectory)
163 ret_val.push_back(current.BaseName().value()); 210 ret_val.push_back(current.BaseName().value());
164 211
165 // Capture drive letter, if any. 212 // Capture drive letter, if any.
166 FilePath dir = current.DirName(); 213 FilePath dir = current.DirName();
167 StringType::size_type letter = FindDriveLetter(dir.value()); 214 StringType::size_type letter = FindDriveLetter(dir.value());
168 if (letter != FilePath::StringType::npos) { 215 if (letter != StringType::npos) {
169 ret_val.push_back(FilePath::StringType(dir.value(), 0, letter + 1)); 216 ret_val.push_back(StringType(dir.value(), 0, letter + 1));
170 } 217 }
171 218
172 *components = std::vector<FilePath::StringType>(ret_val.rbegin(), 219 *components = std::vector<StringType>(ret_val.rbegin(), ret_val.rend());
173 ret_val.rend());
174 } 220 }
175 221
176 bool FilePath::operator==(const FilePath& that) const { 222 bool FilePath::operator==(const FilePath& that) const {
177 #if defined(FILE_PATH_USES_DRIVE_LETTERS) 223 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
178 return EqualDriveLetterCaseInsensitive(this->path_, that.path_); 224 return EqualDriveLetterCaseInsensitive(this->path_, that.path_);
179 #else // defined(FILE_PATH_USES_DRIVE_LETTERS) 225 #else // defined(FILE_PATH_USES_DRIVE_LETTERS)
180 return path_ == that.path_; 226 return path_ == that.path_;
181 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS) 227 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS)
182 } 228 }
183 229
184 bool FilePath::operator!=(const FilePath& that) const { 230 bool FilePath::operator!=(const FilePath& that) const {
185 #if defined(FILE_PATH_USES_DRIVE_LETTERS) 231 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
186 return !EqualDriveLetterCaseInsensitive(this->path_, that.path_); 232 return !EqualDriveLetterCaseInsensitive(this->path_, that.path_);
187 #else // defined(FILE_PATH_USES_DRIVE_LETTERS) 233 #else // defined(FILE_PATH_USES_DRIVE_LETTERS)
188 return path_ != that.path_; 234 return path_ != that.path_;
189 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS) 235 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS)
190 } 236 }
191 237
192 bool FilePath::IsParent(const FilePath& child) const { 238 bool FilePath::IsParent(const FilePath& child) const {
193 return AppendRelativePath(child, NULL); 239 return AppendRelativePath(child, NULL);
194 } 240 }
195 241
196 bool FilePath::AppendRelativePath(const FilePath& child, 242 bool FilePath::AppendRelativePath(const FilePath& child,
197 FilePath* path) const { 243 FilePath* path) const {
198 std::vector<FilePath::StringType> parent_components; 244 std::vector<StringType> parent_components;
199 std::vector<FilePath::StringType> child_components; 245 std::vector<StringType> child_components;
200 GetComponents(&parent_components); 246 GetComponents(&parent_components);
201 child.GetComponents(&child_components); 247 child.GetComponents(&child_components);
202 248
203 if (parent_components.size() >= child_components.size()) 249 if (parent_components.size() >= child_components.size())
204 return false; 250 return false;
205 if (parent_components.size() == 0) 251 if (parent_components.size() == 0)
206 return false; 252 return false;
207 253
208 std::vector<FilePath::StringType>::const_iterator parent_comp = 254 std::vector<StringType>::const_iterator parent_comp =
209 parent_components.begin(); 255 parent_components.begin();
210 std::vector<FilePath::StringType>::const_iterator child_comp = 256 std::vector<StringType>::const_iterator child_comp =
211 child_components.begin(); 257 child_components.begin();
212 258
213 #if defined(FILE_PATH_USES_DRIVE_LETTERS) 259 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
214 // Windows can access case sensitive filesystems, so component 260 // Windows can access case sensitive filesystems, so component
215 // comparisions must be case sensitive, but drive letters are 261 // comparisions must be case sensitive, but drive letters are
216 // never case sensitive. 262 // never case sensitive.
217 if ((FindDriveLetter(*parent_comp) != FilePath::StringType::npos) && 263 if ((FindDriveLetter(*parent_comp) != StringType::npos) &&
218 (FindDriveLetter(*child_comp) != FilePath::StringType::npos)) { 264 (FindDriveLetter(*child_comp) != StringType::npos)) {
219 if (!StartsWith(*parent_comp, *child_comp, false)) 265 if (!StartsWith(*parent_comp, *child_comp, false))
220 return false; 266 return false;
221 ++parent_comp; 267 ++parent_comp;
222 ++child_comp; 268 ++child_comp;
223 } 269 }
224 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS) 270 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS)
225 271
226 while (parent_comp != parent_components.end()) { 272 while (parent_comp != parent_components.end()) {
227 if (*parent_comp != *child_comp) 273 if (*parent_comp != *child_comp)
228 return false; 274 return false;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 new_path.path_.find_last_of(kSeparators, StringType::npos, 340 new_path.path_.find_last_of(kSeparators, StringType::npos,
295 arraysize(kSeparators) - 1); 341 arraysize(kSeparators) - 1);
296 if (last_separator != StringType::npos && 342 if (last_separator != StringType::npos &&
297 last_separator < new_path.path_.length() - 1) { 343 last_separator < new_path.path_.length() - 1) {
298 new_path.path_.erase(0, last_separator + 1); 344 new_path.path_.erase(0, last_separator + 1);
299 } 345 }
300 346
301 return new_path; 347 return new_path;
302 } 348 }
303 349
304 FilePath::StringType FilePath::Extension() const { 350 StringType FilePath::Extension() const {
305 // BaseName() calls StripTrailingSeparators, so cases like /foo.baz/// work. 351 FilePath base(BaseName());
306 StringType base = BaseName().value(); 352 const StringType::size_type dot = ExtensionSeparatorPosition(base.path_);
307 353 if (dot == StringType::npos)
308 // Special case "." and ".."
309 if (base == kCurrentDirectory || base == kParentDirectory)
310 return StringType(); 354 return StringType();
311 355
312 const StringType::size_type last_dot = base.rfind(kExtensionSeparator); 356 return base.path_.substr(dot, StringType::npos);
313 if (last_dot == StringType::npos)
314 return StringType();
315 return StringType(base, last_dot);
316 } 357 }
317 358
318 FilePath FilePath::RemoveExtension() const { 359 FilePath FilePath::RemoveExtension() const {
319 StringType ext = Extension(); 360 if (Extension().empty())
320 // It's important to check Extension() since that verifies that the 361 return *this;
321 // kExtensionSeparator actually appeared in the last path component. 362
322 if (ext.empty()) 363 const StringType::size_type dot = ExtensionSeparatorPosition(path_);
323 return FilePath(path_); 364 if (dot == StringType::npos)
324 // Since Extension() verified that the extension is in fact in the last path 365 return *this;
325 // component, this substr will effectively strip trailing separators. 366
326 const StringType::size_type last_dot = path_.rfind(kExtensionSeparator); 367 return FilePath(path_.substr(0, dot));
327 return FilePath(path_.substr(0, last_dot));
328 } 368 }
329 369
330 FilePath FilePath::InsertBeforeExtension(const StringType& suffix) const { 370 FilePath FilePath::InsertBeforeExtension(const StringType& suffix) const {
331 if (suffix.empty()) 371 if (suffix.empty())
332 return FilePath(path_); 372 return FilePath(path_);
333 373
334 if (path_.empty()) 374 if (path_.empty())
335 return FilePath(); 375 return FilePath();
336 376
337 StringType base = BaseName().value(); 377 StringType base = BaseName().value();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 StringType str = no_ext.value(); 423 StringType str = no_ext.value();
384 if (extension[0] != kExtensionSeparator) 424 if (extension[0] != kExtensionSeparator)
385 str.append(1, kExtensionSeparator); 425 str.append(1, kExtensionSeparator);
386 str.append(extension); 426 str.append(extension);
387 return FilePath(str); 427 return FilePath(str);
388 } 428 }
389 429
390 bool FilePath::MatchesExtension(const StringType& extension) const { 430 bool FilePath::MatchesExtension(const StringType& extension) const {
391 DCHECK(extension.empty() || extension[0] == kExtensionSeparator); 431 DCHECK(extension.empty() || extension[0] == kExtensionSeparator);
392 432
393 FilePath::StringType current_extension = Extension(); 433 StringType current_extension = Extension();
394 434
395 if (current_extension.length() != extension.length()) 435 if (current_extension.length() != extension.length())
396 return false; 436 return false;
397 437
398 return FilePath::CompareEqualIgnoreCase(extension, current_extension); 438 return FilePath::CompareEqualIgnoreCase(extension, current_extension);
399 } 439 }
400 440
401 FilePath FilePath::Append(const StringType& component) const { 441 FilePath FilePath::Append(const StringType& component) const {
402 DCHECK(!IsPathAbsolute(component)); 442 DCHECK(!IsPathAbsolute(component));
403 if (path_.compare(kCurrentDirectory) == 0) { 443 if (path_.compare(kCurrentDirectory) == 0) {
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 if (codepoint1 != codepoint2) 983 if (codepoint1 != codepoint2)
944 return (codepoint1 < codepoint2) ? -1 : 1; 984 return (codepoint1 < codepoint2) ? -1 : 1;
945 if (codepoint1 == 0) { 985 if (codepoint1 == 0) {
946 DCHECK_EQ(index1, length1); 986 DCHECK_EQ(index1, length1);
947 DCHECK_EQ(index2, length2); 987 DCHECK_EQ(index2, length2);
948 return 0; 988 return 0;
949 } 989 }
950 } 990 }
951 } 991 }
952 992
953 FilePath::StringType FilePath::GetHFSDecomposedForm(const StringType& string) { 993 StringType FilePath::GetHFSDecomposedForm(const StringType& string) {
954 scoped_cftyperef<CFStringRef> cfstring( 994 scoped_cftyperef<CFStringRef> cfstring(
955 CFStringCreateWithBytesNoCopy( 995 CFStringCreateWithBytesNoCopy(
956 NULL, 996 NULL,
957 reinterpret_cast<const UInt8*>(string.c_str()), 997 reinterpret_cast<const UInt8*>(string.c_str()),
958 string.length(), 998 string.length(),
959 kCFStringEncodingUTF8, 999 kCFStringEncodingUTF8,
960 false, 1000 false,
961 kCFAllocatorNull)); 1001 kCFAllocatorNull));
962 // Query the maximum length needed to store the result. In most cases this 1002 // Query the maximum length needed to store the result. In most cases this
963 // will overestimate the required space. The return value also already 1003 // will overestimate the required space. The return value also already
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 1104
1065 FilePath FilePath::StripTrailingSeparators() const { 1105 FilePath FilePath::StripTrailingSeparators() const {
1066 FilePath new_path(path_); 1106 FilePath new_path(path_);
1067 new_path.StripTrailingSeparatorsInternal(); 1107 new_path.StripTrailingSeparatorsInternal();
1068 1108
1069 return new_path; 1109 return new_path;
1070 } 1110 }
1071 1111
1072 // static. 1112 // static.
1073 void FilePath::WriteStringTypeToPickle(Pickle* pickle, 1113 void FilePath::WriteStringTypeToPickle(Pickle* pickle,
1074 const FilePath::StringType& path) { 1114 const StringType& path) {
1075 #if defined(WCHAR_T_IS_UTF16) 1115 #if defined(WCHAR_T_IS_UTF16)
1076 pickle->WriteWString(path); 1116 pickle->WriteWString(path);
1077 #elif defined(WCHAR_T_IS_UTF32) 1117 #elif defined(WCHAR_T_IS_UTF32)
1078 pickle->WriteString(path); 1118 pickle->WriteString(path);
1079 #else 1119 #else
1080 NOTIMPLEMENTED() << "Impossible encoding situation!"; 1120 NOTIMPLEMENTED() << "Impossible encoding situation!";
1081 #endif 1121 #endif
1082 } 1122 }
1083 1123
1084 // static. 1124 // static.
1085 bool FilePath::ReadStringTypeFromPickle(Pickle* pickle, void** iter, 1125 bool FilePath::ReadStringTypeFromPickle(Pickle* pickle, void** iter,
1086 FilePath::StringType* path) { 1126 StringType* path) {
1087 #if defined(WCHAR_T_IS_UTF16) 1127 #if defined(WCHAR_T_IS_UTF16)
1088 if (!pickle->ReadWString(iter, path)) 1128 if (!pickle->ReadWString(iter, path))
1089 return false; 1129 return false;
1090 #elif defined(WCHAR_T_IS_UTF32) 1130 #elif defined(WCHAR_T_IS_UTF32)
1091 if (!pickle->ReadString(iter, path)) 1131 if (!pickle->ReadString(iter, path))
1092 return false; 1132 return false;
1093 #else 1133 #else
1094 NOTIMPLEMENTED() << "Impossible encoding situation!"; 1134 NOTIMPLEMENTED() << "Impossible encoding situation!";
1095 return false; 1135 return false;
1096 #endif 1136 #endif
(...skipping 25 matching lines...) Expand all
1122 // don't strip them, unless the string began with more than two separators. 1162 // don't strip them, unless the string began with more than two separators.
1123 if (pos != start + 1 || last_stripped == start + 2 || 1163 if (pos != start + 1 || last_stripped == start + 2 ||
1124 !IsSeparator(path_[start - 1])) { 1164 !IsSeparator(path_[start - 1])) {
1125 path_.resize(pos - 1); 1165 path_.resize(pos - 1);
1126 last_stripped = pos; 1166 last_stripped = pos;
1127 } 1167 }
1128 } 1168 }
1129 } 1169 }
1130 1170
1131 bool FilePath::ReferencesParent() const { 1171 bool FilePath::ReferencesParent() const {
1132 std::vector<FilePath::StringType> components; 1172 std::vector<StringType> components;
1133 GetComponents(&components); 1173 GetComponents(&components);
1134 1174
1135 std::vector<FilePath::StringType>::const_iterator it = components.begin(); 1175 std::vector<StringType>::const_iterator it = components.begin();
1136 for (; it != components.end(); ++it) { 1176 for (; it != components.end(); ++it) {
1137 const FilePath::StringType& component = *it; 1177 const StringType& component = *it;
1138 if (component == kParentDirectory) 1178 if (component == kParentDirectory)
1139 return true; 1179 return true;
1140 } 1180 }
1141 return false; 1181 return false;
1142 } 1182 }
1143 1183
1144 #if defined(FILE_PATH_USES_WIN_SEPARATORS) 1184 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
1145 FilePath FilePath::NormalizeWindowsPathSeparators() const { 1185 FilePath FilePath::NormalizeWindowsPathSeparators() const {
1146 StringType copy = path_; 1186 StringType copy = path_;
1147 for (size_t i = 1; i < arraysize(kSeparators); ++i) { 1187 for (size_t i = 1; i < arraysize(kSeparators); ++i) {
1148 std::replace(copy.begin(), copy.end(), kSeparators[i], kSeparators[0]); 1188 std::replace(copy.begin(), copy.end(), kSeparators[i], kSeparators[0]);
1149 } 1189 }
1150 return FilePath(copy); 1190 return FilePath(copy);
1151 } 1191 }
1152 #endif 1192 #endif
OLDNEW
« no previous file with comments | « no previous file | base/file_path_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698