Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include <string.h> | 7 #include <string.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 40 | 40 |
| 41 const FilePath::CharType FilePath::kExtensionSeparator = FILE_PATH_LITERAL('.'); | 41 const FilePath::CharType FilePath::kExtensionSeparator = FILE_PATH_LITERAL('.'); |
| 42 | 42 |
| 43 typedef FilePath::StringType StringType; | 43 typedef FilePath::StringType StringType; |
| 44 | 44 |
| 45 namespace { | 45 namespace { |
| 46 | 46 |
| 47 const char* kCommonDoubleExtensionSuffixes[] = { "gz", "z", "bz2" }; | 47 const char* kCommonDoubleExtensionSuffixes[] = { "gz", "z", "bz2" }; |
| 48 const char* kCommonDoubleExtensions[] = { "user.js" }; | 48 const char* kCommonDoubleExtensions[] = { "user.js" }; |
| 49 | 49 |
| 50 const FilePath::CharType kStringTerminator = FILE_PATH_LITERAL('\0'); | |
| 51 | |
| 50 // If this FilePath contains a drive letter specification, returns the | 52 // If this FilePath contains a drive letter specification, returns the |
| 51 // position of the last character of the drive letter specification, | 53 // position of the last character of the drive letter specification, |
| 52 // otherwise returns npos. This can only be true on Windows, when a pathname | 54 // otherwise returns npos. This can only be true on Windows, when a pathname |
| 53 // begins with a letter followed by a colon. On other platforms, this always | 55 // begins with a letter followed by a colon. On other platforms, this always |
| 54 // returns npos. | 56 // returns npos. |
| 55 StringType::size_type FindDriveLetter(const StringType& path) { | 57 StringType::size_type FindDriveLetter(const StringType& path) { |
| 56 #if defined(FILE_PATH_USES_DRIVE_LETTERS) | 58 #if defined(FILE_PATH_USES_DRIVE_LETTERS) |
| 57 // This is dependent on an ASCII-based character set, but that's a | 59 // This is dependent on an ASCII-based character set, but that's a |
| 58 // reasonable assumption. iswalpha can be too inclusive here. | 60 // reasonable assumption. iswalpha can be too inclusive here. |
| 59 if (path.length() >= 2 && path[1] == L':' && | 61 if (path.length() >= 2 && path[1] == L':' && |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 | 177 |
| 176 } // namespace | 178 } // namespace |
| 177 | 179 |
| 178 FilePath::FilePath() { | 180 FilePath::FilePath() { |
| 179 } | 181 } |
| 180 | 182 |
| 181 FilePath::FilePath(const FilePath& that) : path_(that.path_) { | 183 FilePath::FilePath(const FilePath& that) : path_(that.path_) { |
| 182 } | 184 } |
| 183 | 185 |
| 184 FilePath::FilePath(const StringType& path) : path_(path) { | 186 FilePath::FilePath(const StringType& path) : path_(path) { |
| 187 StringType::size_type nul_pos = path_.find(kStringTerminator); | |
| 188 if (nul_pos != StringType::npos) | |
| 189 path_.erase(nul_pos, StringType::npos); | |
| 185 } | 190 } |
| 186 | 191 |
| 187 FilePath::~FilePath() { | 192 FilePath::~FilePath() { |
| 188 } | 193 } |
| 189 | 194 |
| 190 FilePath& FilePath::operator=(const FilePath& that) { | 195 FilePath& FilePath::operator=(const FilePath& that) { |
| 191 path_ = that.path_; | 196 path_ = that.path_; |
| 192 return *this; | 197 return *this; |
| 193 } | 198 } |
| 194 | 199 |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 | 452 |
| 448 StringType current_extension = Extension(); | 453 StringType current_extension = Extension(); |
| 449 | 454 |
| 450 if (current_extension.length() != extension.length()) | 455 if (current_extension.length() != extension.length()) |
| 451 return false; | 456 return false; |
| 452 | 457 |
| 453 return FilePath::CompareEqualIgnoreCase(extension, current_extension); | 458 return FilePath::CompareEqualIgnoreCase(extension, current_extension); |
| 454 } | 459 } |
| 455 | 460 |
| 456 FilePath FilePath::Append(const StringType& component) const { | 461 FilePath FilePath::Append(const StringType& component) const { |
| 457 DCHECK(!IsPathAbsolute(component)); | 462 const StringType* appended = &component; |
| 463 StringType without_nuls; | |
| 464 | |
| 465 StringType::size_type nul_pos = component.find(kStringTerminator); | |
| 466 if (nul_pos != StringType::npos) { | |
| 467 without_nuls = component.substr(0, nul_pos); | |
| 468 appended = &without_nuls; | |
| 469 } | |
| 470 | |
| 471 DCHECK(!IsPathAbsolute(*appended)); | |
| 472 | |
| 458 if (path_.compare(kCurrentDirectory) == 0) { | 473 if (path_.compare(kCurrentDirectory) == 0) { |
| 459 // Append normally doesn't do any normalization, but as a special case, | 474 // Append normally doesn't do any normalization, but as a special case, |
| 460 // when appending to kCurrentDirectory, just return a new path for the | 475 // when appending to kCurrentDirectory, just return a new path for the |
| 461 // component argument. Appending component to kCurrentDirectory would | 476 // component argument. Appending component to kCurrentDirectory would |
| 462 // serve no purpose other than needlessly lengthening the path, and | 477 // serve no purpose other than needlessly lengthening the path, and |
| 463 // it's likely in practice to wind up with FilePath objects containing | 478 // it's likely in practice to wind up with FilePath objects containing |
| 464 // only kCurrentDirectory when calling DirName on a single relative path | 479 // only kCurrentDirectory when calling DirName on a single relative path |
| 465 // component. | 480 // component. |
| 466 return FilePath(component); | 481 return FilePath(*appended); |
| 467 } | 482 } |
| 468 | 483 |
| 469 FilePath new_path(path_); | 484 FilePath new_path(path_); |
| 470 new_path.StripTrailingSeparatorsInternal(); | 485 new_path.StripTrailingSeparatorsInternal(); |
| 471 | 486 |
| 472 // Don't append a separator if the path is empty (indicating the current | 487 // Don't append a separator if the path is empty (indicating the current |
| 473 // directory) or if the path component is empty (indicating nothing to | 488 // directory) or if the path component is empty (indicating nothing to |
| 474 // append). | 489 // append). |
| 475 if (component.length() > 0 && new_path.path_.length() > 0) { | 490 if (appended->length() > 0 && new_path.path_.length() > 0) { |
| 476 // Don't append a separator if the path still ends with a trailing | 491 // Don't append a separator if the path still ends with a trailing |
| 477 // separator after stripping (indicating the root directory). | 492 // separator after stripping (indicating the root directory). |
| 478 if (!IsSeparator(new_path.path_[new_path.path_.length() - 1])) { | 493 if (!IsSeparator(new_path.path_[new_path.path_.length() - 1])) { |
| 479 // Don't append a separator if the path is just a drive letter. | 494 // Don't append a separator if the path is just a drive letter. |
| 480 if (FindDriveLetter(new_path.path_) + 1 != new_path.path_.length()) { | 495 if (FindDriveLetter(new_path.path_) + 1 != new_path.path_.length()) { |
| 481 new_path.path_.append(1, kSeparators[0]); | 496 new_path.path_.append(1, kSeparators[0]); |
| 482 } | 497 } |
| 483 } | 498 } |
| 484 } | 499 } |
| 485 | 500 |
| 486 new_path.path_.append(component); | 501 new_path.path_.append(*appended); |
| 487 return new_path; | 502 return new_path; |
| 488 } | 503 } |
| 489 | 504 |
| 490 FilePath FilePath::Append(const FilePath& component) const { | 505 FilePath FilePath::Append(const FilePath& component) const { |
| 491 return Append(component.value()); | 506 return Append(component.value()); |
| 492 } | 507 } |
| 493 | 508 |
| 494 FilePath FilePath::AppendASCII(const base::StringPiece& component) const { | 509 FilePath FilePath::AppendASCII(const base::StringPiece& component) const { |
| 495 DCHECK(IsStringASCII(component)); | 510 DCHECK(IsStringASCII(component)); |
| 496 #if defined(OS_WIN) | 511 #if defined(OS_WIN) |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 599 | 614 |
| 600 bool FilePath::ReadFromPickle(PickleIterator* iter) { | 615 bool FilePath::ReadFromPickle(PickleIterator* iter) { |
| 601 #if defined(OS_WIN) | 616 #if defined(OS_WIN) |
| 602 if (!iter->ReadString16(&path_)) | 617 if (!iter->ReadString16(&path_)) |
| 603 return false; | 618 return false; |
| 604 #else | 619 #else |
| 605 if (!iter->ReadString(&path_)) | 620 if (!iter->ReadString(&path_)) |
| 606 return false; | 621 return false; |
| 607 #endif | 622 #endif |
| 608 | 623 |
| 624 if (path_.find(kStringTerminator) != StringType::npos) | |
| 625 return false; | |
|
Chris Evans
2013/01/23 10:34:06
Cleanup: the logic in here is now the same as Para
| |
| 626 | |
| 609 return true; | 627 return true; |
| 610 } | 628 } |
| 611 | 629 |
| 612 #if defined(OS_WIN) | 630 #if defined(OS_WIN) |
| 613 // Windows specific implementation of file string comparisons | 631 // Windows specific implementation of file string comparisons |
| 614 | 632 |
| 615 int FilePath::CompareIgnoreCase(const StringType& string1, | 633 int FilePath::CompareIgnoreCase(const StringType& string1, |
| 616 const StringType& string2) { | 634 const StringType& string2) { |
| 617 // Perform character-wise upper case comparison rather than using the | 635 // Perform character-wise upper case comparison rather than using the |
| 618 // fully Unicode-aware CompareString(). For details see: | 636 // fully Unicode-aware CompareString(). For details see: |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1229 } | 1247 } |
| 1230 return FilePath(copy); | 1248 return FilePath(copy); |
| 1231 #else | 1249 #else |
| 1232 return *this; | 1250 return *this; |
| 1233 #endif | 1251 #endif |
| 1234 } | 1252 } |
| 1235 | 1253 |
| 1236 void PrintTo(const FilePath& path, std::ostream* out) { | 1254 void PrintTo(const FilePath& path, std::ostream* out) { |
| 1237 *out << path.value(); | 1255 *out << path.value(); |
| 1238 } | 1256 } |
| OLD | NEW |