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

Side by Side Diff: base/files/file_path.cc

Issue 4883003: Add FilePath::FinalExtension() to avoid double extensions (.tar.gz) for file selector (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comment (also a rebase) Created 7 years 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/files/file_path.h ('k') | base/files/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) 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
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
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
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 }
OLDNEW
« no previous file with comments | « base/files/file_path.h ('k') | base/files/file_path_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698