OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |