Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2008 The Chromium Authors. All rights reserved. | 1 // Copyright 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/files/file_path.h" | 5 #include "base/files/file_path.h" |
| 6 | 6 |
| 7 #include <ctype.h> | 7 #include <ctype.h> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 | 11 |
| 12 namespace base { | 12 namespace base { |
| 13 | 13 |
| 14 #if defined(FILE_PATH_USES_WIN_SEPARATORS) | 14 #if defined(FILE_PATH_USES_WIN_SEPARATORS) |
| 15 const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("\\/"); | 15 const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("\\/"); |
| 16 #else // FILE_PATH_USES_WIN_SEPARATORS | 16 #else // FILE_PATH_USES_WIN_SEPARATORS |
| 17 const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("/"); | 17 const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("/"); |
| 18 #endif // FILE_PATH_USES_WIN_SEPARATORS | 18 #endif // FILE_PATH_USES_WIN_SEPARATORS |
| 19 | 19 |
| 20 const FilePath::CharType FilePath::kCurrentDirectory[] = FILE_PATH_LITERAL("."); | 20 const FilePath::CharType FilePath::kCurrentDirectory[] = FILE_PATH_LITERAL("."); |
| 21 const FilePath::CharType FilePath::kParentDirectory[] = FILE_PATH_LITERAL(".."); | |
| 22 const FilePath::CharType FilePath::kExtensionSeparator = FILE_PATH_LITERAL('.'); | |
| 21 | 23 |
| 22 typedef FilePath::StringType StringType; | 24 typedef FilePath::StringType StringType; |
| 23 | 25 |
| 24 namespace { | 26 namespace { |
| 25 | 27 |
| 26 const FilePath::CharType kStringTerminator = FILE_PATH_LITERAL('\0'); | 28 const FilePath::CharType kStringTerminator = FILE_PATH_LITERAL('\0'); |
| 27 | 29 |
| 28 // If this FilePath contains a drive letter specification, returns the | 30 // If this FilePath contains a drive letter specification, returns the |
| 29 // position of the last character of the drive letter specification, | 31 // position of the last character of the drive letter specification, |
| 30 // otherwise returns npos. This can only be true on Windows, when a pathname | 32 // otherwise returns npos. This can only be true on Windows, when a pathname |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 71 } | 73 } |
| 72 // Look for a pair of leading separators. | 74 // Look for a pair of leading separators. |
| 73 return path.length() > 1 && | 75 return path.length() > 1 && |
| 74 FilePath::IsSeparator(path[0]) && FilePath::IsSeparator(path[1]); | 76 FilePath::IsSeparator(path[0]) && FilePath::IsSeparator(path[1]); |
| 75 #else // FILE_PATH_USES_DRIVE_LETTERS | 77 #else // FILE_PATH_USES_DRIVE_LETTERS |
| 76 // Look for a separator in the first position. | 78 // Look for a separator in the first position. |
| 77 return path.length() > 0 && FilePath::IsSeparator(path[0]); | 79 return path.length() > 0 && FilePath::IsSeparator(path[0]); |
| 78 #endif // FILE_PATH_USES_DRIVE_LETTERS | 80 #endif // FILE_PATH_USES_DRIVE_LETTERS |
| 79 } | 81 } |
| 80 | 82 |
| 83 // Find the position of the '.' that separates the extension from the rest | |
| 84 // of the file name. The position is relative to BaseName(), not value(). | |
|
Mark Mentovai
2015/01/20 17:11:53
The second sentence should be harsher: this functi
scottmg
2015/01/20 18:01:27
After simplifying below, just deleted this functio
| |
| 85 // Returns npos if it can't find an extension. | |
| 86 StringType::size_type FinalExtensionSeparatorPosition(const StringType& path) { | |
| 87 // Special case "." and ".." | |
| 88 if (path == FilePath::kCurrentDirectory || path == FilePath::kParentDirectory) | |
| 89 return StringType::npos; | |
| 90 | |
| 91 return path.rfind(FilePath::kExtensionSeparator); | |
| 92 } | |
| 93 | |
| 81 } // namespace | 94 } // namespace |
| 82 | 95 |
| 83 FilePath::FilePath() { | 96 FilePath::FilePath() { |
| 84 } | 97 } |
| 85 | 98 |
| 86 FilePath::FilePath(const FilePath& that) : path_(that.path_) { | 99 FilePath::FilePath(const FilePath& that) : path_(that.path_) { |
| 87 } | 100 } |
| 88 | 101 |
| 89 FilePath::FilePath(const StringType& path) : path_(path) { | 102 FilePath::FilePath(const StringType& path) : path_(path) { |
| 90 StringType::size_type nul_pos = path_.find(kStringTerminator); | 103 StringType::size_type nul_pos = path_.find(kStringTerminator); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 183 new_path.path_.find_last_of(kSeparators, StringType::npos, | 196 new_path.path_.find_last_of(kSeparators, StringType::npos, |
| 184 arraysize(kSeparators) - 1); | 197 arraysize(kSeparators) - 1); |
| 185 if (last_separator != StringType::npos && | 198 if (last_separator != StringType::npos && |
| 186 last_separator < new_path.path_.length() - 1) { | 199 last_separator < new_path.path_.length() - 1) { |
| 187 new_path.path_.erase(0, last_separator + 1); | 200 new_path.path_.erase(0, last_separator + 1); |
| 188 } | 201 } |
| 189 | 202 |
| 190 return new_path; | 203 return new_path; |
| 191 } | 204 } |
| 192 | 205 |
| 206 StringType FilePath::FinalExtension() const { | |
| 207 FilePath base(BaseName()); | |
| 208 const StringType::size_type dot = FinalExtensionSeparatorPosition(base.path_); | |
| 209 if (dot == StringType::npos) | |
| 210 return StringType(); | |
| 211 | |
| 212 return base.path_.substr(dot, StringType::npos); | |
| 213 } | |
| 214 | |
| 215 FilePath FilePath::RemoveFinalExtension() const { | |
| 216 if (FinalExtension().empty()) | |
| 217 return *this; | |
| 218 | |
| 219 const StringType::size_type dot = FinalExtensionSeparatorPosition(path_); | |
|
Mark Mentovai
2015/01/20 17:11:53
This logic winds up calling FinalExtension() twice
scottmg
2015/01/20 18:01:27
Done.
| |
| 220 if (dot == StringType::npos) | |
| 221 return *this; | |
| 222 | |
| 223 return FilePath(path_.substr(0, dot)); | |
| 224 } | |
| 225 | |
| 193 FilePath FilePath::Append(const StringType& component) const { | 226 FilePath FilePath::Append(const StringType& component) const { |
| 194 const StringType* appended = &component; | 227 const StringType* appended = &component; |
| 195 StringType without_nuls; | 228 StringType without_nuls; |
| 196 | 229 |
| 197 StringType::size_type nul_pos = component.find(kStringTerminator); | 230 StringType::size_type nul_pos = component.find(kStringTerminator); |
| 198 if (nul_pos != StringType::npos) { | 231 if (nul_pos != StringType::npos) { |
| 199 without_nuls = component.substr(0, nul_pos); | 232 without_nuls = component.substr(0, nul_pos); |
| 200 appended = &without_nuls; | 233 appended = &without_nuls; |
| 201 } | 234 } |
| 202 | 235 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 262 last_stripped = pos; | 295 last_stripped = pos; |
| 263 } | 296 } |
| 264 } | 297 } |
| 265 } | 298 } |
| 266 | 299 |
| 267 } // namespace base | 300 } // namespace base |
| 268 | 301 |
| 269 void PrintTo(const base::FilePath& path, std::ostream* out) { | 302 void PrintTo(const base::FilePath& path, std::ostream* out) { |
| 270 *out << path.value().c_str(); | 303 *out << path.value().c_str(); |
| 271 } | 304 } |
| OLD | NEW |