- add sources.
[platform/framework/web/crosswalk.git] / src / webkit / browser / fileapi / file_system_url.cc
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.
4
5 #include "webkit/browser/fileapi/file_system_url.h"
6
7 #include <sstream>
8
9 #include "base/logging.h"
10 #include "base/strings/string_util.h"
11 #include "net/base/escape.h"
12 #include "webkit/common/fileapi/file_system_types.h"
13 #include "webkit/common/fileapi/file_system_util.h"
14
15 namespace fileapi {
16
17 namespace {
18
19 }  // namespace
20
21 FileSystemURL::FileSystemURL()
22     : is_valid_(false),
23       mount_type_(kFileSystemTypeUnknown),
24       type_(kFileSystemTypeUnknown) {
25 }
26
27 // static
28 FileSystemURL FileSystemURL::CreateForTest(const GURL& url) {
29   return FileSystemURL(url);
30 }
31
32 FileSystemURL FileSystemURL::CreateForTest(const GURL& origin,
33                                            FileSystemType mount_type,
34                                            const base::FilePath& virtual_path) {
35   return FileSystemURL(origin, mount_type, virtual_path);
36 }
37
38 // static
39 bool FileSystemURL::ParseFileSystemSchemeURL(
40     const GURL& url,
41     GURL* origin_url,
42     FileSystemType* mount_type,
43     base::FilePath* virtual_path) {
44   GURL origin;
45   FileSystemType file_system_type = kFileSystemTypeUnknown;
46
47   if (!url.is_valid() || !url.SchemeIsFileSystem())
48     return false;
49
50   const struct {
51     FileSystemType type;
52     const char* dir;
53   } kValidTypes[] = {
54     { kFileSystemTypePersistent, kPersistentDir },
55     { kFileSystemTypeTemporary, kTemporaryDir },
56     { kFileSystemTypeIsolated, kIsolatedDir },
57     { kFileSystemTypeExternal, kExternalDir },
58     { kFileSystemTypeTest, kTestDir },
59   };
60
61   // A path of the inner_url contains only mount type part (e.g. "/temporary").
62   DCHECK(url.inner_url());
63   std::string inner_path = url.inner_url()->path();
64   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidTypes); ++i) {
65     if (inner_path == kValidTypes[i].dir) {
66       file_system_type = kValidTypes[i].type;
67       break;
68     }
69   }
70
71   if (file_system_type == kFileSystemTypeUnknown)
72     return false;
73
74   std::string path = net::UnescapeURLComponent(url.path(),
75       net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS |
76       net::UnescapeRule::CONTROL_CHARS);
77
78   // Ensure the path is relative.
79   while (!path.empty() && path[0] == '/')
80     path.erase(0, 1);
81
82   base::FilePath converted_path = base::FilePath::FromUTF8Unsafe(path);
83
84   // All parent references should have been resolved in the renderer.
85   if (converted_path.ReferencesParent())
86     return false;
87
88   if (origin_url)
89     *origin_url = url.GetOrigin();
90   if (mount_type)
91     *mount_type = file_system_type;
92   if (virtual_path)
93     *virtual_path = converted_path.NormalizePathSeparators().
94         StripTrailingSeparators();
95
96   return true;
97 }
98
99 FileSystemURL::FileSystemURL(const GURL& url)
100     : mount_type_(kFileSystemTypeUnknown),
101       type_(kFileSystemTypeUnknown) {
102   is_valid_ = ParseFileSystemSchemeURL(url, &origin_, &mount_type_,
103                                        &virtual_path_);
104   path_ = virtual_path_;
105   type_ = mount_type_;
106 }
107
108 FileSystemURL::FileSystemURL(const GURL& origin,
109                              FileSystemType mount_type,
110                              const base::FilePath& virtual_path)
111     : is_valid_(true),
112       origin_(origin),
113       mount_type_(mount_type),
114       virtual_path_(virtual_path.NormalizePathSeparators()),
115       type_(mount_type),
116       path_(virtual_path.NormalizePathSeparators()) {
117 }
118
119 FileSystemURL::FileSystemURL(const GURL& origin,
120                              FileSystemType mount_type,
121                              const base::FilePath& virtual_path,
122                              const std::string& mount_filesystem_id,
123                              FileSystemType cracked_type,
124                              const base::FilePath& cracked_path,
125                              const std::string& filesystem_id)
126     : is_valid_(true),
127       origin_(origin),
128       mount_type_(mount_type),
129       virtual_path_(virtual_path.NormalizePathSeparators()),
130       mount_filesystem_id_(mount_filesystem_id),
131       type_(cracked_type),
132       path_(cracked_path.NormalizePathSeparators()),
133       filesystem_id_(filesystem_id) {
134 }
135
136 FileSystemURL::~FileSystemURL() {}
137
138 GURL FileSystemURL::ToGURL() const {
139   if (!is_valid_)
140     return GURL();
141
142   std::string url = GetFileSystemRootURI(origin_, mount_type_).spec();
143   if (url.empty())
144     return GURL();
145
146   url.append(virtual_path_.AsUTF8Unsafe());
147
148   // Build nested GURL.
149   return GURL(url);
150 }
151
152 std::string FileSystemURL::DebugString() const {
153   if (!is_valid_)
154     return "invalid filesystem: URL";
155   std::ostringstream ss;
156   ss << GetFileSystemRootURI(origin_, mount_type_);
157
158   // filesystem_id_ will be non empty for (and only for) cracked URLs.
159   if (!filesystem_id_.empty()) {
160     ss << virtual_path_.value();
161     ss << " (";
162     ss << GetFileSystemTypeString(type_) << "@" << filesystem_id_ << ":";
163     ss << path_.value();
164     ss << ")";
165   } else {
166     ss << path_.value();
167   }
168   return ss.str();
169 }
170
171 bool FileSystemURL::IsParent(const FileSystemURL& child) const {
172   return IsInSameFileSystem(child) &&
173          path().IsParent(child.path());
174 }
175
176 bool FileSystemURL::IsInSameFileSystem(const FileSystemURL& other) const {
177   return origin() == other.origin() &&
178          type() == other.type() &&
179          filesystem_id() == other.filesystem_id();
180 }
181
182 bool FileSystemURL::operator==(const FileSystemURL& that) const {
183   return origin_ == that.origin_ &&
184       type_ == that.type_ &&
185       path_ == that.path_ &&
186       filesystem_id_ == that.filesystem_id_ &&
187       is_valid_ == that.is_valid_;
188 }
189
190 bool FileSystemURL::Comparator::operator()(const FileSystemURL& lhs,
191                                            const FileSystemURL& rhs) const {
192   DCHECK(lhs.is_valid_ && rhs.is_valid_);
193   if (lhs.origin_ != rhs.origin_)
194     return lhs.origin_ < rhs.origin_;
195   if (lhs.type_ != rhs.type_)
196     return lhs.type_ < rhs.type_;
197   if (lhs.filesystem_id_ != rhs.filesystem_id_)
198     return lhs.filesystem_id_ < rhs.filesystem_id_;
199   return lhs.path_ < rhs.path_;
200 }
201
202 }  // namespace fileapi