summaryrefslogtreecommitdiffstats
path: root/base/file_path.cc
diff options
context:
space:
mode:
authortim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-27 02:17:53 +0000
committertim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-27 02:17:53 +0000
commit71b0c7f62e9c674adb0ffc785ee0e8de05b55468 (patch)
treeee375dfcf70ac3957a999c5b05b21f90b395c8a6 /base/file_path.cc
parentbd6bf836e379f88b7634c897d210355fbd4e67cb (diff)
downloadchromium_src-71b0c7f62e9c674adb0ffc785ee0e8de05b55468.zip
chromium_src-71b0c7f62e9c674adb0ffc785ee0e8de05b55468.tar.gz
chromium_src-71b0c7f62e9c674adb0ffc785ee0e8de05b55468.tar.bz2
Revert 30149 - The existing file_util::AbsolutePath() function was already doing what we needed to do in the ExtensionResource class.
BUG= http://crbug.com/25681 & http://crbug.com/25131 Review URL: http://codereview.chromium.org/334028 TBR=mad@chromium.org Review URL: http://codereview.chromium.org/335042 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30152 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/file_path.cc')
-rw-r--r--base/file_path.cc69
1 files changed, 69 insertions, 0 deletions
diff --git a/base/file_path.cc b/base/file_path.cc
index e36a168e..2152187 100644
--- a/base/file_path.cc
+++ b/base/file_path.cc
@@ -158,6 +158,75 @@ bool FilePath::operator!=(const FilePath& that) const {
#endif // defined(FILE_PATH_USES_DRIVE_LETTERS)
}
+bool FilePath::AppendAndResolveRelative(const FilePath& relative_path,
+ FilePath* path) const {
+ DCHECK(path);
+ if (!path || relative_path.IsAbsolute())
+ return false;
+
+ FilePath full_path = Append(relative_path);
+ // Is it worth looking for parent references?
+ if (!full_path.ReferencesParent()) {
+ *path = full_path;
+ return true;
+ }
+
+ // If the parent has a drive letter, then we must not remove the first
+ // component, which is the drive letter.
+ bool drive_letter = (FindDriveLetter(full_path.path_) !=
+ FilePath::StringType::npos);
+
+ std::vector<FilePath::StringType> components;
+ full_path.GetComponents(&components);
+ std::vector<FilePath::StringType>::iterator it = components.begin();
+ // Start by removing any kCurrentDirectory component, since they may
+ // fool us into not going back to the appropriate parent level.
+ for (; it != components.end(); ++it) {
+ if (*it == kCurrentDirectory) {
+ // erase returns an iterator to the next component.
+ it = components.erase(it);
+ // So now, go back to previous iterator,
+ // so that we can appropriately process the next one as we loop.
+ --it;
+ }
+ }
+
+ // Now parse the component looking for kParentDirectory and remove them as
+ // well as the previous component.
+ it = components.begin();
+ for (; it != components.end(); ++it) {
+ if (*it == kParentDirectory) {
+ // Did we reach the beginning?
+ if (it == components.begin() ||
+ (drive_letter && (it - 1) == components.begin())) {
+ return false;
+ }
+ // Remove the previous component, as well as the current one.
+ std::vector<FilePath::StringType>::iterator previous = it - 1;
+ // Unless the previous is at the beginning.
+ if (previous == components.begin() ||
+ (drive_letter && (previous - 1) == components.begin())) {
+ return false;
+ }
+ // vector::erase doesn't erase _Last, it erases [_First, _Last[,
+ // so we must increment current which we want erased.
+ it = components.erase(previous, it + 1);
+ // And go back to previous so that we can process the next one as we loop.
+ --it;
+ }
+ }
+
+ // Now reconstruct the path with the components that were left in.
+ it = components.begin();
+ // We start with the first component, in case it is absolute
+ // and absolute paths can't be appended.
+ *path = FilePath(*it);
+ for (++it; it != components.end(); ++it)
+ *path = path->Append(*it);
+
+ return true;
+}
+
bool FilePath::IsParent(const FilePath& child) const {
return AppendRelativePath(child, NULL);
}