Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(924)

Side by Side Diff: base/file_path.cc

Issue 17243: Add implementations of various extension related methods (derived from file_u... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/file_path.h ('k') | base/file_path_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/file_util.h" 6 #include "base/file_util.h"
7 #include "base/logging.h" 7 #include "base/logging.h"
8 8
9 // These includes are just for the *Hack functions, and should be removed 9 // These includes are just for the *Hack functions, and should be removed
10 // when those functions are removed. 10 // when those functions are removed.
11 #include "base/string_piece.h" 11 #include "base/string_piece.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "base/sys_string_conversions.h" 13 #include "base/sys_string_conversions.h"
14 14
15 #if defined(FILE_PATH_USES_WIN_SEPARATORS) 15 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
16 const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("\\/"); 16 const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("\\/");
17 #else // FILE_PATH_USES_WIN_SEPARATORS 17 #else // FILE_PATH_USES_WIN_SEPARATORS
18 const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("/"); 18 const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("/");
19 #endif // FILE_PATH_USES_WIN_SEPARATORS 19 #endif // FILE_PATH_USES_WIN_SEPARATORS
20 20
21 const FilePath::CharType FilePath::kCurrentDirectory[] = FILE_PATH_LITERAL("."); 21 const FilePath::CharType FilePath::kCurrentDirectory[] = FILE_PATH_LITERAL(".");
22 const FilePath::CharType FilePath::kParentDirectory[] = FILE_PATH_LITERAL(".."); 22 const FilePath::CharType FilePath::kParentDirectory[] = FILE_PATH_LITERAL("..");
23 23
24 const FilePath::CharType FilePath::kExtensionSeparator = FILE_PATH_LITERAL('.');
25
26
24 namespace { 27 namespace {
25 28
26 // If this FilePath contains a drive letter specification, returns the 29 // If this FilePath contains a drive letter specification, returns the
27 // position of the last character of the drive letter specification, 30 // position of the last character of the drive letter specification,
28 // otherwise returns npos. This can only be true on Windows, when a pathname 31 // otherwise returns npos. This can only be true on Windows, when a pathname
29 // begins with a letter followed by a colon. On other platforms, this always 32 // begins with a letter followed by a colon. On other platforms, this always
30 // returns npos. 33 // returns npos.
31 FilePath::StringType::size_type FindDriveLetter( 34 FilePath::StringType::size_type FindDriveLetter(
32 const FilePath::StringType& path) { 35 const FilePath::StringType& path) {
33 #if defined(FILE_PATH_USES_DRIVE_LETTERS) 36 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
34 // This is dependent on an ASCII-based character set, but that's a 37 // This is dependent on an ASCII-based character set, but that's a
35 // reasonable assumption. iswalpha can be too inclusive here. 38 // reasonable assumption. iswalpha can be too inclusive here.
36 if (path.length() >= 2 && path[1] == L':' && 39 if (path.length() >= 2 && path[1] == L':' &&
37 ((path[0] >= L'A' && path[0] <= L'Z') || 40 ((path[0] >= L'A' && path[0] <= L'Z') ||
38 (path[0] >= L'a' && path[0] <= L'z'))) { 41 (path[0] >= L'a' && path[0] <= L'z'))) {
39 return 1; 42 return 1;
40 } 43 }
44 #endif // FILE_PATH_USES_DRIVE_LETTERS
41 return FilePath::StringType::npos; 45 return FilePath::StringType::npos;
42 #else // FILE_PATH_USES_DRIVE_LETTERS
43 return FilePath::StringType::npos;
44 #endif // FILE_PATH_USES_DRIVE_LETTERS
45 } 46 }
46 47
47 bool IsPathAbsolute(const FilePath::StringType& path) { 48 bool IsPathAbsolute(const FilePath::StringType& path) {
48 #if defined(FILE_PATH_USES_DRIVE_LETTERS) 49 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
49 FilePath::StringType::size_type letter = FindDriveLetter(path); 50 FilePath::StringType::size_type letter = FindDriveLetter(path);
50 if (letter != FilePath::StringType::npos) { 51 if (letter != FilePath::StringType::npos) {
51 // Look for a separator right after the drive specification. 52 // Look for a separator right after the drive specification.
52 return path.length() > letter + 1 && 53 return path.length() > letter + 1 &&
53 FilePath::IsSeparator(path[letter + 1]); 54 FilePath::IsSeparator(path[letter + 1]);
54 } 55 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 new_path.path_.find_last_of(kSeparators, StringType::npos, 130 new_path.path_.find_last_of(kSeparators, StringType::npos,
130 arraysize(kSeparators) - 1); 131 arraysize(kSeparators) - 1);
131 if (last_separator != StringType::npos && 132 if (last_separator != StringType::npos &&
132 last_separator < new_path.path_.length() - 1) { 133 last_separator < new_path.path_.length() - 1) {
133 new_path.path_.erase(0, last_separator + 1); 134 new_path.path_.erase(0, last_separator + 1);
134 } 135 }
135 136
136 return new_path; 137 return new_path;
137 } 138 }
138 139
139 FilePath FilePath::Append(const FilePath::StringType& component) const { 140 FilePath::StringType FilePath::Extension() const {
141 // BaseName() calls StripTrailingSeparators, so cases like /foo.baz/// work.
142 StringType base = BaseName().value();
143
144 // Special case "." and ".."
145 if (base == kCurrentDirectory || base == kParentDirectory)
146 return StringType();
147
148 const StringType::size_type last_dot = base.rfind(kExtensionSeparator);
149 if (last_dot == StringType::npos)
150 return StringType();
151 return StringType(base, last_dot);
152 }
153
154 FilePath FilePath::RemoveExtension() const {
155 StringType ext = Extension();
156 // It's important to check Extension() since that verifies that the
157 // kExtensionSeparator actually appeared in the last path component.
158 if (ext.empty())
159 return FilePath(path_);
160 // Since Extension() verified that the extension is in fact in the last path
161 // component, this substr will effectively strip trailing separators.
162 const StringType::size_type last_dot = path_.rfind(kExtensionSeparator);
163 return FilePath(path_.substr(0, last_dot));
164 }
165
166 FilePath FilePath::InsertBeforeExtension(const StringType& suffix) const {
167 if (suffix.empty())
168 return FilePath(path_);
169
170 if (path_.empty())
171 return FilePath();
172
173 StringType base = BaseName().value();
174 if (base.empty())
175 return FilePath();
176 if (*(base.end() - 1) == kExtensionSeparator) {
177 // Special case "." and ".."
178 if (base == kCurrentDirectory || base == kParentDirectory) {
179 return FilePath();
180 }
181 }
182
183 StringType ext = Extension();
184 StringType ret = RemoveExtension().value();
185 ret.append(suffix);
186 ret.append(ext);
187 return FilePath(ret);
188 }
189
190 FilePath FilePath::ReplaceExtension(const StringType& extension) const {
191 if (path_.empty())
192 return FilePath();
193
194 StringType base = BaseName().value();
195 if (base.empty())
196 return FilePath();
197 if (*(base.end() - 1) == kExtensionSeparator) {
198 // Special case "." and ".."
199 if (base == kCurrentDirectory || base == kParentDirectory) {
200 return FilePath();
201 }
202 }
203
204 FilePath no_ext = RemoveExtension();
205 // If the new extension is "" or ".", then just remove the current extension.
206 if (extension.empty() || extension == StringType(1, kExtensionSeparator))
207 return no_ext;
208
209 StringType str = no_ext.value();
210 if (extension[0] != kExtensionSeparator)
211 str.append(1, kExtensionSeparator);
212 str.append(extension);
213 return FilePath(str);
214 }
215
216 FilePath FilePath::Append(const StringType& component) const {
140 DCHECK(!IsPathAbsolute(component)); 217 DCHECK(!IsPathAbsolute(component));
141 if (path_.compare(kCurrentDirectory) == 0) { 218 if (path_.compare(kCurrentDirectory) == 0) {
142 // Append normally doesn't do any normalization, but as a special case, 219 // Append normally doesn't do any normalization, but as a special case,
143 // when appending to kCurrentDirectory, just return a new path for the 220 // when appending to kCurrentDirectory, just return a new path for the
144 // component argument. Appending component to kCurrentDirectory would 221 // component argument. Appending component to kCurrentDirectory would
145 // serve no purpose other than needlessly lengthening the path, and 222 // serve no purpose other than needlessly lengthening the path, and
146 // it's likely in practice to wind up with FilePath objects containing 223 // it's likely in practice to wind up with FilePath objects containing
147 // only kCurrentDirectory when calling DirName on a single relative path 224 // only kCurrentDirectory when calling DirName on a single relative path
148 // component. 225 // component.
149 return FilePath(component); 226 return FilePath(component);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 --pos) { 326 --pos) {
250 // If the string only has two separators and they're at the beginning, 327 // If the string only has two separators and they're at the beginning,
251 // don't strip them, unless the string began with more than two separators. 328 // don't strip them, unless the string began with more than two separators.
252 if (pos != start + 1 || last_stripped == start + 2 || 329 if (pos != start + 1 || last_stripped == start + 2 ||
253 !IsSeparator(path_[start - 1])) { 330 !IsSeparator(path_[start - 1])) {
254 path_.resize(pos - 1); 331 path_.resize(pos - 1);
255 last_stripped = pos; 332 last_stripped = pos;
256 } 333 }
257 } 334 }
258 } 335 }
OLDNEW
« no previous file with comments | « base/file_path.h ('k') | base/file_path_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698