| OLD | NEW | 
|---|
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 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 #include "base/logging.h" | 6 #include "base/logging.h" | 
| 7 | 7 | 
| 8 // These includes are just for the *Hack functions, and should be removed | 8 // These includes are just for the *Hack functions, and should be removed | 
| 9 // when those functions are removed. | 9 // when those functions are removed. | 
| 10 #include "base/string_piece.h" | 10 #include "base/string_piece.h" | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 70 | 70 | 
| 71   return false; | 71   return false; | 
| 72 } | 72 } | 
| 73 | 73 | 
| 74 // libgen's dirname and basename aren't guaranteed to be thread-safe and aren't | 74 // libgen's dirname and basename aren't guaranteed to be thread-safe and aren't | 
| 75 // guaranteed to not modify their input strings, and in fact are implmeneted | 75 // guaranteed to not modify their input strings, and in fact are implmeneted | 
| 76 // differently in this regard on different platforms.  Don't use them, but | 76 // differently in this regard on different platforms.  Don't use them, but | 
| 77 // adhere to their behavior. | 77 // adhere to their behavior. | 
| 78 FilePath FilePath::DirName() const { | 78 FilePath FilePath::DirName() const { | 
| 79   FilePath new_path(path_); | 79   FilePath new_path(path_); | 
| 80   new_path.StripTrailingSeparators(); | 80   new_path.StripTrailingSeparatorsInternal(); | 
| 81 | 81 | 
| 82   // The drive letter, if any, always needs to remain in the output.  If there | 82   // The drive letter, if any, always needs to remain in the output.  If there | 
| 83   // is no drive letter, as will always be the case on platforms which do not | 83   // is no drive letter, as will always be the case on platforms which do not | 
| 84   // support drive letters, letter will be npos, or -1, so the comparisons and | 84   // support drive letters, letter will be npos, or -1, so the comparisons and | 
| 85   // resizes below using letter will still be valid. | 85   // resizes below using letter will still be valid. | 
| 86   StringType::size_type letter = FindDriveLetter(new_path.path_); | 86   StringType::size_type letter = FindDriveLetter(new_path.path_); | 
| 87 | 87 | 
| 88   StringType::size_type last_separator = | 88   StringType::size_type last_separator = | 
| 89       new_path.path_.find_last_of(kSeparators, StringType::npos, | 89       new_path.path_.find_last_of(kSeparators, StringType::npos, | 
| 90                                   arraysize(kSeparators) - 1); | 90                                   arraysize(kSeparators) - 1); | 
| 91   if (last_separator == StringType::npos) { | 91   if (last_separator == StringType::npos) { | 
| 92     // path_ is in the current directory. | 92     // path_ is in the current directory. | 
| 93     new_path.path_.resize(letter + 1); | 93     new_path.path_.resize(letter + 1); | 
| 94   } else if (last_separator == letter + 1) { | 94   } else if (last_separator == letter + 1) { | 
| 95     // path_ is in the root directory. | 95     // path_ is in the root directory. | 
| 96     new_path.path_.resize(letter + 2); | 96     new_path.path_.resize(letter + 2); | 
| 97   } else if (last_separator == letter + 2 && | 97   } else if (last_separator == letter + 2 && | 
| 98              IsSeparator(new_path.path_[letter + 1])) { | 98              IsSeparator(new_path.path_[letter + 1])) { | 
| 99     // path_ is in "//" (possibly with a drive letter); leave the double | 99     // path_ is in "//" (possibly with a drive letter); leave the double | 
| 100     // separator intact indicating alternate root. | 100     // separator intact indicating alternate root. | 
| 101     new_path.path_.resize(letter + 3); | 101     new_path.path_.resize(letter + 3); | 
| 102   } else if (last_separator != 0) { | 102   } else if (last_separator != 0) { | 
| 103     // path_ is somewhere else, trim the basename. | 103     // path_ is somewhere else, trim the basename. | 
| 104     new_path.path_.resize(last_separator); | 104     new_path.path_.resize(last_separator); | 
| 105   } | 105   } | 
| 106 | 106 | 
| 107   new_path.StripTrailingSeparators(); | 107   new_path.StripTrailingSeparatorsInternal(); | 
| 108   if (!new_path.path_.length()) | 108   if (!new_path.path_.length()) | 
| 109     new_path.path_ = kCurrentDirectory; | 109     new_path.path_ = kCurrentDirectory; | 
| 110 | 110 | 
| 111   return new_path; | 111   return new_path; | 
| 112 } | 112 } | 
| 113 | 113 | 
| 114 FilePath FilePath::BaseName() const { | 114 FilePath FilePath::BaseName() const { | 
| 115   FilePath new_path(path_); | 115   FilePath new_path(path_); | 
| 116   new_path.StripTrailingSeparators(); | 116   new_path.StripTrailingSeparatorsInternal(); | 
| 117 | 117 | 
| 118   // The drive letter, if any, is always stripped. | 118   // The drive letter, if any, is always stripped. | 
| 119   StringType::size_type letter = FindDriveLetter(new_path.path_); | 119   StringType::size_type letter = FindDriveLetter(new_path.path_); | 
| 120   if (letter != StringType::npos) { | 120   if (letter != StringType::npos) { | 
| 121     new_path.path_.erase(0, letter + 1); | 121     new_path.path_.erase(0, letter + 1); | 
| 122   } | 122   } | 
| 123 | 123 | 
| 124   // Keep everything after the final separator, but if the pathname is only | 124   // Keep everything after the final separator, but if the pathname is only | 
| 125   // one character and it's a separator, leave it alone. | 125   // one character and it's a separator, leave it alone. | 
| 126   StringType::size_type last_separator = | 126   StringType::size_type last_separator = | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 141     // when appending to kCurrentDirectory, just return a new path for the | 141     // when appending to kCurrentDirectory, just return a new path for the | 
| 142     // component argument.  Appending component to kCurrentDirectory would | 142     // component argument.  Appending component to kCurrentDirectory would | 
| 143     // serve no purpose other than needlessly lengthening the path, and | 143     // serve no purpose other than needlessly lengthening the path, and | 
| 144     // it's likely in practice to wind up with FilePath objects containing | 144     // it's likely in practice to wind up with FilePath objects containing | 
| 145     // only kCurrentDirectory when calling DirName on a single relative path | 145     // only kCurrentDirectory when calling DirName on a single relative path | 
| 146     // component. | 146     // component. | 
| 147     return FilePath(component); | 147     return FilePath(component); | 
| 148   } | 148   } | 
| 149 | 149 | 
| 150   FilePath new_path(path_); | 150   FilePath new_path(path_); | 
| 151   new_path.StripTrailingSeparators(); | 151   new_path.StripTrailingSeparatorsInternal(); | 
| 152 | 152 | 
| 153   // Don't append a separator if the path is empty (indicating the current | 153   // Don't append a separator if the path is empty (indicating the current | 
| 154   // directory) or if the path component is empty (indicating nothing to | 154   // directory) or if the path component is empty (indicating nothing to | 
| 155   // append). | 155   // append). | 
| 156   if (component.length() > 0 && new_path.path_.length() > 0) { | 156   if (component.length() > 0 && new_path.path_.length() > 0) { | 
| 157 | 157 | 
| 158     // Don't append a separator if the path still ends with a trailing | 158     // Don't append a separator if the path still ends with a trailing | 
| 159     // separator after stripping (indicating the root directory). | 159     // separator after stripping (indicating the root directory). | 
| 160     if (!IsSeparator(new_path.path_[new_path.path_.length() - 1])) { | 160     if (!IsSeparator(new_path.path_[new_path.path_.length() - 1])) { | 
| 161 | 161 | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 194 #elif defined(OS_WIN) | 194 #elif defined(OS_WIN) | 
| 195 // static | 195 // static | 
| 196 FilePath FilePath::FromWStringHack(const std::wstring& wstring) { | 196 FilePath FilePath::FromWStringHack(const std::wstring& wstring) { | 
| 197   return FilePath(wstring); | 197   return FilePath(wstring); | 
| 198 } | 198 } | 
| 199 std::wstring FilePath::ToWStringHack() const { | 199 std::wstring FilePath::ToWStringHack() const { | 
| 200   return path_; | 200   return path_; | 
| 201 } | 201 } | 
| 202 #endif | 202 #endif | 
| 203 | 203 | 
| 204 void FilePath::StripTrailingSeparators() { | 204 FilePath FilePath::StripTrailingSeparators() const { | 
|  | 205   FilePath new_path(path_); | 
|  | 206   new_path.StripTrailingSeparatorsInternal(); | 
|  | 207 | 
|  | 208   return new_path; | 
|  | 209 } | 
|  | 210 | 
|  | 211 void FilePath::StripTrailingSeparatorsInternal() { | 
| 205   // If there is no drive letter, start will be 1, which will prevent stripping | 212   // If there is no drive letter, start will be 1, which will prevent stripping | 
| 206   // the leading separator if there is only one separator.  If there is a drive | 213   // the leading separator if there is only one separator.  If there is a drive | 
| 207   // letter, start will be set appropriately to prevent stripping the first | 214   // letter, start will be set appropriately to prevent stripping the first | 
| 208   // separator following the drive letter, if a separator immediately follows | 215   // separator following the drive letter, if a separator immediately follows | 
| 209   // the drive letter. | 216   // the drive letter. | 
| 210   StringType::size_type start = FindDriveLetter(path_) + 2; | 217   StringType::size_type start = FindDriveLetter(path_) + 2; | 
| 211 | 218 | 
| 212   StringType::size_type last_stripped = StringType::npos; | 219   StringType::size_type last_stripped = StringType::npos; | 
| 213   for (StringType::size_type pos = path_.length(); | 220   for (StringType::size_type pos = path_.length(); | 
| 214        pos > start && IsSeparator(path_[pos - 1]); | 221        pos > start && IsSeparator(path_[pos - 1]); | 
| 215        --pos) { | 222        --pos) { | 
| 216     // If the string only has two separators and they're at the beginning, | 223     // If the string only has two separators and they're at the beginning, | 
| 217     // don't strip them, unless the string began with more than two separators. | 224     // don't strip them, unless the string began with more than two separators. | 
| 218     if (pos != start + 1 || last_stripped == start + 2 || | 225     if (pos != start + 1 || last_stripped == start + 2 || | 
| 219         !IsSeparator(path_[start - 1])) { | 226         !IsSeparator(path_[start - 1])) { | 
| 220       path_.resize(pos - 1); | 227       path_.resize(pos - 1); | 
| 221       last_stripped = pos; | 228       last_stripped = pos; | 
| 222     } | 229     } | 
| 223   } | 230   } | 
| 224 } | 231 } | 
| OLD | NEW | 
|---|