| Index: base/file_path.cc
|
| ===================================================================
|
| --- base/file_path.cc (revision 6311)
|
| +++ base/file_path.cc (working copy)
|
| @@ -3,6 +3,7 @@
|
| // found in the LICENSE file.
|
|
|
| #include "base/file_path.h"
|
| +#include "base/logging.h"
|
|
|
| // These includes are just for the *Hack functions, and should be removed
|
| // when those functions are removed.
|
| @@ -18,6 +19,48 @@
|
| const FilePath::CharType FilePath::kCurrentDirectory[] = FILE_PATH_LITERAL(".");
|
| const FilePath::CharType FilePath::kParentDirectory[] = FILE_PATH_LITERAL("..");
|
|
|
| +namespace {
|
| +
|
| +// If this FilePath contains a drive letter specification, returns the
|
| +// position of the last character of the drive letter specification,
|
| +// otherwise returns npos. This can only be true on Windows, when a pathname
|
| +// begins with a letter followed by a colon. On other platforms, this always
|
| +// returns npos.
|
| +FilePath::StringType::size_type FindDriveLetter(
|
| + const FilePath::StringType& path) {
|
| +#if defined(FILE_PATH_USES_DRIVE_LETTERS)
|
| + // This is dependent on an ASCII-based character set, but that's a
|
| + // reasonable assumption. iswalpha can be too inclusive here.
|
| + if (path.length() >= 2 && path[1] == L':' &&
|
| + ((path[0] >= L'A' && path[0] <= L'Z') ||
|
| + (path[0] >= L'a' && path[0] <= L'z'))) {
|
| + return 1;
|
| + }
|
| + return FilePath::StringType::npos;
|
| +#else // FILE_PATH_USES_DRIVE_LETTERS
|
| + return FilePath::StringType::npos;
|
| +#endif // FILE_PATH_USES_DRIVE_LETTERS
|
| +}
|
| +
|
| +bool IsPathAbsolute(const FilePath::StringType& path) {
|
| +#if defined(FILE_PATH_USES_DRIVE_LETTERS)
|
| + FilePath::StringType::size_type letter = FindDriveLetter(path);
|
| + if (letter != FilePath::StringType::npos) {
|
| + // Look for a separator right after the drive specification.
|
| + return path.length() > letter + 1 &&
|
| + FilePath::IsSeparator(path[letter + 1]);
|
| + }
|
| + // Look for a pair of leading separators.
|
| + return path.length() > 1 &&
|
| + FilePath::IsSeparator(path[0]) && FilePath::IsSeparator(path[1]);
|
| +#else // FILE_PATH_USES_DRIVE_LETTERS
|
| + // Look for a separator in the first position.
|
| + return path.length() > 0 && FilePath::IsSeparator(path[0]);
|
| +#endif // FILE_PATH_USES_DRIVE_LETTERS
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| bool FilePath::IsSeparator(CharType character) {
|
| for (size_t i = 0; i < arraysize(kSeparators) - 1; ++i) {
|
| if (character == kSeparators[i]) {
|
| @@ -40,7 +83,7 @@
|
| // is no drive letter, as will always be the case on platforms which do not
|
| // support drive letters, letter will be npos, or -1, so the comparisons and
|
| // resizes below using letter will still be valid.
|
| - StringType::size_type letter = new_path.FindDriveLetter();
|
| + StringType::size_type letter = FindDriveLetter(new_path.path_);
|
|
|
| StringType::size_type last_separator =
|
| new_path.path_.find_last_of(kSeparators, StringType::npos,
|
| @@ -73,7 +116,7 @@
|
| new_path.StripTrailingSeparators();
|
|
|
| // The drive letter, if any, is always stripped.
|
| - StringType::size_type letter = new_path.FindDriveLetter();
|
| + StringType::size_type letter = FindDriveLetter(new_path.path_);
|
| if (letter != StringType::npos) {
|
| new_path.path_.erase(0, letter + 1);
|
| }
|
| @@ -92,6 +135,7 @@
|
| }
|
|
|
| FilePath FilePath::Append(const FilePath::StringType& component) const {
|
| + DCHECK(!IsPathAbsolute(component));
|
| if (path_.compare(kCurrentDirectory) == 0) {
|
| // Append normally doesn't do any normalization, but as a special case,
|
| // when appending to kCurrentDirectory, just return a new path for the
|
| @@ -116,7 +160,7 @@
|
| if (!IsSeparator(new_path.path_[new_path.path_.length() - 1])) {
|
|
|
| // Don't append a separator if the path is just a drive letter.
|
| - if (new_path.FindDriveLetter() + 1 != new_path.path_.length()) {
|
| + if (FindDriveLetter(new_path.path_) + 1 != new_path.path_.length()) {
|
| new_path.path_.append(1, kSeparators[0]);
|
| }
|
| }
|
| @@ -126,34 +170,12 @@
|
| return new_path;
|
| }
|
|
|
| -FilePath::StringType::size_type FilePath::FindDriveLetter() const {
|
| -#if defined(FILE_PATH_USES_DRIVE_LETTERS)
|
| - // This is dependent on an ASCII-based character set, but that's a
|
| - // reasonable assumption. iswalpha can be too inclusive here.
|
| - if (path_.length() >= 2 && path_[1] == L':' &&
|
| - ((path_[0] >= L'A' && path_[0] <= L'Z') ||
|
| - (path_[0] >= L'a' && path_[0] <= L'z'))) {
|
| - return 1;
|
| - }
|
| - return StringType::npos;
|
| -#else // FILE_PATH_USES_DRIVE_LETTERS
|
| - return StringType::npos;
|
| -#endif // FILE_PATH_USES_DRIVE_LETTERS
|
| +FilePath FilePath::Append(const FilePath& component) const {
|
| + return Append(component.value());
|
| }
|
|
|
| bool FilePath::IsAbsolute() const {
|
| -#if defined(FILE_PATH_USES_DRIVE_LETTERS)
|
| - StringType::size_type letter = FindDriveLetter();
|
| - if (letter != StringType::npos) {
|
| - // Look for a separator right after the drive specification.
|
| - return path_.length() > letter + 1 && IsSeparator(path_[letter + 1]);
|
| - }
|
| - // Look for a pair of leading separators.
|
| - return path_.length() > 1 && IsSeparator(path_[0]) && IsSeparator(path_[1]);
|
| -#else // FILE_PATH_USES_DRIVE_LETTERS
|
| - // Look for a separator in the first position.
|
| - return path_.length() > 0 && IsSeparator(path_[0]);
|
| -#endif // FILE_PATH_USES_DRIVE_LETTERS
|
| + return IsPathAbsolute(path_);
|
| }
|
|
|
| #if defined(OS_POSIX)
|
| @@ -185,7 +207,7 @@
|
| // letter, start will be set appropriately to prevent stripping the first
|
| // separator following the drive letter, if a separator immediately follows
|
| // the drive letter.
|
| - StringType::size_type start = FindDriveLetter() + 2;
|
| + StringType::size_type start = FindDriveLetter(path_) + 2;
|
|
|
| StringType::size_type last_stripped = StringType::npos;
|
| for (StringType::size_type pos = path_.length();
|
|
|