1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "webkit/fileapi/file_system_url.h"
9 #include "base/logging.h"
10 #include "base/string_util.h"
11 #include "net/base/escape.h"
12 #include "webkit/fileapi/external_mount_points.h"
13 #include "webkit/fileapi/file_system_types.h"
14 #include "webkit/fileapi/file_system_util.h"
15 #include "webkit/fileapi/isolated_context.h"
23 FileSystemURL::FileSystemURL()
25 mount_type_(kFileSystemTypeUnknown
),
26 type_(kFileSystemTypeUnknown
) {
30 FileSystemURL
FileSystemURL::CreateForTest(const GURL
& url
) {
31 return FileSystemURL(url
);
34 FileSystemURL
FileSystemURL::CreateForTest(const GURL
& origin
,
36 const base::FilePath
& path
) {
37 return FileSystemURL(origin
, type
, path
);
41 bool FileSystemURL::ParseFileSystemSchemeURL(
45 base::FilePath
* file_path
) {
47 FileSystemType file_system_type
= kFileSystemTypeUnknown
;
49 if (!url
.is_valid() || !url
.SchemeIsFileSystem())
51 DCHECK(url
.inner_url());
53 std::string inner_path
= url
.inner_url()->path();
59 { kFileSystemTypePersistent
, kPersistentDir
},
60 { kFileSystemTypeTemporary
, kTemporaryDir
},
61 { kFileSystemTypeIsolated
, kIsolatedDir
},
62 { kFileSystemTypeExternal
, kExternalDir
},
63 { kFileSystemTypeTest
, kTestDir
},
66 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kValidTypes
); ++i
) {
67 if (StartsWithASCII(inner_path
, kValidTypes
[i
].dir
, true)) {
68 file_system_type
= kValidTypes
[i
].type
;
73 if (file_system_type
== kFileSystemTypeUnknown
)
76 std::string path
= net::UnescapeURLComponent(url
.path(),
77 net::UnescapeRule::SPACES
| net::UnescapeRule::URL_SPECIAL_CHARS
|
78 net::UnescapeRule::CONTROL_CHARS
);
80 // Ensure the path is relative.
81 while (!path
.empty() && path
[0] == '/')
84 base::FilePath converted_path
= base::FilePath::FromUTF8Unsafe(path
);
86 // All parent references should have been resolved in the renderer.
87 if (converted_path
.ReferencesParent())
91 *origin_url
= url
.GetOrigin();
93 *type
= file_system_type
;
95 *file_path
= converted_path
.NormalizePathSeparators().
96 StripTrailingSeparators();
101 FileSystemURL::FileSystemURL(const GURL
& url
)
102 : mount_type_(kFileSystemTypeUnknown
),
103 type_(kFileSystemTypeUnknown
) {
104 is_valid_
= ParseFileSystemSchemeURL(url
, &origin_
, &type_
, &path_
);
105 virtual_path_
= path_
;
109 FileSystemURL::FileSystemURL(const GURL
& origin
,
111 const base::FilePath
& path
)
115 virtual_path_(path
.NormalizePathSeparators()),
117 path_(path
.NormalizePathSeparators()) {
120 FileSystemURL::FileSystemURL(const GURL
& origin
,
121 FileSystemType mount_type
,
122 const base::FilePath
& virtual_path
,
123 const std::string
& mount_filesystem_id
,
124 FileSystemType cracked_type
,
125 const base::FilePath
& cracked_path
,
126 const std::string
& filesystem_id
)
129 mount_type_(mount_type
),
130 virtual_path_(virtual_path
.NormalizePathSeparators()),
131 mount_filesystem_id_(mount_filesystem_id
),
133 path_(cracked_path
.NormalizePathSeparators()),
134 filesystem_id_(filesystem_id
) {
137 FileSystemURL::~FileSystemURL() {}
139 std::string
FileSystemURL::DebugString() const {
141 return "invalid filesystem: URL";
142 std::ostringstream ss
;
143 ss
<< GetFileSystemRootURI(origin_
, mount_type_
);
145 // filesystem_id_ will be non empty for (and only for) cracked URLs.
146 if (!filesystem_id_
.empty()) {
147 ss
<< virtual_path_
.value();
149 ss
<< GetFileSystemTypeString(type_
) << "@" << filesystem_id_
<< ":";
158 bool FileSystemURL::IsParent(const FileSystemURL
& child
) const {
159 return origin() == child
.origin() &&
160 type() == child
.type() &&
161 filesystem_id() == child
.filesystem_id() &&
162 path().IsParent(child
.path());
165 bool FileSystemURL::operator==(const FileSystemURL
& that
) const {
166 return origin_
== that
.origin_
&&
167 type_
== that
.type_
&&
168 path_
== that
.path_
&&
169 filesystem_id_
== that
.filesystem_id_
&&
170 is_valid_
== that
.is_valid_
;
173 bool FileSystemURL::Comparator::operator()(const FileSystemURL
& lhs
,
174 const FileSystemURL
& rhs
) const {
175 DCHECK(lhs
.is_valid_
&& rhs
.is_valid_
);
176 if (lhs
.origin_
!= rhs
.origin_
)
177 return lhs
.origin_
< rhs
.origin_
;
178 if (lhs
.type_
!= rhs
.type_
)
179 return lhs
.type_
< rhs
.type_
;
180 if (lhs
.filesystem_id_
!= rhs
.filesystem_id_
)
181 return lhs
.filesystem_id_
< rhs
.filesystem_id_
;
182 return lhs
.path_
< rhs
.path_
;
185 } // namespace fileapi