OLD | NEW |
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/logging.h" | 6 #include "base/logging.h" |
7 | 7 |
8 // These includes are just for the *Hack functions, and should be removed | 8 // These includes are just for the *Hack functions, and should be removed |
9 // when those functions are removed. | 9 // when those functions are removed. |
10 #include "base/string_piece.h" | 10 #include "base/string_piece.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 } | 54 } |
55 // Look for a pair of leading separators. | 55 // Look for a pair of leading separators. |
56 return path.length() > 1 && | 56 return path.length() > 1 && |
57 FilePath::IsSeparator(path[0]) && FilePath::IsSeparator(path[1]); | 57 FilePath::IsSeparator(path[0]) && FilePath::IsSeparator(path[1]); |
58 #else // FILE_PATH_USES_DRIVE_LETTERS | 58 #else // FILE_PATH_USES_DRIVE_LETTERS |
59 // Look for a separator in the first position. | 59 // Look for a separator in the first position. |
60 return path.length() > 0 && FilePath::IsSeparator(path[0]); | 60 return path.length() > 0 && FilePath::IsSeparator(path[0]); |
61 #endif // FILE_PATH_USES_DRIVE_LETTERS | 61 #endif // FILE_PATH_USES_DRIVE_LETTERS |
62 } | 62 } |
63 | 63 |
| 64 bool AreAllSeparators(FilePath::StringType input) { |
| 65 for (FilePath::StringType::const_iterator it = input.begin(); |
| 66 it != input.end(); ++it) { |
| 67 if (!FilePath::IsSeparator(*it)) |
| 68 return false; |
| 69 } |
| 70 |
| 71 return true; |
| 72 } |
| 73 |
64 } // namespace | 74 } // namespace |
65 | 75 |
66 bool FilePath::IsSeparator(CharType character) { | 76 bool FilePath::IsSeparator(CharType character) { |
67 for (size_t i = 0; i < arraysize(kSeparators) - 1; ++i) { | 77 for (size_t i = 0; i < arraysize(kSeparators) - 1; ++i) { |
68 if (character == kSeparators[i]) { | 78 if (character == kSeparators[i]) { |
69 return true; | 79 return true; |
70 } | 80 } |
71 } | 81 } |
72 | 82 |
73 return false; | 83 return false; |
74 } | 84 } |
75 | 85 |
| 86 void FilePath::GetComponents(std::vector<FilePath::StringType>* components) |
| 87 const { |
| 88 DCHECK(components); |
| 89 if (!components) |
| 90 return; |
| 91 components->clear(); |
| 92 if (value().empty()) |
| 93 return; |
| 94 |
| 95 std::vector<FilePath::StringType> ret_val; |
| 96 FilePath current = *this; |
| 97 FilePath base; |
| 98 |
| 99 // Capture path components. |
| 100 while (current != current.DirName()) { |
| 101 base = current.BaseName(); |
| 102 if (!AreAllSeparators(base.value())) |
| 103 ret_val.push_back(base.value()); |
| 104 current = current.DirName(); |
| 105 } |
| 106 |
| 107 // Capture root, if any. |
| 108 base = current.BaseName(); |
| 109 if (!base.value().empty() && base.value() != kCurrentDirectory) |
| 110 ret_val.push_back(current.BaseName().value()); |
| 111 |
| 112 // Capture drive letter, if any. |
| 113 FilePath dir = current.DirName(); |
| 114 StringType::size_type letter = FindDriveLetter(dir.value()); |
| 115 if (letter != FilePath::StringType::npos) { |
| 116 ret_val.push_back(FilePath::StringType(dir.value(), 0, letter + 1)); |
| 117 } |
| 118 |
| 119 *components = std::vector<FilePath::StringType>(ret_val.rbegin(), |
| 120 ret_val.rend()); |
| 121 } |
| 122 |
| 123 bool FilePath::IsParent(const FilePath& child) const { |
| 124 std::vector<FilePath::StringType> parent_components; |
| 125 std::vector<FilePath::StringType> child_components; |
| 126 GetComponents(&parent_components); |
| 127 child.GetComponents(&child_components); |
| 128 |
| 129 if (parent_components.size() >= child_components.size()) |
| 130 return false; |
| 131 if (parent_components.size() == 0) |
| 132 return false; |
| 133 |
| 134 std::vector<FilePath::StringType>::const_iterator parent_comp = |
| 135 parent_components.begin(); |
| 136 std::vector<FilePath::StringType>::const_iterator child_comp = |
| 137 child_components.begin(); |
| 138 while (parent_comp != parent_components.end()) { |
| 139 if (*parent_comp != *child_comp) |
| 140 return false; |
| 141 ++parent_comp; |
| 142 ++child_comp; |
| 143 } |
| 144 |
| 145 return true; |
| 146 } |
| 147 |
76 // libgen's dirname and basename aren't guaranteed to be thread-safe and aren't | 148 // libgen's dirname and basename aren't guaranteed to be thread-safe and aren't |
77 // guaranteed to not modify their input strings, and in fact are implemented | 149 // guaranteed to not modify their input strings, and in fact are implemented |
78 // differently in this regard on different platforms. Don't use them, but | 150 // differently in this regard on different platforms. Don't use them, but |
79 // adhere to their behavior. | 151 // adhere to their behavior. |
80 FilePath FilePath::DirName() const { | 152 FilePath FilePath::DirName() const { |
81 FilePath new_path(path_); | 153 FilePath new_path(path_); |
82 new_path.StripTrailingSeparatorsInternal(); | 154 new_path.StripTrailingSeparatorsInternal(); |
83 | 155 |
84 // The drive letter, if any, always needs to remain in the output. If there | 156 // The drive letter, if any, always needs to remain in the output. If there |
85 // is no drive letter, as will always be the case on platforms which do not | 157 // is no drive letter, as will always be the case on platforms which do not |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 --pos) { | 381 --pos) { |
310 // If the string only has two separators and they're at the beginning, | 382 // If the string only has two separators and they're at the beginning, |
311 // don't strip them, unless the string began with more than two separators. | 383 // don't strip them, unless the string began with more than two separators. |
312 if (pos != start + 1 || last_stripped == start + 2 || | 384 if (pos != start + 1 || last_stripped == start + 2 || |
313 !IsSeparator(path_[start - 1])) { | 385 !IsSeparator(path_[start - 1])) { |
314 path_.resize(pos - 1); | 386 path_.resize(pos - 1); |
315 last_stripped = pos; | 387 last_stripped = pos; |
316 } | 388 } |
317 } | 389 } |
318 } | 390 } |
OLD | NEW |