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 |
161 bool FilePath::IsParent(const FilePath& child) const { | 230 bool FilePath::IsParent(const FilePath& child) const { |
162 return AppendRelativePath(child, NULL); | 231 return AppendRelativePath(child, NULL); |
163 } | 232 } |
164 | 233 |
165 bool FilePath::AppendRelativePath(const FilePath& child, | 234 bool FilePath::AppendRelativePath(const FilePath& child, |
166 FilePath* path) const { | 235 FilePath* path) const { |
167 std::vector<FilePath::StringType> parent_components; | 236 std::vector<FilePath::StringType> parent_components; |
168 std::vector<FilePath::StringType> child_components; | 237 std::vector<FilePath::StringType> child_components; |
169 GetComponents(&parent_components); | 238 GetComponents(&parent_components); |
170 child.GetComponents(&child_components); | 239 child.GetComponents(&child_components); |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 | 546 |
478 std::vector<FilePath::StringType>::const_iterator it = components.begin(); | 547 std::vector<FilePath::StringType>::const_iterator it = components.begin(); |
479 for (; it != components.end(); ++it) { | 548 for (; it != components.end(); ++it) { |
480 const FilePath::StringType& component = *it; | 549 const FilePath::StringType& component = *it; |
481 if (component == kParentDirectory) | 550 if (component == kParentDirectory) |
482 return true; | 551 return true; |
483 } | 552 } |
484 return false; | 553 return false; |
485 } | 554 } |
486 | 555 |
OLD | NEW |