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_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |