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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 } | 151 } |
152 | 152 |
153 bool FilePath::operator!=(const FilePath& that) const { | 153 bool FilePath::operator!=(const FilePath& that) const { |
154 #if defined(FILE_PATH_USES_DRIVE_LETTERS) | 154 #if defined(FILE_PATH_USES_DRIVE_LETTERS) |
155 return !EqualDriveLetterCaseInsensitive(this->path_, that.path_); | 155 return !EqualDriveLetterCaseInsensitive(this->path_, that.path_); |
156 #else // defined(FILE_PATH_USES_DRIVE_LETTERS) | 156 #else // defined(FILE_PATH_USES_DRIVE_LETTERS) |
157 return path_ != that.path_; | 157 return path_ != that.path_; |
158 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS) | 158 #endif // defined(FILE_PATH_USES_DRIVE_LETTERS) |
159 } | 159 } |
160 | 160 |
161 bool FilePath::AppendAndResolveRelative(const FilePath& relative_path, | |
162 FilePath* path) const { | |
163 DCHECK(path); | |
164 if (!path || relative_path.IsAbsolute()) | |
165 return false; | |
166 | |
167 FilePath full_path = Append(relative_path); | |
168 // Is it worth looking for parent references? | |
169 if (!full_path.ReferencesParent()) { | |
170 *path = full_path; | |
171 return true; | |
172 } | |
173 | |
174 // If the parent has a drive letter, then we must not remove the first | |
175 // component, which is the drive letter. | |
176 bool drive_letter = (FindDriveLetter(full_path.path_) != | |
177 FilePath::StringType::npos); | |
178 | |
179 std::vector<FilePath::StringType> components; | |
180 full_path.GetComponents(&components); | |
181 std::vector<FilePath::StringType>::iterator it = components.begin(); | |
182 // Start by removing any kCurrentDirectory component, since they may | |
183 // fool us into not going back to the appropriate parent level. | |
184 for (; it != components.end(); ++it) { | |
185 if (*it == kCurrentDirectory) { | |
186 // erase returns an iterator to the next component. | |
187 it = components.erase(it); | |
188 // So now, go back to previous iterator, | |
189 // so that we can appropriately process the next one as we loop. | |
190 --it; | |
191 } | |
192 } | |
193 | |
194 // Now parse the component looking for kParentDirectory and remove them as | |
195 // well as the previous component. | |
196 it = components.begin(); | |
197 for (; it != components.end(); ++it) { | |
198 if (*it == kParentDirectory) { | |
199 // Did we reach the beginning? | |
200 if (it == components.begin() || | |
201 (drive_letter && (it - 1) == components.begin())) { | |
202 return false; | |
203 } | |
204 // Remove the previous component, as well as the current one. | |
205 std::vector<FilePath::StringType>::iterator previous = it - 1; | |
206 // Unless the previous is at the beginning. | |
207 if (previous == components.begin() || | |
208 (drive_letter && (previous - 1) == components.begin())) { | |
209 return false; | |
210 } | |
211 // vector::erase doesn't erase _Last, it erases [_First, _Last[, | |
212 // so we must increment current which we want erased. | |
213 it = components.erase(previous, it + 1); | |
214 // And go back to previous so that we can process the next one as we loop. | |
215 --it; | |
216 } | |
217 } | |
218 | |
219 // Now reconstruct the path with the components that were left in. | |
220 it = components.begin(); | |
221 // We start with the first component, in case it is absolute | |
222 // and absolute paths can't be appended. | |
223 *path = FilePath(*it); | |
224 for (++it; it != components.end(); ++it) | |
225 *path = path->Append(*it); | |
226 | |
227 return true; | |
228 } | |
229 | |
230 bool FilePath::IsParent(const FilePath& child) const { | 161 bool FilePath::IsParent(const FilePath& child) const { |
231 return AppendRelativePath(child, NULL); | 162 return AppendRelativePath(child, NULL); |
232 } | 163 } |
233 | 164 |
234 bool FilePath::AppendRelativePath(const FilePath& child, | 165 bool FilePath::AppendRelativePath(const FilePath& child, |
235 FilePath* path) const { | 166 FilePath* path) const { |
236 std::vector<FilePath::StringType> parent_components; | 167 std::vector<FilePath::StringType> parent_components; |
237 std::vector<FilePath::StringType> child_components; | 168 std::vector<FilePath::StringType> child_components; |
238 GetComponents(&parent_components); | 169 GetComponents(&parent_components); |
239 child.GetComponents(&child_components); | 170 child.GetComponents(&child_components); |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 | 477 |
547 std::vector<FilePath::StringType>::const_iterator it = components.begin(); | 478 std::vector<FilePath::StringType>::const_iterator it = components.begin(); |
548 for (; it != components.end(); ++it) { | 479 for (; it != components.end(); ++it) { |
549 const FilePath::StringType& component = *it; | 480 const FilePath::StringType& component = *it; |
550 if (component == kParentDirectory) | 481 if (component == kParentDirectory) |
551 return true; | 482 return true; |
552 } | 483 } |
553 return false; | 484 return false; |
554 } | 485 } |
555 | 486 |
OLD | NEW |