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/files/file_path.h" | 5 #include "base/files/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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 it != input.end(); ++it) { | 100 it != input.end(); ++it) { |
101 if (!FilePath::IsSeparator(*it)) | 101 if (!FilePath::IsSeparator(*it)) |
102 return false; | 102 return false; |
103 } | 103 } |
104 | 104 |
105 return true; | 105 return true; |
106 } | 106 } |
107 | 107 |
108 // Find the position of the '.' that separates the extension from the rest | 108 // Find the position of the '.' that separates the extension from the rest |
109 // of the file name. The position is relative to BaseName(), not value(). | 109 // of the file name. The position is relative to BaseName(), not value(). |
110 // This allows a second extension component of up to 4 characters when the | 110 // Returns npos if it can't find an extension. |
111 // rightmost extension component is a common double extension (gz, bz2, Z). | 111 StringType::size_type FinalExtensionSeparatorPosition(const StringType& path) { |
112 // For example, foo.tar.gz or foo.tar.Z would have extension components of | |
113 // '.tar.gz' and '.tar.Z' respectively. Returns npos if it can't find an | |
114 // extension. | |
115 StringType::size_type ExtensionSeparatorPosition(const StringType& path) { | |
116 // Special case "." and ".." | 112 // Special case "." and ".." |
117 if (path == FilePath::kCurrentDirectory || path == FilePath::kParentDirectory) | 113 if (path == FilePath::kCurrentDirectory || path == FilePath::kParentDirectory) |
118 return StringType::npos; | 114 return StringType::npos; |
119 | 115 |
120 const StringType::size_type last_dot = | 116 return path.rfind(FilePath::kExtensionSeparator); |
121 path.rfind(FilePath::kExtensionSeparator); | 117 } |
| 118 |
| 119 // Same as above, but allow a second extension component of up to 4 |
| 120 // characters when the rightmost extension component is a common double |
| 121 // extension (gz, bz2, Z). For example, foo.tar.gz or foo.tar.Z would have |
| 122 // extension components of '.tar.gz' and '.tar.Z' respectively. |
| 123 StringType::size_type ExtensionSeparatorPosition(const StringType& path) { |
| 124 const StringType::size_type last_dot = FinalExtensionSeparatorPosition(path); |
122 | 125 |
123 // No extension, or the extension is the whole filename. | 126 // No extension, or the extension is the whole filename. |
124 if (last_dot == StringType::npos || last_dot == 0U) | 127 if (last_dot == StringType::npos || last_dot == 0U) |
125 return last_dot; | 128 return last_dot; |
126 | 129 |
127 const StringType::size_type penultimate_dot = | 130 const StringType::size_type penultimate_dot = |
128 path.rfind(FilePath::kExtensionSeparator, last_dot - 1); | 131 path.rfind(FilePath::kExtensionSeparator, last_dot - 1); |
129 const StringType::size_type last_separator = | 132 const StringType::size_type last_separator = |
130 path.find_last_of(FilePath::kSeparators, last_dot - 1, | 133 path.find_last_of(FilePath::kSeparators, last_dot - 1, |
131 FilePath::kSeparatorsLength - 1); | 134 FilePath::kSeparatorsLength - 1); |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 | 366 |
364 StringType FilePath::Extension() const { | 367 StringType FilePath::Extension() const { |
365 FilePath base(BaseName()); | 368 FilePath base(BaseName()); |
366 const StringType::size_type dot = ExtensionSeparatorPosition(base.path_); | 369 const StringType::size_type dot = ExtensionSeparatorPosition(base.path_); |
367 if (dot == StringType::npos) | 370 if (dot == StringType::npos) |
368 return StringType(); | 371 return StringType(); |
369 | 372 |
370 return base.path_.substr(dot, StringType::npos); | 373 return base.path_.substr(dot, StringType::npos); |
371 } | 374 } |
372 | 375 |
| 376 StringType FilePath::FinalExtension() const { |
| 377 FilePath base(BaseName()); |
| 378 const StringType::size_type dot = FinalExtensionSeparatorPosition(base.path_); |
| 379 if (dot == StringType::npos) |
| 380 return StringType(); |
| 381 |
| 382 return base.path_.substr(dot, StringType::npos); |
| 383 } |
| 384 |
373 FilePath FilePath::RemoveExtension() const { | 385 FilePath FilePath::RemoveExtension() const { |
374 if (Extension().empty()) | 386 if (Extension().empty()) |
375 return *this; | 387 return *this; |
376 | 388 |
377 const StringType::size_type dot = ExtensionSeparatorPosition(path_); | 389 const StringType::size_type dot = ExtensionSeparatorPosition(path_); |
378 if (dot == StringType::npos) | 390 if (dot == StringType::npos) |
379 return *this; | 391 return *this; |
380 | 392 |
381 return FilePath(path_.substr(0, dot)); | 393 return FilePath(path_.substr(0, dot)); |
382 } | 394 } |
383 | 395 |
| 396 FilePath FilePath::RemoveFinalExtension() const { |
| 397 if (FinalExtension().empty()) |
| 398 return *this; |
| 399 |
| 400 const StringType::size_type dot = FinalExtensionSeparatorPosition(path_); |
| 401 if (dot == StringType::npos) |
| 402 return *this; |
| 403 |
| 404 return FilePath(path_.substr(0, dot)); |
| 405 } |
| 406 |
384 FilePath FilePath::InsertBeforeExtension(const StringType& suffix) const { | 407 FilePath FilePath::InsertBeforeExtension(const StringType& suffix) const { |
385 if (suffix.empty()) | 408 if (suffix.empty()) |
386 return FilePath(path_); | 409 return FilePath(path_); |
387 | 410 |
388 if (IsEmptyOrSpecialCase(BaseName().value())) | 411 if (IsEmptyOrSpecialCase(BaseName().value())) |
389 return FilePath(); | 412 return FilePath(); |
390 | 413 |
391 StringType ext = Extension(); | 414 StringType ext = Extension(); |
392 StringType ret = RemoveExtension().value(); | 415 StringType ret = RemoveExtension().value(); |
393 ret.append(suffix); | 416 ret.append(suffix); |
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 bool FilePath::IsContentUri() const { | 1307 bool FilePath::IsContentUri() const { |
1285 return StartsWithASCII(path_, "content://", false /*case_sensitive*/); | 1308 return StartsWithASCII(path_, "content://", false /*case_sensitive*/); |
1286 } | 1309 } |
1287 #endif | 1310 #endif |
1288 | 1311 |
1289 } // namespace base | 1312 } // namespace base |
1290 | 1313 |
1291 void PrintTo(const base::FilePath& path, std::ostream* out) { | 1314 void PrintTo(const base::FilePath& path, std::ostream* out) { |
1292 *out << path.value(); | 1315 *out << path.value(); |
1293 } | 1316 } |
OLD | NEW |