| 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 |