Experimental push messaging api reference docs.
[chromium-blink-merge.git] / webkit / fileapi / file_system_url.cc
blob6aaf8a0a8b2504c090729119d82919bb10a62b51
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"
7 #include "base/logging.h"
8 #include "base/string_util.h"
9 #include "net/base/escape.h"
10 #include "webkit/fileapi/file_system_types.h"
11 #include "webkit/fileapi/file_system_util.h"
12 #include "webkit/fileapi/isolated_context.h"
14 namespace fileapi {
15 namespace {
16 bool CrackFileSystemURL(
17 const GURL& url,
18 GURL* origin_url,
19 FileSystemType* type,
20 FilePath* file_path) {
21 GURL origin;
22 FileSystemType file_system_type = kFileSystemTypeUnknown;
24 if (!url.is_valid() || !url.SchemeIsFileSystem())
25 return false;
26 DCHECK(url.inner_url());
28 std::string inner_path = url.inner_url()->path();
30 const struct {
31 FileSystemType type;
32 const char* dir;
33 } kValidTypes[] = {
34 { kFileSystemTypePersistent, kPersistentDir },
35 { kFileSystemTypeTemporary, kTemporaryDir },
36 { kFileSystemTypeIsolated, kIsolatedDir },
37 { kFileSystemTypeExternal, kExternalDir },
38 { kFileSystemTypeTest, kTestDir },
40 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidTypes); ++i) {
41 if (StartsWithASCII(inner_path, kValidTypes[i].dir, true)) {
42 file_system_type = kValidTypes[i].type;
43 break;
47 if (file_system_type == kFileSystemTypeUnknown)
48 return false;
50 std::string path = net::UnescapeURLComponent(url.path(),
51 net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS |
52 net::UnescapeRule::CONTROL_CHARS);
54 // Ensure the path is relative.
55 while (!path.empty() && path[0] == '/')
56 path.erase(0, 1);
58 FilePath converted_path = FilePath::FromUTF8Unsafe(path);
60 // All parent references should have been resolved in the renderer.
61 if (converted_path.ReferencesParent())
62 return false;
64 if (origin_url)
65 *origin_url = url.GetOrigin();
66 if (type)
67 *type = file_system_type;
68 if (file_path)
69 *file_path = converted_path.NormalizePathSeparators().
70 StripTrailingSeparators();
72 return true;
75 } // namespace
77 FileSystemURL::FileSystemURL()
78 : type_(kFileSystemTypeUnknown),
79 is_valid_(false) {}
81 FileSystemURL::FileSystemURL(const GURL& url)
82 : type_(kFileSystemTypeUnknown) {
83 is_valid_ = CrackFileSystemURL(url, &origin_, &type_, &virtual_path_);
84 MayCrackIsolatedPath();
87 FileSystemURL::FileSystemURL(
88 const GURL& origin,
89 FileSystemType type,
90 const FilePath& path)
91 : origin_(origin),
92 type_(type),
93 virtual_path_(path),
94 is_valid_(true) {
95 MayCrackIsolatedPath();
98 FileSystemURL::~FileSystemURL() {}
100 std::string FileSystemURL::spec() const {
101 if (!is_valid_)
102 return std::string();
103 return GetFileSystemRootURI(origin_, type_).spec() + "/" +
104 path_.AsUTF8Unsafe();
107 FileSystemURL FileSystemURL::WithPath(const FilePath& path) const {
108 return FileSystemURL(origin(), type(), path);
111 bool FileSystemURL::operator==(const FileSystemURL& that) const {
112 return origin_ == that.origin_ &&
113 type_ == that.type_ &&
114 path_ == that.path_ &&
115 virtual_path_ == that.virtual_path_ &&
116 filesystem_id_ == that.filesystem_id_ &&
117 is_valid_ == that.is_valid_;
120 bool FileSystemURL::Comparator::operator()(const FileSystemURL& lhs,
121 const FileSystemURL& rhs) const {
122 DCHECK(lhs.is_valid_ && rhs.is_valid_);
123 if (lhs.origin_ != rhs.origin_)
124 return lhs.origin_ < rhs.origin_;
125 if (lhs.type_ != rhs.type_)
126 return lhs.type_ < rhs.type_;
127 // Compares the virtual path, i.e. the path() part of the original URL
128 // so rhs this reflects the virtual path relationship (rather than
129 // rhs of cracked paths).
130 return lhs.virtual_path_ < rhs.virtual_path_;
133 void FileSystemURL::MayCrackIsolatedPath() {
134 path_ = virtual_path_;
135 mount_type_ = type_;
136 if (is_valid_ && IsolatedContext::IsIsolatedType(type_)) {
137 // If the type is isolated, crack the path further to get the 'real'
138 // filesystem type and path.
139 is_valid_ = IsolatedContext::GetInstance()->CrackIsolatedPath(
140 virtual_path_, &filesystem_id_, &type_, &path_);
144 } // namespace fileapi