Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: webkit/fileapi/isolated_file_util.cc

Issue 10713007: Make isolated file system works for a device root (e.g. X:\\) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 "webkit/fileapi/isolated_file_util.h" 5 #include "webkit/fileapi/isolated_file_util.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "webkit/fileapi/file_system_context.h" 11 #include "webkit/fileapi/file_system_context.h"
12 #include "webkit/fileapi/file_system_operation_context.h" 12 #include "webkit/fileapi/file_system_operation_context.h"
13 #include "webkit/fileapi/file_system_url.h" 13 #include "webkit/fileapi/file_system_url.h"
14 #include "webkit/fileapi/isolated_context.h" 14 #include "webkit/fileapi/isolated_context.h"
15 #include "webkit/fileapi/native_file_util.h" 15 #include "webkit/fileapi/native_file_util.h"
16 16
17 using base::PlatformFileError; 17 using base::PlatformFileError;
18 using base::PlatformFileInfo; 18 using base::PlatformFileInfo;
19 19
20 namespace fileapi { 20 namespace fileapi {
21 21
22 typedef IsolatedContext::FileInfo FileInfo;
23
22 namespace { 24 namespace {
23 25
24 // Simply enumerate each path from a given paths set. 26 // Simply enumerate each path from a given fileinfo set.
25 // Used to enumerate top-level paths of an isolated filesystem. 27 // Used to enumerate top-level paths of an isolated filesystem.
26 class SetFileEnumerator : public FileSystemFileUtil::AbstractFileEnumerator { 28 class SetFileEnumerator : public FileSystemFileUtil::AbstractFileEnumerator {
27 public: 29 public:
28 SetFileEnumerator(const std::vector<FilePath>& paths, 30 SetFileEnumerator(const std::vector<FileInfo>& files,
29 const FilePath& root) 31 const FilePath& root)
30 : paths_(paths), 32 : files_(files),
31 root_(root) { 33 root_(root) {
32 path_iter_ = paths_.begin(); 34 file_iter_ = files_.begin();
33 } 35 }
34 virtual ~SetFileEnumerator() {} 36 virtual ~SetFileEnumerator() {}
35 37
36 // AbstractFileEnumerator overrides. 38 // AbstractFileEnumerator overrides.
37 virtual FilePath Next() OVERRIDE { 39 virtual FilePath Next() OVERRIDE {
38 if (path_iter_ == paths_.end()) 40 if (file_iter_ == files_.end())
39 return FilePath(); 41 return FilePath();
40 FilePath platform_path = *path_iter_++; 42 FilePath platform_file = (file_iter_++)->path;
41 NativeFileUtil::GetFileInfo(platform_path, &file_info_); 43 NativeFileUtil::GetFileInfo(platform_file, &file_info_);
42 return root_.Append(platform_path.BaseName()); 44 return root_.Append(platform_file.BaseName());
43 } 45 }
44 virtual int64 Size() OVERRIDE { return file_info_.size; } 46 virtual int64 Size() OVERRIDE { return file_info_.size; }
45 virtual bool IsDirectory() OVERRIDE { return file_info_.is_directory; } 47 virtual bool IsDirectory() OVERRIDE { return file_info_.is_directory; }
46 virtual base::Time LastModifiedTime() OVERRIDE { 48 virtual base::Time LastModifiedTime() OVERRIDE {
47 return file_info_.last_modified; 49 return file_info_.last_modified;
48 } 50 }
49 51
50 private: 52 private:
51 std::vector<FilePath> paths_; 53 std::vector<FileInfo> files_;
52 std::vector<FilePath>::const_iterator path_iter_; 54 std::vector<FileInfo>::const_iterator file_iter_;
53 FilePath root_; 55 FilePath root_;
54 base::PlatformFileInfo file_info_; 56 base::PlatformFileInfo file_info_;
55 }; 57 };
56 58
57 // A wrapper file enumerator which returns a virtual path of the path returned 59 // A wrapper file enumerator which returns a virtual path of the path returned
58 // by the wrapped enumerator. 60 // by the wrapped enumerator.
59 // 61 //
60 // A virtual path is constructed as following: 62 // A virtual path is constructed as following:
61 // virtual_path = |virtual_base_path| + relative-path-to-|platform_base_path| 63 // virtual_path = |virtual_base_path| + relative-path-to-|platform_base_path|
62 // 64 //
63 // Where |virtual_base_path| is in our case the virtual top-level directory 65 // Where |virtual_base_path| is in our case the virtual top-level directory
64 // that looks like: '/<filesystem_id>'. 66 // that looks like: '/<filesystem_id>'.
65 // 67 //
66 // Example: 68 // Example:
67 // Suppose virtual_base_path is: '/CAFEBABE', 69 // Suppose virtual_base_path is: '/CAFEBABE/dir',
68 // platform_base_path is: '/full/path/to/example/dir', and 70 // platform_base_path is: '/full/path/to/example/dir', and
69 // a path returned by wrapped_is: '/full/path/to/example/dir/a/b/c', 71 // a path returned by wrapped_ is: '/full/path/to/example/dir/a/b/c',
70 // Next() would return: '/CAFEBABE/dir/a/b/c'. 72 // Next() would return: '/CAFEBABE/dir/a/b/c'.
71 // 73 //
72 class PathConverterEnumerator 74 class PathConverterEnumerator
73 : public FileSystemFileUtil::AbstractFileEnumerator { 75 : public FileSystemFileUtil::AbstractFileEnumerator {
74 public: 76 public:
75 PathConverterEnumerator( 77 PathConverterEnumerator(
76 FileSystemFileUtil::AbstractFileEnumerator* wrapped, 78 FileSystemFileUtil::AbstractFileEnumerator* wrapped,
77 const FilePath& virtual_base_path, 79 const FilePath& virtual_base_path,
78 const FilePath& platform_base_path) 80 const FilePath& platform_base_path)
79 : wrapped_(wrapped), 81 : wrapped_(wrapped),
80 virtual_base_path_(virtual_base_path), 82 virtual_base_path_(virtual_base_path),
81 platform_base_path_(platform_base_path) {} 83 platform_base_path_(platform_base_path) {}
82 virtual ~PathConverterEnumerator() {} 84 virtual ~PathConverterEnumerator() {}
83 85
84 // AbstractFileEnumerator overrides. 86 // AbstractFileEnumerator overrides.
85 virtual FilePath Next() OVERRIDE { 87 virtual FilePath Next() OVERRIDE {
86 DCHECK(wrapped_.get()); 88 DCHECK(wrapped_.get());
87 FilePath path = wrapped_->Next(); 89 FilePath path = wrapped_->Next();
88 // Don't return symlinks in subdirectories. 90 // Don't return symlinks in subdirectories.
89 while (!path.empty() && file_util::IsLink(path)) 91 while (!path.empty() && file_util::IsLink(path))
90 path = wrapped_->Next(); 92 path = wrapped_->Next();
91 if (path.empty()) 93 if (path.empty())
92 return path; 94 return path;
93 FilePath virtual_path = virtual_base_path_; 95 FilePath virtual_path = virtual_base_path_;
94 platform_base_path_.DirName().AppendRelativePath(path, &virtual_path); 96 platform_base_path_.AppendRelativePath(path, &virtual_path);
95 return virtual_path; 97 return virtual_path;
96 } 98 }
97 virtual int64 Size() OVERRIDE { return wrapped_->Size(); } 99 virtual int64 Size() OVERRIDE { return wrapped_->Size(); }
98 virtual bool IsDirectory() OVERRIDE { return wrapped_->IsDirectory(); } 100 virtual bool IsDirectory() OVERRIDE { return wrapped_->IsDirectory(); }
99 virtual base::Time LastModifiedTime() OVERRIDE { 101 virtual base::Time LastModifiedTime() OVERRIDE {
100 return wrapped_->LastModifiedTime(); 102 return wrapped_->LastModifiedTime();
101 } 103 }
102 104
103 private: 105 private:
104 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> wrapped_; 106 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> wrapped_;
105 FilePath virtual_base_path_; 107 FilePath virtual_base_path_;
106 FilePath platform_base_path_; 108 FilePath platform_base_path_;
107 }; 109 };
108 110
109 // Recursively enumerate each path from a given paths set. 111 // Recursively enumerate each path from a given paths set.
110 class RecursiveSetFileEnumerator 112 class RecursiveSetFileEnumerator
111 : public FileSystemFileUtil::AbstractFileEnumerator { 113 : public FileSystemFileUtil::AbstractFileEnumerator {
112 public: 114 public:
113 RecursiveSetFileEnumerator(const FilePath& virtual_base_path, 115 RecursiveSetFileEnumerator(const FilePath& virtual_base_path,
114 const std::vector<FilePath>& paths, 116 const std::vector<FileInfo>& files,
115 const FilePath& root) 117 const FilePath& root)
116 : virtual_base_path_(virtual_base_path), 118 : virtual_base_path_(virtual_base_path),
117 paths_(paths), 119 files_(files),
118 root_(root) { 120 root_(root) {
119 path_iter_ = paths_.begin(); 121 file_iter_ = files_.begin();
120 current_enumerator_.reset( 122 current_enumerator_.reset(new SetFileEnumerator(files, root));
121 new SetFileEnumerator(paths, root));
122 } 123 }
123 virtual ~RecursiveSetFileEnumerator() {} 124 virtual ~RecursiveSetFileEnumerator() {}
124 125
125 // AbstractFileEnumerator overrides. 126 // AbstractFileEnumerator overrides.
126 virtual FilePath Next() OVERRIDE; 127 virtual FilePath Next() OVERRIDE;
127 virtual int64 Size() OVERRIDE { 128 virtual int64 Size() OVERRIDE {
128 DCHECK(current_enumerator_.get()); 129 DCHECK(current_enumerator_.get());
129 return current_enumerator_->Size(); 130 return current_enumerator_->Size();
130 } 131 }
131 virtual bool IsDirectory() OVERRIDE { 132 virtual bool IsDirectory() OVERRIDE {
132 DCHECK(current_enumerator_.get()); 133 DCHECK(current_enumerator_.get());
133 return current_enumerator_->IsDirectory(); 134 return current_enumerator_->IsDirectory();
134 } 135 }
135 virtual base::Time LastModifiedTime() OVERRIDE { 136 virtual base::Time LastModifiedTime() OVERRIDE {
136 DCHECK(current_enumerator_.get()); 137 DCHECK(current_enumerator_.get());
137 return current_enumerator_->LastModifiedTime(); 138 return current_enumerator_->LastModifiedTime();
138 } 139 }
139 140
140 private: 141 private:
141 FilePath virtual_base_path_; 142 FilePath virtual_base_path_;
142 std::vector<FilePath> paths_; 143 std::vector<FileInfo> files_;
143 std::vector<FilePath>::iterator path_iter_; 144 std::vector<FileInfo>::iterator file_iter_;
144 base::PlatformFileInfo file_info_; 145 base::PlatformFileInfo file_info_;
145 FilePath root_; 146 FilePath root_;
146 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> current_enumerator_; 147 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> current_enumerator_;
147 }; 148 };
148 149
149 FilePath RecursiveSetFileEnumerator::Next() { 150 FilePath RecursiveSetFileEnumerator::Next() {
150 if (current_enumerator_.get()) { 151 if (current_enumerator_.get()) {
151 FilePath path = current_enumerator_->Next(); 152 FilePath path = current_enumerator_->Next();
152 if (!path.empty()) 153 if (!path.empty())
153 return path; 154 return path;
154 } 155 }
155 156
156 // We reached the end. 157 // We reached the end.
157 if (path_iter_ == paths_.end()) 158 if (file_iter_ == files_.end())
158 return FilePath(); 159 return FilePath();
159 160
160 // Enumerates subdirectories of the next path. 161 // Enumerates subdirectories of the next path.
161 FilePath next_path = *path_iter_++; 162 FileInfo& next_file = *file_iter_++;
162 current_enumerator_.reset( 163 current_enumerator_.reset(
163 new PathConverterEnumerator( 164 new PathConverterEnumerator(
164 NativeFileUtil::CreateFileEnumerator( 165 NativeFileUtil::CreateFileEnumerator(
165 next_path, true /* recursive */), 166 next_file.path, true /* recursive */),
166 virtual_base_path_, next_path)); 167 virtual_base_path_.AppendASCII(next_file.name), next_file.path));
167 DCHECK(current_enumerator_.get()); 168 DCHECK(current_enumerator_.get());
168 return current_enumerator_->Next(); 169 return current_enumerator_->Next();
169 } 170 }
170 171
171 } // namespace 172 } // namespace
172 173
173 IsolatedFileUtil::IsolatedFileUtil() { 174 IsolatedFileUtil::IsolatedFileUtil() {
174 } 175 }
175 176
176 PlatformFileError IsolatedFileUtil::CreateOrOpen( 177 PlatformFileError IsolatedFileUtil::CreateOrOpen(
(...skipping 25 matching lines...) Expand all
202 return base::PLATFORM_FILE_ERROR_SECURITY; 203 return base::PLATFORM_FILE_ERROR_SECURITY;
203 } 204 }
204 205
205 PlatformFileError IsolatedFileUtil::GetFileInfo( 206 PlatformFileError IsolatedFileUtil::GetFileInfo(
206 FileSystemOperationContext* context, 207 FileSystemOperationContext* context,
207 const FileSystemURL& url, 208 const FileSystemURL& url,
208 PlatformFileInfo* file_info, 209 PlatformFileInfo* file_info,
209 FilePath* platform_path) { 210 FilePath* platform_path) {
210 DCHECK(file_info); 211 DCHECK(file_info);
211 std::string filesystem_id; 212 std::string filesystem_id;
212 FilePath root_unused, cracked_path; 213 FilePath cracked_path;
213 if (!IsolatedContext::GetInstance()->CrackIsolatedPath( 214 if (!IsolatedContext::GetInstance()->CrackIsolatedPath(
214 url.path(), &filesystem_id, &root_unused, &cracked_path)) 215 url.path(), &filesystem_id, NULL, &cracked_path))
215 return base::PLATFORM_FILE_ERROR_SECURITY; 216 return base::PLATFORM_FILE_ERROR_SECURITY;
216 if (cracked_path.empty()) { 217 if (cracked_path.empty()) {
217 // The root directory case. 218 // The root directory case.
218 // For now we leave three time fields (modified/accessed/creation time) 219 // For now we leave three time fields (modified/accessed/creation time)
219 // NULL as it is not really clear what to be set for this virtual directory. 220 // NULL as it is not really clear what to be set for this virtual directory.
220 // TODO(kinuko): Maybe we want to set the time when this filesystem is 221 // TODO(kinuko): Maybe we want to set the time when this filesystem is
221 // created (i.e. when the files/directories are dropped). 222 // created (i.e. when the files/directories are dropped).
222 file_info->is_directory = true; 223 file_info->is_directory = true;
223 file_info->is_symbolic_link = false; 224 file_info->is_symbolic_link = false;
224 file_info->size = 0; 225 file_info->size = 0;
225 return base::PLATFORM_FILE_OK; 226 return base::PLATFORM_FILE_OK;
226 } 227 }
227 base::PlatformFileError error = 228 base::PlatformFileError error =
228 NativeFileUtil::GetFileInfo(cracked_path, file_info); 229 NativeFileUtil::GetFileInfo(cracked_path, file_info);
229 if (file_util::IsLink(cracked_path) && !FilePath().IsParent(cracked_path)) { 230 if (file_util::IsLink(cracked_path) && !FilePath().IsParent(cracked_path)) {
230 // Don't follow symlinks unless it's the one that are selected by the user. 231 // Don't follow symlinks unless it's the one that are selected by the user.
231 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 232 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
232 } 233 }
233 if (error == base::PLATFORM_FILE_OK) 234 if (error == base::PLATFORM_FILE_OK)
234 *platform_path = cracked_path; 235 *platform_path = cracked_path;
235 return error; 236 return error;
236 } 237 }
237 238
238 FileSystemFileUtil::AbstractFileEnumerator* 239 FileSystemFileUtil::AbstractFileEnumerator*
239 IsolatedFileUtil::CreateFileEnumerator( 240 IsolatedFileUtil::CreateFileEnumerator(
240 FileSystemOperationContext* context, 241 FileSystemOperationContext* context,
241 const FileSystemURL& root, 242 const FileSystemURL& root,
242 bool recursive) { 243 bool recursive) {
243 std::string filesystem_id; 244 std::string filesystem_id;
244 FilePath root_path, cracked_path; 245 FileInfo root_info;
246 FilePath cracked_path;
245 if (!IsolatedContext::GetInstance()->CrackIsolatedPath( 247 if (!IsolatedContext::GetInstance()->CrackIsolatedPath(
246 root.path(), &filesystem_id, &root_path, &cracked_path)) 248 root.path(), &filesystem_id, &root_info, &cracked_path))
247 return NULL; 249 return NULL;
248 250
249 FilePath virtual_base_path = 251 FilePath virtual_base_path =
250 IsolatedContext::GetInstance()->CreateVirtualPath(filesystem_id, 252 IsolatedContext::GetInstance()->CreateVirtualRootPath(filesystem_id);
251 FilePath());
252 253
253 if (!cracked_path.empty()) { 254 if (!cracked_path.empty()) {
254 return new PathConverterEnumerator( 255 return new PathConverterEnumerator(
255 NativeFileUtil::CreateFileEnumerator(cracked_path, recursive), 256 NativeFileUtil::CreateFileEnumerator(cracked_path, recursive),
256 virtual_base_path, root_path); 257 virtual_base_path.AppendASCII(root_info.name), root_info.path);
257 } 258 }
258 259
259 // Root path case. 260 // Root path case.
260 std::vector<FilePath> toplevels; 261 std::vector<FileInfo> toplevels;
261 IsolatedContext::GetInstance()->GetTopLevelPaths(filesystem_id, &toplevels); 262 IsolatedContext::GetInstance()->GetRegisteredFileInfo(
263 filesystem_id, &toplevels);
262 if (!recursive) 264 if (!recursive)
263 return new SetFileEnumerator(toplevels, root.path()); 265 return new SetFileEnumerator(toplevels, root.path());
264 return new RecursiveSetFileEnumerator( 266 return new RecursiveSetFileEnumerator(
265 virtual_base_path, toplevels, root.path()); 267 virtual_base_path, toplevels, root.path());
266 } 268 }
267 269
268 PlatformFileError IsolatedFileUtil::GetLocalFilePath( 270 PlatformFileError IsolatedFileUtil::GetLocalFilePath(
269 FileSystemOperationContext* context, 271 FileSystemOperationContext* context,
270 const FileSystemURL& file_system_url, 272 const FileSystemURL& file_system_url,
271 FilePath* local_file_path) { 273 FilePath* local_file_path) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 FileSystemOperationContext* context, 328 FileSystemOperationContext* context,
327 const FileSystemURL& url) { 329 const FileSystemURL& url) {
328 std::string filesystem_id; 330 std::string filesystem_id;
329 FilePath platform_path; 331 FilePath platform_path;
330 if (!IsolatedContext::GetInstance()->CrackIsolatedPath( 332 if (!IsolatedContext::GetInstance()->CrackIsolatedPath(
331 url.path(), &filesystem_id, 333 url.path(), &filesystem_id,
332 NULL, &platform_path)) 334 NULL, &platform_path))
333 return false; 335 return false;
334 if (platform_path.empty()) { 336 if (platform_path.empty()) {
335 // The root directory case. 337 // The root directory case.
336 std::vector<FilePath> toplevels; 338 std::vector<FileInfo> toplevels;
337 bool success = IsolatedContext::GetInstance()->GetTopLevelPaths( 339 bool success = IsolatedContext::GetInstance()->GetRegisteredFileInfo(
338 filesystem_id, &toplevels); 340 filesystem_id, &toplevels);
339 DCHECK(success); 341 DCHECK(success);
340 return toplevels.empty(); 342 return toplevels.empty();
341 } 343 }
342 return NativeFileUtil::IsDirectoryEmpty(platform_path); 344 return NativeFileUtil::IsDirectoryEmpty(platform_path);
343 } 345 }
344 346
345 PlatformFileError IsolatedFileUtil::CopyOrMoveFile( 347 PlatformFileError IsolatedFileUtil::CopyOrMoveFile(
346 FileSystemOperationContext* context, 348 FileSystemOperationContext* context,
347 const FileSystemURL& src_url, 349 const FileSystemURL& src_url,
(...skipping 18 matching lines...) Expand all
366 PlatformFileError IsolatedFileUtil::DeleteSingleDirectory( 368 PlatformFileError IsolatedFileUtil::DeleteSingleDirectory(
367 FileSystemOperationContext* context, 369 FileSystemOperationContext* context,
368 const FileSystemURL& url) { 370 const FileSystemURL& url) {
369 return base::PLATFORM_FILE_ERROR_SECURITY; 371 return base::PLATFORM_FILE_ERROR_SECURITY;
370 } 372 }
371 373
372 bool IsolatedFileUtil::GetPlatformPath(const FileSystemURL& url, 374 bool IsolatedFileUtil::GetPlatformPath(const FileSystemURL& url,
373 FilePath* platform_path) const { 375 FilePath* platform_path) const {
374 DCHECK(platform_path); 376 DCHECK(platform_path);
375 std::string filesystem_id; 377 std::string filesystem_id;
376 FilePath root_path;
377 if (!IsolatedContext::GetInstance()->CrackIsolatedPath( 378 if (!IsolatedContext::GetInstance()->CrackIsolatedPath(
378 url.path(), &filesystem_id, &root_path, platform_path)) 379 url.path(), &filesystem_id, NULL, platform_path))
379 return false; 380 return false;
380 return true; 381 return true;
381 } 382 }
382 383
383 } // namespace 384 } // namespace
OLDNEW
« no previous file with comments | « webkit/fileapi/isolated_context_unittest.cc ('k') | webkit/fileapi/isolated_file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698