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...) 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...) 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...) 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...) 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 |