| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <windows.h> | 8 #include <windows.h> |
| 9 #elif defined(OS_MACOSX) | 9 #elif defined(OS_MACOSX) |
| 10 #include <CoreFoundation/CoreFoundation.h> | 10 #include <CoreFoundation/CoreFoundation.h> |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 } | 167 } |
| 168 | 168 |
| 169 FilePath::~FilePath() { | 169 FilePath::~FilePath() { |
| 170 } | 170 } |
| 171 | 171 |
| 172 FilePath& FilePath::operator=(const FilePath& that) { | 172 FilePath& FilePath::operator=(const FilePath& that) { |
| 173 path_ = that.path_; | 173 path_ = that.path_; |
| 174 return *this; | 174 return *this; |
| 175 } | 175 } |
| 176 | 176 |
| 177 bool FilePath::operator==(const FilePath& that) const { |
| 178 #if defined(FILE_PATH_USES_DRIVE_LETTERS) |
| 179 return EqualDriveLetterCaseInsensitive(this->path_, that.path_); |
| 180 #else // defined(FILE_PATH_USES_DRIVE_LETTERS) |
| 181 return path_ == that.path_; |
| 182 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS) |
| 183 } |
| 184 |
| 185 bool FilePath::operator!=(const FilePath& that) const { |
| 186 #if defined(FILE_PATH_USES_DRIVE_LETTERS) |
| 187 return !EqualDriveLetterCaseInsensitive(this->path_, that.path_); |
| 188 #else // defined(FILE_PATH_USES_DRIVE_LETTERS) |
| 189 return path_ != that.path_; |
| 190 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS) |
| 191 } |
| 192 |
| 193 // static |
| 177 bool FilePath::IsSeparator(CharType character) { | 194 bool FilePath::IsSeparator(CharType character) { |
| 178 for (size_t i = 0; i < arraysize(kSeparators) - 1; ++i) { | 195 for (size_t i = 0; i < arraysize(kSeparators) - 1; ++i) { |
| 179 if (character == kSeparators[i]) { | 196 if (character == kSeparators[i]) { |
| 180 return true; | 197 return true; |
| 181 } | 198 } |
| 182 } | 199 } |
| 183 | 200 |
| 184 return false; | 201 return false; |
| 185 } | 202 } |
| 186 | 203 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 212 // Capture drive letter, if any. | 229 // Capture drive letter, if any. |
| 213 FilePath dir = current.DirName(); | 230 FilePath dir = current.DirName(); |
| 214 StringType::size_type letter = FindDriveLetter(dir.value()); | 231 StringType::size_type letter = FindDriveLetter(dir.value()); |
| 215 if (letter != StringType::npos) { | 232 if (letter != StringType::npos) { |
| 216 ret_val.push_back(StringType(dir.value(), 0, letter + 1)); | 233 ret_val.push_back(StringType(dir.value(), 0, letter + 1)); |
| 217 } | 234 } |
| 218 | 235 |
| 219 *components = std::vector<StringType>(ret_val.rbegin(), ret_val.rend()); | 236 *components = std::vector<StringType>(ret_val.rbegin(), ret_val.rend()); |
| 220 } | 237 } |
| 221 | 238 |
| 222 bool FilePath::operator==(const FilePath& that) const { | |
| 223 #if defined(FILE_PATH_USES_DRIVE_LETTERS) | |
| 224 return EqualDriveLetterCaseInsensitive(this->path_, that.path_); | |
| 225 #else // defined(FILE_PATH_USES_DRIVE_LETTERS) | |
| 226 return path_ == that.path_; | |
| 227 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS) | |
| 228 } | |
| 229 | |
| 230 bool FilePath::operator!=(const FilePath& that) const { | |
| 231 #if defined(FILE_PATH_USES_DRIVE_LETTERS) | |
| 232 return !EqualDriveLetterCaseInsensitive(this->path_, that.path_); | |
| 233 #else // defined(FILE_PATH_USES_DRIVE_LETTERS) | |
| 234 return path_ != that.path_; | |
| 235 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS) | |
| 236 } | |
| 237 | |
| 238 bool FilePath::IsParent(const FilePath& child) const { | 239 bool FilePath::IsParent(const FilePath& child) const { |
| 239 return AppendRelativePath(child, NULL); | 240 return AppendRelativePath(child, NULL); |
| 240 } | 241 } |
| 241 | 242 |
| 242 bool FilePath::AppendRelativePath(const FilePath& child, | 243 bool FilePath::AppendRelativePath(const FilePath& child, |
| 243 FilePath* path) const { | 244 FilePath* path) const { |
| 244 std::vector<StringType> parent_components; | 245 std::vector<StringType> parent_components; |
| 245 std::vector<StringType> child_components; | 246 std::vector<StringType> child_components; |
| 246 GetComponents(&parent_components); | 247 GetComponents(&parent_components); |
| 247 child.GetComponents(&child_components); | 248 child.GetComponents(&child_components); |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 return Append(ASCIIToUTF16(component.as_string())); | 483 return Append(ASCIIToUTF16(component.as_string())); |
| 483 #elif defined(OS_POSIX) | 484 #elif defined(OS_POSIX) |
| 484 return Append(component.as_string()); | 485 return Append(component.as_string()); |
| 485 #endif | 486 #endif |
| 486 } | 487 } |
| 487 | 488 |
| 488 bool FilePath::IsAbsolute() const { | 489 bool FilePath::IsAbsolute() const { |
| 489 return IsPathAbsolute(path_); | 490 return IsPathAbsolute(path_); |
| 490 } | 491 } |
| 491 | 492 |
| 493 FilePath FilePath::StripTrailingSeparators() const { |
| 494 FilePath new_path(path_); |
| 495 new_path.StripTrailingSeparatorsInternal(); |
| 496 |
| 497 return new_path; |
| 498 } |
| 499 |
| 500 bool FilePath::ReferencesParent() const { |
| 501 std::vector<StringType> components; |
| 502 GetComponents(&components); |
| 503 |
| 504 std::vector<StringType>::const_iterator it = components.begin(); |
| 505 for (; it != components.end(); ++it) { |
| 506 const StringType& component = *it; |
| 507 if (component == kParentDirectory) |
| 508 return true; |
| 509 } |
| 510 return false; |
| 511 } |
| 512 |
| 513 #if defined(OS_POSIX) |
| 514 |
| 515 // See file_path.h for a discussion of the encoding of paths on POSIX |
| 516 // platforms. These *Hack() functions are not quite correct, but they're |
| 517 // only temporary while we fix the remainder of the code. |
| 518 // Remember to remove the #includes at the top when you remove these. |
| 519 |
| 520 // static |
| 521 FilePath FilePath::FromWStringHack(const std::wstring& wstring) { |
| 522 return FilePath(base::SysWideToNativeMB(wstring)); |
| 523 } |
| 524 std::wstring FilePath::ToWStringHack() const { |
| 525 return base::SysNativeMBToWide(path_); |
| 526 } |
| 527 #elif defined(OS_WIN) |
| 528 // static |
| 529 FilePath FilePath::FromWStringHack(const std::wstring& wstring) { |
| 530 return FilePath(wstring); |
| 531 } |
| 532 std::wstring FilePath::ToWStringHack() const { |
| 533 return path_; |
| 534 } |
| 535 #endif |
| 536 |
| 537 // static. |
| 538 void FilePath::WriteStringTypeToPickle(Pickle* pickle, |
| 539 const StringType& path) { |
| 540 #if defined(WCHAR_T_IS_UTF16) |
| 541 pickle->WriteWString(path); |
| 542 #elif defined(WCHAR_T_IS_UTF32) |
| 543 pickle->WriteString(path); |
| 544 #else |
| 545 NOTIMPLEMENTED() << "Impossible encoding situation!"; |
| 546 #endif |
| 547 } |
| 548 |
| 549 // static. |
| 550 bool FilePath::ReadStringTypeFromPickle(Pickle* pickle, void** iter, |
| 551 StringType* path) { |
| 552 #if defined(WCHAR_T_IS_UTF16) |
| 553 if (!pickle->ReadWString(iter, path)) |
| 554 return false; |
| 555 #elif defined(WCHAR_T_IS_UTF32) |
| 556 if (!pickle->ReadString(iter, path)) |
| 557 return false; |
| 558 #else |
| 559 NOTIMPLEMENTED() << "Impossible encoding situation!"; |
| 560 return false; |
| 561 #endif |
| 562 |
| 563 return true; |
| 564 } |
| 565 |
| 566 void FilePath::WriteToPickle(Pickle* pickle) { |
| 567 WriteStringTypeToPickle(pickle, value()); |
| 568 } |
| 569 |
| 570 bool FilePath::ReadFromPickle(Pickle* pickle, void** iter) { |
| 571 return ReadStringTypeFromPickle(pickle, iter, &path_); |
| 572 } |
| 573 |
| 492 #if defined(OS_WIN) | 574 #if defined(OS_WIN) |
| 493 // Windows specific implementation of file string comparisons | 575 // Windows specific implementation of file string comparisons |
| 494 | 576 |
| 495 int FilePath::CompareIgnoreCase(const StringType& string1, | 577 int FilePath::CompareIgnoreCase(const StringType& string1, |
| 496 const StringType& string2) { | 578 const StringType& string2) { |
| 497 // Perform character-wise upper case comparison rather than using the | 579 // Perform character-wise upper case comparison rather than using the |
| 498 // fully Unicode-aware CompareString(). For details see: | 580 // fully Unicode-aware CompareString(). For details see: |
| 499 // http://blogs.msdn.com/michkap/archive/2005/10/17/481600.aspx | 581 // http://blogs.msdn.com/michkap/archive/2005/10/17/481600.aspx |
| 500 StringType::const_iterator i1 = string1.begin(); | 582 StringType::const_iterator i1 = string1.begin(); |
| 501 StringType::const_iterator i2 = string2.begin(); | 583 StringType::const_iterator i2 = string2.begin(); |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1071 int comparison = strcasecmp(string1.c_str(), string2.c_str()); | 1153 int comparison = strcasecmp(string1.c_str(), string2.c_str()); |
| 1072 if (comparison < 0) | 1154 if (comparison < 0) |
| 1073 return -1; | 1155 return -1; |
| 1074 if (comparison > 0) | 1156 if (comparison > 0) |
| 1075 return 1; | 1157 return 1; |
| 1076 return 0; | 1158 return 0; |
| 1077 } | 1159 } |
| 1078 | 1160 |
| 1079 #endif // OS versions of CompareIgnoreCase() | 1161 #endif // OS versions of CompareIgnoreCase() |
| 1080 | 1162 |
| 1081 #if defined(OS_POSIX) | |
| 1082 | |
| 1083 // See file_path.h for a discussion of the encoding of paths on POSIX | |
| 1084 // platforms. These *Hack() functions are not quite correct, but they're | |
| 1085 // only temporary while we fix the remainder of the code. | |
| 1086 // Remember to remove the #includes at the top when you remove these. | |
| 1087 | |
| 1088 // static | |
| 1089 FilePath FilePath::FromWStringHack(const std::wstring& wstring) { | |
| 1090 return FilePath(base::SysWideToNativeMB(wstring)); | |
| 1091 } | |
| 1092 std::wstring FilePath::ToWStringHack() const { | |
| 1093 return base::SysNativeMBToWide(path_); | |
| 1094 } | |
| 1095 #elif defined(OS_WIN) | |
| 1096 // static | |
| 1097 FilePath FilePath::FromWStringHack(const std::wstring& wstring) { | |
| 1098 return FilePath(wstring); | |
| 1099 } | |
| 1100 std::wstring FilePath::ToWStringHack() const { | |
| 1101 return path_; | |
| 1102 } | |
| 1103 #endif | |
| 1104 | |
| 1105 FilePath FilePath::StripTrailingSeparators() const { | |
| 1106 FilePath new_path(path_); | |
| 1107 new_path.StripTrailingSeparatorsInternal(); | |
| 1108 | |
| 1109 return new_path; | |
| 1110 } | |
| 1111 | |
| 1112 // static. | |
| 1113 void FilePath::WriteStringTypeToPickle(Pickle* pickle, | |
| 1114 const StringType& path) { | |
| 1115 #if defined(WCHAR_T_IS_UTF16) | |
| 1116 pickle->WriteWString(path); | |
| 1117 #elif defined(WCHAR_T_IS_UTF32) | |
| 1118 pickle->WriteString(path); | |
| 1119 #else | |
| 1120 NOTIMPLEMENTED() << "Impossible encoding situation!"; | |
| 1121 #endif | |
| 1122 } | |
| 1123 | |
| 1124 // static. | |
| 1125 bool FilePath::ReadStringTypeFromPickle(Pickle* pickle, void** iter, | |
| 1126 StringType* path) { | |
| 1127 #if defined(WCHAR_T_IS_UTF16) | |
| 1128 if (!pickle->ReadWString(iter, path)) | |
| 1129 return false; | |
| 1130 #elif defined(WCHAR_T_IS_UTF32) | |
| 1131 if (!pickle->ReadString(iter, path)) | |
| 1132 return false; | |
| 1133 #else | |
| 1134 NOTIMPLEMENTED() << "Impossible encoding situation!"; | |
| 1135 return false; | |
| 1136 #endif | |
| 1137 | |
| 1138 return true; | |
| 1139 } | |
| 1140 | |
| 1141 void FilePath::WriteToPickle(Pickle* pickle) { | |
| 1142 WriteStringTypeToPickle(pickle, value()); | |
| 1143 } | |
| 1144 | |
| 1145 bool FilePath::ReadFromPickle(Pickle* pickle, void** iter) { | |
| 1146 return ReadStringTypeFromPickle(pickle, iter, &path_); | |
| 1147 } | |
| 1148 | 1163 |
| 1149 void FilePath::StripTrailingSeparatorsInternal() { | 1164 void FilePath::StripTrailingSeparatorsInternal() { |
| 1150 // If there is no drive letter, start will be 1, which will prevent stripping | 1165 // If there is no drive letter, start will be 1, which will prevent stripping |
| 1151 // the leading separator if there is only one separator. If there is a drive | 1166 // the leading separator if there is only one separator. If there is a drive |
| 1152 // letter, start will be set appropriately to prevent stripping the first | 1167 // letter, start will be set appropriately to prevent stripping the first |
| 1153 // separator following the drive letter, if a separator immediately follows | 1168 // separator following the drive letter, if a separator immediately follows |
| 1154 // the drive letter. | 1169 // the drive letter. |
| 1155 StringType::size_type start = FindDriveLetter(path_) + 2; | 1170 StringType::size_type start = FindDriveLetter(path_) + 2; |
| 1156 | 1171 |
| 1157 StringType::size_type last_stripped = StringType::npos; | 1172 StringType::size_type last_stripped = StringType::npos; |
| 1158 for (StringType::size_type pos = path_.length(); | 1173 for (StringType::size_type pos = path_.length(); |
| 1159 pos > start && IsSeparator(path_[pos - 1]); | 1174 pos > start && IsSeparator(path_[pos - 1]); |
| 1160 --pos) { | 1175 --pos) { |
| 1161 // If the string only has two separators and they're at the beginning, | 1176 // If the string only has two separators and they're at the beginning, |
| 1162 // don't strip them, unless the string began with more than two separators. | 1177 // don't strip them, unless the string began with more than two separators. |
| 1163 if (pos != start + 1 || last_stripped == start + 2 || | 1178 if (pos != start + 1 || last_stripped == start + 2 || |
| 1164 !IsSeparator(path_[start - 1])) { | 1179 !IsSeparator(path_[start - 1])) { |
| 1165 path_.resize(pos - 1); | 1180 path_.resize(pos - 1); |
| 1166 last_stripped = pos; | 1181 last_stripped = pos; |
| 1167 } | 1182 } |
| 1168 } | 1183 } |
| 1169 } | 1184 } |
| 1170 | 1185 |
| 1171 bool FilePath::ReferencesParent() const { | |
| 1172 std::vector<StringType> components; | |
| 1173 GetComponents(&components); | |
| 1174 | |
| 1175 std::vector<StringType>::const_iterator it = components.begin(); | |
| 1176 for (; it != components.end(); ++it) { | |
| 1177 const StringType& component = *it; | |
| 1178 if (component == kParentDirectory) | |
| 1179 return true; | |
| 1180 } | |
| 1181 return false; | |
| 1182 } | |
| 1183 | |
| 1184 #if defined(FILE_PATH_USES_WIN_SEPARATORS) | 1186 #if defined(FILE_PATH_USES_WIN_SEPARATORS) |
| 1185 FilePath FilePath::NormalizeWindowsPathSeparators() const { | 1187 FilePath FilePath::NormalizeWindowsPathSeparators() const { |
| 1186 StringType copy = path_; | 1188 StringType copy = path_; |
| 1187 for (size_t i = 1; i < arraysize(kSeparators); ++i) { | 1189 for (size_t i = 1; i < arraysize(kSeparators); ++i) { |
| 1188 std::replace(copy.begin(), copy.end(), kSeparators[i], kSeparators[0]); | 1190 std::replace(copy.begin(), copy.end(), kSeparators[i], kSeparators[0]); |
| 1189 } | 1191 } |
| 1190 return FilePath(copy); | 1192 return FilePath(copy); |
| 1191 } | 1193 } |
| 1192 #endif | 1194 #endif |
| OLD | NEW |