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 26 matching lines...) Expand all Loading... |
37 | 37 |
38 const FilePath::CharType FilePath::kCurrentDirectory[] = FILE_PATH_LITERAL("."); | 38 const FilePath::CharType FilePath::kCurrentDirectory[] = FILE_PATH_LITERAL("."); |
39 const FilePath::CharType FilePath::kParentDirectory[] = FILE_PATH_LITERAL(".."); | 39 const FilePath::CharType FilePath::kParentDirectory[] = FILE_PATH_LITERAL(".."); |
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* kCommonDoubleExtensions[] = { "gz", "z", "bz2" }; | 47 const char* kCommonDoubleExtensionSuffixes[] = { "gz", "z", "bz2" }; |
| 48 const char* kCommonDoubleExtensions[] = { "user.js" }; |
48 | 49 |
49 // If this FilePath contains a drive letter specification, returns the | 50 // If this FilePath contains a drive letter specification, returns the |
50 // position of the last character of the drive letter specification, | 51 // position of the last character of the drive letter specification, |
51 // otherwise returns npos. This can only be true on Windows, when a pathname | 52 // otherwise returns npos. This can only be true on Windows, when a pathname |
52 // begins with a letter followed by a colon. On other platforms, this always | 53 // begins with a letter followed by a colon. On other platforms, this always |
53 // returns npos. | 54 // returns npos. |
54 StringType::size_type FindDriveLetter(const StringType& path) { | 55 StringType::size_type FindDriveLetter(const StringType& path) { |
55 #if defined(FILE_PATH_USES_DRIVE_LETTERS) | 56 #if defined(FILE_PATH_USES_DRIVE_LETTERS) |
56 // This is dependent on an ASCII-based character set, but that's a | 57 // This is dependent on an ASCII-based character set, but that's a |
57 // reasonable assumption. iswalpha can be too inclusive here. | 58 // reasonable assumption. iswalpha can be too inclusive here. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 if (path == FilePath::kCurrentDirectory || path == FilePath::kParentDirectory) | 124 if (path == FilePath::kCurrentDirectory || path == FilePath::kParentDirectory) |
124 return StringType::npos; | 125 return StringType::npos; |
125 | 126 |
126 const StringType::size_type last_dot = | 127 const StringType::size_type last_dot = |
127 path.rfind(FilePath::kExtensionSeparator); | 128 path.rfind(FilePath::kExtensionSeparator); |
128 | 129 |
129 // No extension, or the extension is the whole filename. | 130 // No extension, or the extension is the whole filename. |
130 if (last_dot == StringType::npos || last_dot == 0U) | 131 if (last_dot == StringType::npos || last_dot == 0U) |
131 return last_dot; | 132 return last_dot; |
132 | 133 |
133 // Special case .<extension1>.<extension2>, but only if the final extension | |
134 // is one of a few common double extensions. | |
135 StringType extension(path, last_dot + 1); | |
136 bool is_common_double_extension = false; | |
137 for (size_t i = 0; i < arraysize(kCommonDoubleExtensions); ++i) { | |
138 if (LowerCaseEqualsASCII(extension, kCommonDoubleExtensions[i])) | |
139 is_common_double_extension = true; | |
140 } | |
141 if (!is_common_double_extension) | |
142 return last_dot; | |
143 | |
144 // Check that <extension1> is 1-4 characters, otherwise fall back to | |
145 // <extension2>. | |
146 const StringType::size_type penultimate_dot = | 134 const StringType::size_type penultimate_dot = |
147 path.rfind(FilePath::kExtensionSeparator, last_dot - 1); | 135 path.rfind(FilePath::kExtensionSeparator, last_dot - 1); |
148 const StringType::size_type last_separator = | 136 const StringType::size_type last_separator = |
149 path.find_last_of(FilePath::kSeparators, last_dot - 1, | 137 path.find_last_of(FilePath::kSeparators, last_dot - 1, |
150 arraysize(FilePath::kSeparators) - 1); | 138 arraysize(FilePath::kSeparators) - 1); |
151 if (penultimate_dot != StringType::npos && | 139 |
152 (last_separator == StringType::npos || | 140 if (penultimate_dot == StringType::npos || |
153 penultimate_dot > last_separator) && | 141 (last_separator != StringType::npos && |
154 last_dot - penultimate_dot <= 5U && | 142 penultimate_dot < last_separator)) { |
155 last_dot - penultimate_dot > 1U) { | 143 return last_dot; |
156 return penultimate_dot; | 144 } |
| 145 |
| 146 for (size_t i = 0; i < arraysize(kCommonDoubleExtensions); ++i) { |
| 147 StringType extension(path, penultimate_dot + 1); |
| 148 if (LowerCaseEqualsASCII(extension, kCommonDoubleExtensions[i])) |
| 149 return penultimate_dot; |
| 150 } |
| 151 |
| 152 StringType extension(path, last_dot + 1); |
| 153 for (size_t i = 0; i < arraysize(kCommonDoubleExtensionSuffixes); ++i) { |
| 154 if (LowerCaseEqualsASCII(extension, kCommonDoubleExtensionSuffixes[i])) { |
| 155 if ((last_dot - penultimate_dot) <= 5U && |
| 156 (last_dot - penultimate_dot) > 1U) { |
| 157 return penultimate_dot; |
| 158 } |
| 159 } |
157 } | 160 } |
158 | 161 |
159 return last_dot; | 162 return last_dot; |
160 } | 163 } |
161 | 164 |
162 // Returns true if path is "", ".", or "..". | 165 // Returns true if path is "", ".", or "..". |
163 bool IsEmptyOrSpecialCase(const StringType& path) { | 166 bool IsEmptyOrSpecialCase(const StringType& path) { |
164 // Special cases "", ".", and ".." | 167 // Special cases "", ".", and ".." |
165 if (path.empty() || path == FilePath::kCurrentDirectory || | 168 if (path.empty() || path == FilePath::kCurrentDirectory || |
166 path == FilePath::kParentDirectory) { | 169 path == FilePath::kParentDirectory) { |
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1222 #if defined(FILE_PATH_USES_WIN_SEPARATORS) | 1225 #if defined(FILE_PATH_USES_WIN_SEPARATORS) |
1223 StringType copy = path_; | 1226 StringType copy = path_; |
1224 for (size_t i = 1; i < arraysize(kSeparators); ++i) { | 1227 for (size_t i = 1; i < arraysize(kSeparators); ++i) { |
1225 std::replace(copy.begin(), copy.end(), kSeparators[i], kSeparators[0]); | 1228 std::replace(copy.begin(), copy.end(), kSeparators[i], kSeparators[0]); |
1226 } | 1229 } |
1227 return FilePath(copy); | 1230 return FilePath(copy); |
1228 #else | 1231 #else |
1229 return *this; | 1232 return *this; |
1230 #endif | 1233 #endif |
1231 } | 1234 } |
OLD | NEW |