Index: base/files/file_path.cc |
diff --git a/base/files/file_path.cc b/base/files/file_path.cc |
index de8927ac5b27c2b70a4117e243181be6c55860f1..10dcf94cdc10b7db5e71012c4e8ea8669dc70e0b 100644 |
--- a/base/files/file_path.cc |
+++ b/base/files/file_path.cc |
@@ -10,9 +10,6 @@ |
#include "base/basictypes.h" |
#include "base/logging.h" |
#include "base/pickle.h" |
- |
-// These includes are just for the *Hack functions, and should be removed |
-// when those functions are removed. |
#include "base/strings/string_piece.h" |
#include "base/strings/string_util.h" |
#include "base/strings/sys_string_conversions.h" |
@@ -31,7 +28,8 @@ |
namespace base { |
-typedef FilePath::StringType StringType; |
+using StringType = FilePath::StringType; |
+using StringPieceType = FilePath::StringPieceType; |
namespace { |
@@ -45,7 +43,7 @@ const FilePath::CharType kStringTerminator = FILE_PATH_LITERAL('\0'); |
// otherwise returns npos. This can only be true on Windows, when a pathname |
// begins with a letter followed by a colon. On other platforms, this always |
// returns npos. |
-StringType::size_type FindDriveLetter(const StringType& path) { |
+StringPieceType::size_type FindDriveLetter(StringPieceType path) { |
#if defined(FILE_PATH_USES_DRIVE_LETTERS) |
// This is dependent on an ASCII-based character set, but that's a |
// reasonable assumption. iswalpha can be too inclusive here. |
@@ -59,26 +57,25 @@ StringType::size_type FindDriveLetter(const StringType& path) { |
} |
#if defined(FILE_PATH_USES_DRIVE_LETTERS) |
-bool EqualDriveLetterCaseInsensitive(const StringType& a, |
- const StringType& b) { |
+bool EqualDriveLetterCaseInsensitive(StringPieceType a, StringPieceType b) { |
size_t a_letter_pos = FindDriveLetter(a); |
size_t b_letter_pos = FindDriveLetter(b); |
if (a_letter_pos == StringType::npos || b_letter_pos == StringType::npos) |
return a == b; |
- StringType a_letter(a.substr(0, a_letter_pos + 1)); |
- StringType b_letter(b.substr(0, b_letter_pos + 1)); |
- if (!StartsWith(a_letter, b_letter, false)) |
+ StringPieceType a_letter(a.substr(0, a_letter_pos + 1)); |
+ StringPieceType b_letter(b.substr(0, b_letter_pos + 1)); |
+ if (!StartsWith(a_letter, b_letter, CompareCase::INSENSITIVE_ASCII)) |
return false; |
- StringType a_rest(a.substr(a_letter_pos + 1)); |
- StringType b_rest(b.substr(b_letter_pos + 1)); |
+ StringPieceType a_rest(a.substr(a_letter_pos + 1)); |
+ StringPieceType b_rest(b.substr(b_letter_pos + 1)); |
return a_rest == b_rest; |
} |
#endif // defined(FILE_PATH_USES_DRIVE_LETTERS) |
-bool IsPathAbsolute(const StringType& path) { |
+bool IsPathAbsolute(StringPieceType path) { |
#if defined(FILE_PATH_USES_DRIVE_LETTERS) |
StringType::size_type letter = FindDriveLetter(path); |
if (letter != StringType::npos) { |
@@ -177,7 +174,8 @@ FilePath::FilePath() { |
FilePath::FilePath(const FilePath& that) : path_(that.path_) { |
} |
-FilePath::FilePath(const StringType& path) : path_(path) { |
+FilePath::FilePath(StringPieceType path) { |
+ path.CopyToString(&path_); |
StringType::size_type nul_pos = path_.find(kStringTerminator); |
if (nul_pos != StringType::npos) |
path_.erase(nul_pos, StringType::npos); |
@@ -279,7 +277,7 @@ bool FilePath::AppendRelativePath(const FilePath& child, |
// never case sensitive. |
if ((FindDriveLetter(*parent_comp) != StringType::npos) && |
(FindDriveLetter(*child_comp) != StringType::npos)) { |
- if (!StartsWith(*parent_comp, *child_comp, false)) |
+ if (!StartsWith(*parent_comp, *child_comp, CompareCase::INSENSITIVE_ASCII)) |
return false; |
++parent_comp; |
++child_comp; |
@@ -404,7 +402,7 @@ FilePath FilePath::RemoveFinalExtension() const { |
return FilePath(path_.substr(0, dot)); |
} |
-FilePath FilePath::InsertBeforeExtension(const StringType& suffix) const { |
+FilePath FilePath::InsertBeforeExtension(StringPieceType suffix) const { |
if (suffix.empty()) |
return FilePath(path_); |
@@ -413,27 +411,27 @@ FilePath FilePath::InsertBeforeExtension(const StringType& suffix) const { |
StringType ext = Extension(); |
StringType ret = RemoveExtension().value(); |
- ret.append(suffix); |
+ suffix.AppendToString(&ret); |
ret.append(ext); |
return FilePath(ret); |
} |
-FilePath FilePath::InsertBeforeExtensionASCII(const StringPiece& suffix) |
- const { |
+FilePath FilePath::InsertBeforeExtensionASCII(StringPiece suffix) const { |
DCHECK(IsStringASCII(suffix)); |
#if defined(OS_WIN) |
- return InsertBeforeExtension(ASCIIToUTF16(suffix.as_string())); |
+ return InsertBeforeExtension(ASCIIToUTF16(suffix)); |
#elif defined(OS_POSIX) |
- return InsertBeforeExtension(suffix.as_string()); |
+ return InsertBeforeExtension(suffix); |
#endif |
} |
-FilePath FilePath::AddExtension(const StringType& extension) const { |
+FilePath FilePath::AddExtension(StringPieceType extension) const { |
if (IsEmptyOrSpecialCase(BaseName().value())) |
return FilePath(); |
// If the new extension is "" or ".", then just return the current FilePath. |
- if (extension.empty() || extension == StringType(1, kExtensionSeparator)) |
+ if (extension.empty() || |
+ (extension.size() == 1 && extension[0] == kExtensionSeparator)) |
return *this; |
StringType str = path_; |
@@ -441,27 +439,28 @@ FilePath FilePath::AddExtension(const StringType& extension) const { |
*(str.end() - 1) != kExtensionSeparator) { |
str.append(1, kExtensionSeparator); |
} |
- str.append(extension); |
+ extension.AppendToString(&str); |
return FilePath(str); |
} |
-FilePath FilePath::ReplaceExtension(const StringType& extension) const { |
+FilePath FilePath::ReplaceExtension(StringPieceType extension) const { |
if (IsEmptyOrSpecialCase(BaseName().value())) |
return FilePath(); |
FilePath no_ext = RemoveExtension(); |
// If the new extension is "" or ".", then just remove the current extension. |
- if (extension.empty() || extension == StringType(1, kExtensionSeparator)) |
+ if (extension.empty() || |
+ (extension.size() == 1 && extension[0] == kExtensionSeparator)) |
return no_ext; |
StringType str = no_ext.value(); |
if (extension[0] != kExtensionSeparator) |
str.append(1, kExtensionSeparator); |
- str.append(extension); |
+ extension.AppendToString(&str); |
return FilePath(str); |
} |
-bool FilePath::MatchesExtension(const StringType& extension) const { |
+bool FilePath::MatchesExtension(StringPieceType extension) const { |
DCHECK(extension.empty() || extension[0] == kExtensionSeparator); |
StringType current_extension = Extension(); |
@@ -472,17 +471,17 @@ bool FilePath::MatchesExtension(const StringType& extension) const { |
return FilePath::CompareEqualIgnoreCase(extension, current_extension); |
} |
-FilePath FilePath::Append(const StringType& component) const { |
- const StringType* appended = &component; |
+FilePath FilePath::Append(StringPieceType component) const { |
+ StringPieceType appended = component; |
StringType without_nuls; |
StringType::size_type nul_pos = component.find(kStringTerminator); |
- if (nul_pos != StringType::npos) { |
- without_nuls = component.substr(0, nul_pos); |
- appended = &without_nuls; |
+ if (nul_pos != StringPieceType::npos) { |
+ component.substr(0, nul_pos).CopyToString(&without_nuls); |
+ appended = StringPieceType(without_nuls); |
} |
- DCHECK(!IsPathAbsolute(*appended)); |
+ DCHECK(!IsPathAbsolute(appended)); |
if (path_.compare(kCurrentDirectory) == 0) { |
// Append normally doesn't do any normalization, but as a special case, |
@@ -492,7 +491,7 @@ FilePath FilePath::Append(const StringType& component) const { |
// it's likely in practice to wind up with FilePath objects containing |
// only kCurrentDirectory when calling DirName on a single relative path |
// component. |
- return FilePath(*appended); |
+ return FilePath(appended); |
} |
FilePath new_path(path_); |
@@ -501,7 +500,7 @@ FilePath FilePath::Append(const StringType& component) const { |
// Don't append a separator if the path is empty (indicating the current |
// directory) or if the path component is empty (indicating nothing to |
// append). |
- if (appended->length() > 0 && new_path.path_.length() > 0) { |
+ if (appended.length() > 0 && new_path.path_.length() > 0) { |
// Don't append a separator if the path still ends with a trailing |
// separator after stripping (indicating the root directory). |
if (!IsSeparator(new_path.path_[new_path.path_.length() - 1])) { |
@@ -512,7 +511,7 @@ FilePath FilePath::Append(const StringType& component) const { |
} |
} |
- new_path.path_.append(*appended); |
+ appended.AppendToString(&new_path.path_); |
return new_path; |
} |
@@ -520,12 +519,12 @@ FilePath FilePath::Append(const FilePath& component) const { |
return Append(component.value()); |
} |
-FilePath FilePath::AppendASCII(const StringPiece& component) const { |
+FilePath FilePath::AppendASCII(StringPiece component) const { |
DCHECK(base::IsStringASCII(component)); |
#if defined(OS_WIN) |
- return Append(ASCIIToUTF16(component.as_string())); |
+ return Append(ASCIIToUTF16(component)); |
#elif defined(OS_POSIX) |
- return Append(component.as_string()); |
+ return Append(component); |
#endif |
} |
@@ -680,17 +679,17 @@ bool FilePath::ReadFromPickle(PickleIterator* iter) { |
} |
#if defined(OS_WIN) |
-// Windows specific implementation of file string comparisons |
+// Windows specific implementation of file string comparisons. |
-int FilePath::CompareIgnoreCase(const StringType& string1, |
- const StringType& string2) { |
+int FilePath::CompareIgnoreCase(StringPieceType string1, |
+ StringPieceType string2) { |
// Perform character-wise upper case comparison rather than using the |
// fully Unicode-aware CompareString(). For details see: |
// http://blogs.msdn.com/michkap/archive/2005/10/17/481600.aspx |
- StringType::const_iterator i1 = string1.begin(); |
- StringType::const_iterator i2 = string2.begin(); |
- StringType::const_iterator string1end = string1.end(); |
- StringType::const_iterator string2end = string2.end(); |
+ StringPieceType::const_iterator i1 = string1.begin(); |
+ StringPieceType::const_iterator i2 = string2.begin(); |
+ StringPieceType::const_iterator string1end = string1.end(); |
+ StringPieceType::const_iterator string2end = string2.end(); |
for ( ; i1 != string1end && i2 != string2end; ++i1, ++i2) { |
wchar_t c1 = |
(wchar_t)LOWORD(::CharUpperW((LPWSTR)(DWORD_PTR)MAKELONG(*i1, 0))); |
@@ -709,7 +708,7 @@ int FilePath::CompareIgnoreCase(const StringType& string1, |
} |
#elif defined(OS_MACOSX) |
-// Mac OS X specific implementation of file string comparisons |
+// Mac OS X specific implementation of file string comparisons. |
// cf. http://developer.apple.com/mac/library/technotes/tn/tn1150.html#UnicodeSubtleties |
// |
@@ -1153,25 +1152,23 @@ inline int HFSReadNextNonIgnorableCodepoint(const char* string, |
return codepoint; |
} |
-} // anonymous namespace |
+} // namespace |
// Special UTF-8 version of FastUnicodeCompare. Cf: |
// http://developer.apple.com/mac/library/technotes/tn/tn1150.html#StringComparisonAlgorithm |
// The input strings must be in the special HFS decomposed form. |
-int FilePath::HFSFastUnicodeCompare(const StringType& string1, |
- const StringType& string2) { |
+int FilePath::HFSFastUnicodeCompare(StringPieceType string1, |
+ StringPieceType string2) { |
int length1 = string1.length(); |
int length2 = string2.length(); |
int index1 = 0; |
int index2 = 0; |
for (;;) { |
- int codepoint1 = HFSReadNextNonIgnorableCodepoint(string1.c_str(), |
- length1, |
- &index1); |
- int codepoint2 = HFSReadNextNonIgnorableCodepoint(string2.c_str(), |
- length2, |
- &index2); |
+ int codepoint1 = |
+ HFSReadNextNonIgnorableCodepoint(string1.data(), length1, &index1); |
+ int codepoint2 = |
+ HFSReadNextNonIgnorableCodepoint(string2.data(), length2, &index2); |
if (codepoint1 != codepoint2) |
return (codepoint1 < codepoint2) ? -1 : 1; |
if (codepoint1 == 0) { |
@@ -1182,15 +1179,10 @@ int FilePath::HFSFastUnicodeCompare(const StringType& string1, |
} |
} |
-StringType FilePath::GetHFSDecomposedForm(const StringType& string) { |
- ScopedCFTypeRef<CFStringRef> cfstring( |
- CFStringCreateWithBytesNoCopy( |
- NULL, |
- reinterpret_cast<const UInt8*>(string.c_str()), |
- string.length(), |
- kCFStringEncodingUTF8, |
- false, |
- kCFAllocatorNull)); |
+StringType FilePath::GetHFSDecomposedForm(StringPieceType string) { |
+ ScopedCFTypeRef<CFStringRef> cfstring(CFStringCreateWithBytesNoCopy( |
+ NULL, reinterpret_cast<const UInt8*>(string.data()), string.length(), |
+ kCFStringEncodingUTF8, false, kCFAllocatorNull)); |
// Query the maximum length needed to store the result. In most cases this |
// will overestimate the required space. The return value also already |
// includes the space needed for a terminating 0. |
@@ -1215,8 +1207,8 @@ StringType FilePath::GetHFSDecomposedForm(const StringType& string) { |
return result; |
} |
-int FilePath::CompareIgnoreCase(const StringType& string1, |
- const StringType& string2) { |
+int FilePath::CompareIgnoreCase(StringPieceType string1, |
+ StringPieceType string2) { |
// Quick checks for empty strings - these speed things up a bit and make the |
// following code cleaner. |
if (string1.empty()) |
@@ -1230,22 +1222,12 @@ int FilePath::CompareIgnoreCase(const StringType& string1, |
// GetHFSDecomposedForm() returns an empty string in an error case. |
if (hfs1.empty() || hfs2.empty()) { |
NOTREACHED(); |
- ScopedCFTypeRef<CFStringRef> cfstring1( |
- CFStringCreateWithBytesNoCopy( |
- NULL, |
- reinterpret_cast<const UInt8*>(string1.c_str()), |
- string1.length(), |
- kCFStringEncodingUTF8, |
- false, |
- kCFAllocatorNull)); |
- ScopedCFTypeRef<CFStringRef> cfstring2( |
- CFStringCreateWithBytesNoCopy( |
- NULL, |
- reinterpret_cast<const UInt8*>(string2.c_str()), |
- string2.length(), |
- kCFStringEncodingUTF8, |
- false, |
- kCFAllocatorNull)); |
+ ScopedCFTypeRef<CFStringRef> cfstring1(CFStringCreateWithBytesNoCopy( |
+ NULL, reinterpret_cast<const UInt8*>(string1.data()), string1.length(), |
+ kCFStringEncodingUTF8, false, kCFAllocatorNull)); |
+ ScopedCFTypeRef<CFStringRef> cfstring2(CFStringCreateWithBytesNoCopy( |
+ NULL, reinterpret_cast<const UInt8*>(string2.data()), string2.length(), |
+ kCFStringEncodingUTF8, false, kCFAllocatorNull)); |
return CFStringCompare(cfstring1, |
cfstring2, |
kCFCompareCaseInsensitive); |
@@ -1256,11 +1238,12 @@ int FilePath::CompareIgnoreCase(const StringType& string1, |
#else // << WIN. MACOSX | other (POSIX) >> |
-// Generic (POSIX) implementation of file string comparison. |
-// TODO(rolandsteiner) check if this is sufficient/correct. |
-int FilePath::CompareIgnoreCase(const StringType& string1, |
- const StringType& string2) { |
- int comparison = strcasecmp(string1.c_str(), string2.c_str()); |
+// Generic Posix system comparisons. |
+int FilePath::CompareIgnoreCase(StringPieceType string1, |
+ StringPieceType string2) { |
+ // Specifically need null termianted strings for this API call. |
+ int comparison = |
+ strcasecmp(string1.as_string().c_str(), string2.as_string().c_str()); |
if (comparison < 0) |
return -1; |
if (comparison > 0) |