OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/file_system_file_util.h" | 5 #include "webkit/fileapi/fileapi_file_util.h" |
6 | 6 |
7 #include <stack> | 7 #include <stack> |
8 #include <vector> | |
9 | 8 |
10 #include "base/file_util_proxy.h" | |
11 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
12 #include "webkit/fileapi/file_system_operation_context.h" | 10 #include "webkit/fileapi/file_system_operation_context.h" |
13 | 11 |
14 namespace fileapi { | 12 namespace fileapi { |
15 | 13 |
16 namespace { | 14 namespace { |
17 | 15 |
18 // This assumes that the root exists. | 16 // This assumes that the root exists. |
19 bool ParentExists(FileSystemOperationContext* context, | 17 bool ParentExists(FileSystemOperationContext* context, |
20 FileSystemFileUtil* file_util, const FilePath& file_path) { | 18 FileApiFileUtil* file_util, const FilePath& file_path) { |
21 // If file_path is in the root, file_path.DirName() will be ".", | 19 // If file_path is in the root, file_path.DirName() will be ".", |
22 // since we use paths with no leading '/'. | 20 // since we use paths with no leading '/'. |
23 FilePath parent = file_path.DirName(); | 21 FilePath parent = file_path.DirName(); |
24 if (parent == FilePath(FILE_PATH_LITERAL("."))) | 22 if (parent == FilePath(FILE_PATH_LITERAL("."))) |
25 return true; | 23 return true; |
26 return file_util->DirectoryExists(context, parent); | 24 return file_util->DirectoryExists(context, parent); |
27 } | 25 } |
28 | 26 |
29 } // namespace | 27 } // namespace |
30 | 28 |
31 PlatformFileError FileSystemFileUtil::CreateOrOpen( | 29 FileApiFileUtil::FileApiFileUtil() { |
32 FileSystemOperationContext* unused, | |
33 const FilePath& file_path, int file_flags, | |
34 PlatformFile* file_handle, bool* created) { | |
35 if (!file_util::DirectoryExists(file_path.DirName())) { | |
36 // If its parent does not exist, should return NOT_FOUND error. | |
37 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
38 } | |
39 PlatformFileError error_code = base::PLATFORM_FILE_OK; | |
40 *file_handle = base::CreatePlatformFile(file_path, file_flags, | |
41 created, &error_code); | |
42 return error_code; | |
43 } | 30 } |
44 | 31 |
45 PlatformFileError FileSystemFileUtil::Close( | 32 FileApiFileUtil::FileApiFileUtil(FileApiFileUtil* underlying_file_util) |
46 FileSystemOperationContext* unused, | 33 : underlying_file_util_(underlying_file_util) { |
47 PlatformFile file_handle) { | |
48 if (!base::ClosePlatformFile(file_handle)) | |
49 return base::PLATFORM_FILE_ERROR_FAILED; | |
50 return base::PLATFORM_FILE_OK; | |
51 } | 34 } |
52 | 35 |
53 PlatformFileError FileSystemFileUtil::EnsureFileExists( | 36 FileApiFileUtil::~FileApiFileUtil() { |
54 FileSystemOperationContext* unused, | |
55 const FilePath& file_path, | |
56 bool* created) { | |
57 if (!file_util::DirectoryExists(file_path.DirName())) | |
58 // If its parent does not exist, should return NOT_FOUND error. | |
59 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
60 PlatformFileError error_code = base::PLATFORM_FILE_OK; | |
61 // Tries to create the |file_path| exclusively. This should fail | |
62 // with base::PLATFORM_FILE_ERROR_EXISTS if the path already exists. | |
63 PlatformFile handle = base::CreatePlatformFile( | |
64 file_path, | |
65 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_READ, | |
66 created, &error_code); | |
67 if (error_code == base::PLATFORM_FILE_ERROR_EXISTS) { | |
68 // Make sure created_ is false. | |
69 if (created) | |
70 *created = false; | |
71 error_code = base::PLATFORM_FILE_OK; | |
72 } | |
73 if (handle != base::kInvalidPlatformFileValue) | |
74 base::ClosePlatformFile(handle); | |
75 return error_code; | |
76 } | 37 } |
77 | 38 |
78 PlatformFileError FileSystemFileUtil::GetLocalFilePath( | 39 PlatformFileError FileApiFileUtil::Copy( |
79 FileSystemOperationContext* context, | |
80 const FilePath& virtual_path, | |
81 FilePath* local_path) { | |
82 *local_path = virtual_path; | |
83 return base::PLATFORM_FILE_OK; | |
84 } | |
85 | |
86 PlatformFileError FileSystemFileUtil::GetFileInfo( | |
87 FileSystemOperationContext* unused, | |
88 const FilePath& file_path, | |
89 base::PlatformFileInfo* file_info, | |
90 FilePath* platform_file_path) { | |
91 if (!file_util::PathExists(file_path)) | |
92 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
93 // TODO(rkc): Fix this hack once we have refactored file_util to handle | |
94 // symlinks correctly. | |
95 // http://code.google.com/p/chromium-os/issues/detail?id=15948 | |
96 if (file_util::IsLink(file_path)) | |
97 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
98 if (!file_util::GetFileInfo(file_path, file_info)) | |
99 return base::PLATFORM_FILE_ERROR_FAILED; | |
100 *platform_file_path = file_path; | |
101 return base::PLATFORM_FILE_OK; | |
102 } | |
103 | |
104 PlatformFileError FileSystemFileUtil::ReadDirectory( | |
105 FileSystemOperationContext* unused, | |
106 const FilePath& file_path, | |
107 std::vector<base::FileUtilProxy::Entry>* entries) { | |
108 // TODO(kkanetkar): Implement directory read in multiple chunks. | |
109 if (!file_util::DirectoryExists(file_path)) | |
110 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
111 | |
112 file_util::FileEnumerator file_enum( | |
113 file_path, false, static_cast<file_util::FileEnumerator::FileType>( | |
114 file_util::FileEnumerator::FILES | | |
115 file_util::FileEnumerator::DIRECTORIES)); | |
116 FilePath current; | |
117 while (!(current = file_enum.Next()).empty()) { | |
118 base::FileUtilProxy::Entry entry; | |
119 file_util::FileEnumerator::FindInfo info; | |
120 file_enum.GetFindInfo(&info); | |
121 entry.is_directory = file_enum.IsDirectory(info); | |
122 // This will just give the entry's name instead of entire path | |
123 // if we use current.value(). | |
124 entry.name = file_util::FileEnumerator::GetFilename(info).value(); | |
125 entry.size = file_util::FileEnumerator::GetFilesize(info); | |
126 entry.last_modified_time = | |
127 file_util::FileEnumerator::GetLastModifiedTime(info); | |
128 // TODO(rkc): Fix this also once we've refactored file_util | |
129 // http://code.google.com/p/chromium-os/issues/detail?id=15948 | |
130 // This currently just prevents a file from showing up at all | |
131 // if it's a link, hence preventing arbitary 'read' exploits. | |
132 if (!file_util::IsLink(file_path.Append(entry.name))) | |
133 entries->push_back(entry); | |
134 } | |
135 return base::PLATFORM_FILE_OK; | |
136 } | |
137 | |
138 PlatformFileError FileSystemFileUtil::CreateDirectory( | |
139 FileSystemOperationContext* fs_context, | |
140 const FilePath& file_path, | |
141 bool exclusive, | |
142 bool recursive) { | |
143 if (fs_context->do_not_write_actually()) | |
144 return base::PLATFORM_FILE_OK; | |
145 | |
146 // If parent dir of file doesn't exist. | |
147 if (!recursive && !file_util::PathExists(file_path.DirName())) | |
148 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
149 | |
150 bool path_exists = file_util::PathExists(file_path); | |
151 if (exclusive && path_exists) | |
152 return base::PLATFORM_FILE_ERROR_EXISTS; | |
153 | |
154 // If file exists at the path. | |
155 if (path_exists && !file_util::DirectoryExists(file_path)) | |
156 return base::PLATFORM_FILE_ERROR_EXISTS; | |
157 | |
158 if (!file_util::CreateDirectory(file_path)) | |
159 return base::PLATFORM_FILE_ERROR_FAILED; | |
160 return base::PLATFORM_FILE_OK; | |
161 } | |
162 | |
163 PlatformFileError FileSystemFileUtil::Copy( | |
164 FileSystemOperationContext* context, | 40 FileSystemOperationContext* context, |
165 const FilePath& src_file_path, | 41 const FilePath& src_file_path, |
166 const FilePath& dest_file_path) { | 42 const FilePath& dest_file_path) { |
167 PlatformFileError error_code; | 43 PlatformFileError error_code; |
168 error_code = | 44 error_code = |
169 PerformCommonCheckAndPreparationForMoveAndCopy( | 45 PerformCommonCheckAndPreparationForMoveAndCopy( |
170 context, src_file_path, dest_file_path); | 46 context, src_file_path, dest_file_path); |
171 if (error_code != base::PLATFORM_FILE_OK) | 47 if (error_code != base::PLATFORM_FILE_OK) |
172 return error_code; | 48 return error_code; |
173 | 49 |
174 if (DirectoryExists(context, src_file_path)) | 50 if (DirectoryExists(context, src_file_path)) |
175 return CopyOrMoveDirectory(context, src_file_path, dest_file_path, | 51 return CopyOrMoveDirectory(context, src_file_path, dest_file_path, |
176 true /* copy */); | 52 true /* copy */); |
177 return CopyOrMoveFileHelper(context, src_file_path, dest_file_path, | 53 return CopyOrMoveFileHelper(context, src_file_path, dest_file_path, |
178 true /* copy */); | 54 true /* copy */); |
179 } | 55 } |
180 | 56 |
181 PlatformFileError FileSystemFileUtil::Move( | 57 PlatformFileError FileApiFileUtil::Move( |
182 FileSystemOperationContext* context, | 58 FileSystemOperationContext* context, |
183 const FilePath& src_file_path, | 59 const FilePath& src_file_path, |
184 const FilePath& dest_file_path) { | 60 const FilePath& dest_file_path) { |
185 PlatformFileError error_code; | 61 PlatformFileError error_code; |
186 error_code = | 62 error_code = |
187 PerformCommonCheckAndPreparationForMoveAndCopy( | 63 PerformCommonCheckAndPreparationForMoveAndCopy( |
188 context, src_file_path, dest_file_path); | 64 context, src_file_path, dest_file_path); |
189 if (error_code != base::PLATFORM_FILE_OK) | 65 if (error_code != base::PLATFORM_FILE_OK) |
190 return error_code; | 66 return error_code; |
191 | 67 |
192 // TODO(dmikurube): ReplaceFile if in the same domain and filesystem type. | 68 // TODO(dmikurube): ReplaceFile if in the same domain and filesystem type. |
193 if (DirectoryExists(context, src_file_path)) | 69 if (DirectoryExists(context, src_file_path)) |
194 return CopyOrMoveDirectory(context, src_file_path, dest_file_path, | 70 return CopyOrMoveDirectory(context, src_file_path, dest_file_path, |
195 false /* copy */); | 71 false /* copy */); |
196 return CopyOrMoveFileHelper(context, src_file_path, dest_file_path, | 72 return CopyOrMoveFileHelper(context, src_file_path, dest_file_path, |
197 false /* copy */); | 73 false /* copy */); |
198 } | 74 } |
199 | 75 |
200 PlatformFileError FileSystemFileUtil::Delete( | 76 PlatformFileError FileApiFileUtil::Delete( |
201 FileSystemOperationContext* context, | 77 FileSystemOperationContext* context, |
202 const FilePath& file_path, | 78 const FilePath& file_path, |
203 bool recursive) { | 79 bool recursive) { |
204 if (DirectoryExists(context, file_path)) { | 80 if (DirectoryExists(context, file_path)) { |
205 if (!recursive) | 81 if (!recursive) |
206 return DeleteSingleDirectory(context, file_path); | 82 return DeleteSingleDirectory(context, file_path); |
207 else | 83 else |
208 return DeleteDirectoryRecursive(context, file_path); | 84 return DeleteDirectoryRecursive(context, file_path); |
209 } else { | 85 } else { |
210 return DeleteFile(context, file_path); | 86 return DeleteFile(context, file_path); |
211 } | 87 } |
212 } | 88 } |
213 | 89 |
214 PlatformFileError FileSystemFileUtil::Touch( | |
215 FileSystemOperationContext* unused, | |
216 const FilePath& file_path, | |
217 const base::Time& last_access_time, | |
218 const base::Time& last_modified_time) { | |
219 if (!file_util::TouchFile( | |
220 file_path, last_access_time, last_modified_time)) | |
221 return base::PLATFORM_FILE_ERROR_FAILED; | |
222 return base::PLATFORM_FILE_OK; | |
223 } | |
224 | |
225 PlatformFileError FileSystemFileUtil::Truncate( | |
226 FileSystemOperationContext* unused, | |
227 const FilePath& file_path, | |
228 int64 length) { | |
229 PlatformFileError error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
230 PlatformFile file = | |
231 base::CreatePlatformFile( | |
232 file_path, | |
233 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE, | |
234 NULL, | |
235 &error_code); | |
236 if (error_code != base::PLATFORM_FILE_OK) { | |
237 return error_code; | |
238 } | |
239 DCHECK_NE(base::kInvalidPlatformFileValue, file); | |
240 if (!base::TruncatePlatformFile(file, length)) | |
241 error_code = base::PLATFORM_FILE_ERROR_FAILED; | |
242 base::ClosePlatformFile(file); | |
243 return error_code; | |
244 } | |
245 | |
246 PlatformFileError | 90 PlatformFileError |
247 FileSystemFileUtil::PerformCommonCheckAndPreparationForMoveAndCopy( | 91 FileApiFileUtil::PerformCommonCheckAndPreparationForMoveAndCopy( |
248 FileSystemOperationContext* context, | 92 FileSystemOperationContext* context, |
249 const FilePath& src_file_path, | 93 const FilePath& src_file_path, |
250 const FilePath& dest_file_path) { | 94 const FilePath& dest_file_path) { |
251 bool same_file_system = | 95 bool same_file_system = |
252 (context->src_origin_url() == context->dest_origin_url()) && | 96 (context->src_origin_url() == context->dest_origin_url()) && |
253 (context->src_type() == context->dest_type()); | 97 (context->src_type() == context->dest_type()); |
254 FileSystemFileUtil* dest_util = context->dest_file_system_file_util(); | 98 FileApiFileUtil* dest_util = context->dest_file_util(); |
255 DCHECK(dest_util); | 99 DCHECK(dest_util); |
256 if (same_file_system) | 100 if (same_file_system) |
257 DCHECK(context->src_file_system_file_util() == | 101 DCHECK(context->src_file_util() == context->dest_file_util()); |
258 context->dest_file_system_file_util()); | |
259 // All the single-path virtual FSFU methods expect the context information | 102 // All the single-path virtual FSFU methods expect the context information |
260 // to be in the src_* variables, not the dest_* variables, so we have to | 103 // to be in the src_* variables, not the dest_* variables, so we have to |
261 // make a new context if we want to call them on the dest_file_path. | 104 // make a new context if we want to call them on the dest_file_path. |
262 scoped_ptr<FileSystemOperationContext> dest_context( | 105 scoped_ptr<FileSystemOperationContext> dest_context( |
263 context->CreateInheritedContextForDest()); | 106 context->CreateInheritedContextForDest()); |
264 | 107 |
265 // Exits earlier if the source path does not exist. | 108 // Exits earlier if the source path does not exist. |
266 if (!PathExists(context, src_file_path)) | 109 if (!PathExists(context, src_file_path)) |
267 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 110 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
268 | 111 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
306 context->ImportAllowedBytesGrowth(*dest_context); | 149 context->ImportAllowedBytesGrowth(*dest_context); |
307 if (base::PLATFORM_FILE_OK != error) { | 150 if (base::PLATFORM_FILE_OK != error) { |
308 if (!dest_util->IsDirectoryEmpty(dest_context.get(), dest_file_path)) | 151 if (!dest_util->IsDirectoryEmpty(dest_context.get(), dest_file_path)) |
309 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; | 152 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; |
310 return base::PLATFORM_FILE_ERROR_FAILED; | 153 return base::PLATFORM_FILE_ERROR_FAILED; |
311 } | 154 } |
312 } | 155 } |
313 return base::PLATFORM_FILE_OK; | 156 return base::PLATFORM_FILE_OK; |
314 } | 157 } |
315 | 158 |
316 PlatformFileError FileSystemFileUtil::CopyOrMoveFile( | 159 PlatformFileError FileApiFileUtil::CopyOrMoveDirectory( |
317 FileSystemOperationContext* unused, | |
318 const FilePath& src_file_path, | |
319 const FilePath& dest_file_path, | |
320 bool copy) { | |
321 if (copy) { | |
322 if (file_util::CopyFile(src_file_path, dest_file_path)) | |
323 return base::PLATFORM_FILE_OK; | |
324 } else { | |
325 DCHECK(!file_util::DirectoryExists(src_file_path)); | |
326 if (file_util::Move(src_file_path, dest_file_path)) | |
327 return base::PLATFORM_FILE_OK; | |
328 } | |
329 return base::PLATFORM_FILE_ERROR_FAILED; | |
330 } | |
331 | |
332 PlatformFileError FileSystemFileUtil::CopyInForeignFile( | |
333 FileSystemOperationContext* context, | |
334 const FilePath& src_file_path, | |
335 const FilePath& dest_file_path) { | |
336 return CopyOrMoveFile(context, src_file_path, dest_file_path, true); | |
337 } | |
338 | |
339 PlatformFileError FileSystemFileUtil::CopyOrMoveDirectory( | |
340 FileSystemOperationContext* context, | 160 FileSystemOperationContext* context, |
341 const FilePath& src_file_path, | 161 const FilePath& src_file_path, |
342 const FilePath& dest_file_path, | 162 const FilePath& dest_file_path, |
343 bool copy) { | 163 bool copy) { |
344 FileSystemFileUtil* dest_util = context->dest_file_system_file_util(); | 164 FileApiFileUtil* dest_util = context->dest_file_util(); |
345 scoped_ptr<FileSystemOperationContext> dest_context( | 165 scoped_ptr<FileSystemOperationContext> dest_context( |
346 context->CreateInheritedContextForDest()); | 166 context->CreateInheritedContextForDest()); |
347 | 167 |
348 // Re-check PerformCommonCheckAndPreparationForMoveAndCopy() by DCHECK. | 168 // Re-check PerformCommonCheckAndPreparationForMoveAndCopy() by DCHECK. |
349 DCHECK(DirectoryExists(context, src_file_path)); | 169 DCHECK(DirectoryExists(context, src_file_path)); |
350 DCHECK(ParentExists(dest_context.get(), dest_util, dest_file_path)); | 170 DCHECK(ParentExists(dest_context.get(), dest_util, dest_file_path)); |
351 DCHECK(!dest_util->PathExists(dest_context.get(), dest_file_path)); | 171 DCHECK(!dest_util->PathExists(dest_context.get(), dest_file_path)); |
352 if ((context->src_origin_url() == context->dest_origin_url()) && | 172 if ((context->src_origin_url() == context->dest_origin_url()) && |
353 (context->src_type() == context->dest_type())) | 173 (context->src_type() == context->dest_type())) |
354 DCHECK(!src_file_path.IsParent(dest_file_path)); | 174 DCHECK(!src_file_path.IsParent(dest_file_path)); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
390 } | 210 } |
391 | 211 |
392 if (!copy) { | 212 if (!copy) { |
393 PlatformFileError error = Delete(context, src_file_path, true); | 213 PlatformFileError error = Delete(context, src_file_path, true); |
394 if (error != base::PLATFORM_FILE_OK) | 214 if (error != base::PLATFORM_FILE_OK) |
395 return error; | 215 return error; |
396 } | 216 } |
397 return base::PLATFORM_FILE_OK; | 217 return base::PLATFORM_FILE_OK; |
398 } | 218 } |
399 | 219 |
400 PlatformFileError FileSystemFileUtil::CopyOrMoveFileHelper( | 220 PlatformFileError FileApiFileUtil::CopyOrMoveFileHelper( |
401 FileSystemOperationContext* context, | 221 FileSystemOperationContext* context, |
402 const FilePath& src_file_path, | 222 const FilePath& src_file_path, |
403 const FilePath& dest_file_path, | 223 const FilePath& dest_file_path, |
404 bool copy) { | 224 bool copy) { |
405 // CopyOrMoveFile here is the virtual overridden member function. | 225 // CopyOrMoveFile here is the virtual overridden member function. |
406 if ((context->src_origin_url() == context->dest_origin_url()) && | 226 if ((context->src_origin_url() == context->dest_origin_url()) && |
407 (context->src_type() == context->dest_type())) { | 227 (context->src_type() == context->dest_type())) { |
408 DCHECK(context->src_file_system_file_util() == | 228 DCHECK(context->src_file_util() == context->dest_file_util()); |
409 context->dest_file_system_file_util()); | |
410 return CopyOrMoveFile(context, src_file_path, dest_file_path, copy); | 229 return CopyOrMoveFile(context, src_file_path, dest_file_path, copy); |
411 } | 230 } |
412 base::PlatformFileInfo file_info; | 231 base::PlatformFileInfo file_info; |
413 FilePath platform_file_path; | 232 FilePath platform_file_path; |
414 PlatformFileError error_code; | 233 PlatformFileError error_code; |
415 error_code = | 234 error_code = |
416 GetFileInfo(context, src_file_path, &file_info, &platform_file_path); | 235 GetFileInfo(context, src_file_path, &file_info, &platform_file_path); |
417 if (error_code != base::PLATFORM_FILE_OK) | 236 if (error_code != base::PLATFORM_FILE_OK) |
418 return error_code; | 237 return error_code; |
419 | 238 |
420 DCHECK(context->dest_file_system_file_util()); | 239 DCHECK(context->dest_file_util()); |
421 error_code = context->dest_file_system_file_util()->CopyInForeignFile( | 240 error_code = context->dest_file_util()->CopyInForeignFile( |
422 context, platform_file_path, dest_file_path); | 241 context, platform_file_path, dest_file_path); |
423 if (copy || error_code != base::PLATFORM_FILE_OK) | 242 if (copy || error_code != base::PLATFORM_FILE_OK) |
424 return error_code; | 243 return error_code; |
425 return DeleteFile(context, src_file_path); | 244 return DeleteFile(context, src_file_path); |
426 } | 245 } |
427 | 246 |
428 | 247 PlatformFileError FileApiFileUtil::DeleteDirectoryRecursive( |
429 PlatformFileError FileSystemFileUtil::DeleteFile( | |
430 FileSystemOperationContext* unused, | |
431 const FilePath& file_path) { | |
432 if (!file_util::PathExists(file_path)) | |
433 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
434 if (file_util::DirectoryExists(file_path)) | |
435 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; | |
436 if (!file_util::Delete(file_path, false)) | |
437 return base::PLATFORM_FILE_ERROR_FAILED; | |
438 return base::PLATFORM_FILE_OK; | |
439 } | |
440 | |
441 PlatformFileError FileSystemFileUtil::DeleteSingleDirectory( | |
442 FileSystemOperationContext* unused, | |
443 const FilePath& file_path) { | |
444 if (!file_util::PathExists(file_path)) | |
445 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
446 if (!file_util::DirectoryExists(file_path)) { | |
447 // TODO(dmikurube): Check if this error code is appropriate. | |
448 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | |
449 } | |
450 if (!file_util::IsDirectoryEmpty(file_path)) { | |
451 // TODO(dmikurube): Check if this error code is appropriate. | |
452 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; | |
453 } | |
454 if (!file_util::Delete(file_path, false)) | |
455 return base::PLATFORM_FILE_ERROR_FAILED; | |
456 return base::PLATFORM_FILE_OK; | |
457 } | |
458 | |
459 PlatformFileError FileSystemFileUtil::DeleteDirectoryRecursive( | |
460 FileSystemOperationContext* context, | 248 FileSystemOperationContext* context, |
461 const FilePath& file_path) { | 249 const FilePath& file_path) { |
462 scoped_ptr<AbstractFileEnumerator> file_enum( | 250 scoped_ptr<AbstractFileEnumerator> file_enum( |
463 CreateFileEnumerator(context, file_path)); | 251 CreateFileEnumerator(context, file_path)); |
464 FilePath file_path_each; | 252 FilePath file_path_each; |
465 | 253 |
466 std::stack<FilePath> directories; | 254 std::stack<FilePath> directories; |
467 while (!(file_path_each = file_enum->Next()).empty()) { | 255 while (!(file_path_each = file_enum->Next()).empty()) { |
468 if (file_enum->IsDirectory()) { | 256 if (file_enum->IsDirectory()) { |
469 directories.push(file_path_each); | 257 directories.push(file_path_each); |
(...skipping 21 matching lines...) Expand all Loading... | |
491 context->ImportAllowedBytesGrowth(*inherited_context); | 279 context->ImportAllowedBytesGrowth(*inherited_context); |
492 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) | 280 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) |
493 return base::PLATFORM_FILE_ERROR_FAILED; | 281 return base::PLATFORM_FILE_ERROR_FAILED; |
494 else if (error != base::PLATFORM_FILE_OK) | 282 else if (error != base::PLATFORM_FILE_OK) |
495 return error; | 283 return error; |
496 directories.pop(); | 284 directories.pop(); |
497 } | 285 } |
498 return DeleteSingleDirectory(context, file_path); | 286 return DeleteSingleDirectory(context, file_path); |
499 } | 287 } |
500 | 288 |
501 bool FileSystemFileUtil::PathExists( | 289 PlatformFileError FileApiFileUtil::CreateOrOpen( |
ericu
2011/08/22 17:59:37
It's good for implementations of methods to match
Dai Mikurube (NOT FULLTIME)
2011/08/24 11:57:30
Agreed, and reordered the functions.
| |
502 FileSystemOperationContext* unused, | 290 FileSystemOperationContext* context, |
503 const FilePath& file_path) { | 291 const FilePath& file_path, int file_flags, |
504 return file_util::PathExists(file_path); | 292 PlatformFile* file_handle, bool* created) { |
505 } | 293 if (underlying_file_util_.get()) { |
506 | 294 return underlying_file_util_->CreateOrOpen( |
507 bool FileSystemFileUtil::DirectoryExists( | 295 context, file_path, file_flags, file_handle, created); |
508 FileSystemOperationContext* unused, | 296 } |
509 const FilePath& file_path) { | 297 NOTREACHED() << "Subclasses must provide implementation if it has no" |
510 return file_util::DirectoryExists(file_path); | 298 << "underlying_file_util"; |
511 } | 299 return base::PLATFORM_FILE_ERROR_FAILED; |
512 | 300 } |
513 bool FileSystemFileUtil::IsDirectoryEmpty( | 301 |
514 FileSystemOperationContext* unused, | 302 PlatformFileError FileApiFileUtil::Close( |
515 const FilePath& file_path) { | 303 FileSystemOperationContext* context, |
516 return file_util::IsDirectoryEmpty(file_path); | 304 PlatformFile file_handle) { |
517 } | 305 if (underlying_file_util_.get()) { |
518 | 306 return underlying_file_util_->Close(context, file_handle); |
519 class FileSystemFileEnumerator | 307 } |
520 : public FileSystemFileUtil::AbstractFileEnumerator { | 308 NOTREACHED() << "Subclasses must provide implementation if it has no" |
521 public: | 309 << "underlying_file_util"; |
522 FileSystemFileEnumerator(const FilePath& root_path, | 310 return base::PLATFORM_FILE_ERROR_FAILED; |
523 bool recursive, | 311 } |
524 file_util::FileEnumerator::FileType file_type) | 312 |
525 : file_enum_(root_path, recursive, file_type) { | 313 PlatformFileError FileApiFileUtil::EnsureFileExists( |
526 } | 314 FileSystemOperationContext* context, |
527 | 315 const FilePath& file_path, |
528 ~FileSystemFileEnumerator() {} | 316 bool* created) { |
529 | 317 if (underlying_file_util_.get()) { |
530 virtual FilePath Next(); | 318 return underlying_file_util_->EnsureFileExists(context, file_path, created); |
531 virtual bool IsDirectory(); | 319 } |
532 | 320 NOTREACHED() << "Subclasses must provide implementation if it has no" |
533 private: | 321 << "underlying_file_util"; |
534 file_util::FileEnumerator file_enum_; | 322 return base::PLATFORM_FILE_ERROR_FAILED; |
535 }; | 323 } |
536 | 324 |
537 FilePath FileSystemFileEnumerator::Next() { | 325 PlatformFileError FileApiFileUtil::GetLocalFilePath( |
538 return file_enum_.Next(); | 326 FileSystemOperationContext* context, |
539 } | 327 const FilePath& virtual_path, |
540 | 328 FilePath* local_path) { |
541 bool FileSystemFileEnumerator::IsDirectory() { | 329 if (underlying_file_util_.get()) { |
542 file_util::FileEnumerator::FindInfo file_util_info; | 330 return underlying_file_util_->GetLocalFilePath( |
543 file_enum_.GetFindInfo(&file_util_info); | 331 context, virtual_path, local_path); |
544 return file_util::FileEnumerator::IsDirectory(file_util_info); | 332 } |
545 } | 333 NOTREACHED() << "Subclasses must provide implementation if it has no" |
ericu
2011/08/22 17:59:37
s/it has/they have/g
Dai Mikurube (NOT FULLTIME)
2011/08/24 11:57:30
Done.
| |
546 | 334 << "underlying_file_util"; |
547 FileSystemFileUtil::AbstractFileEnumerator* | 335 return base::PLATFORM_FILE_ERROR_FAILED; |
548 FileSystemFileUtil::CreateFileEnumerator( | 336 } |
549 FileSystemOperationContext* unused, | 337 |
338 PlatformFileError FileApiFileUtil::GetFileInfo( | |
339 FileSystemOperationContext* context, | |
340 const FilePath& file_path, | |
341 base::PlatformFileInfo* file_info, | |
342 FilePath* platform_file_path) { | |
343 if (underlying_file_util_.get()) { | |
344 return underlying_file_util_->GetFileInfo( | |
345 context, file_path, file_info, platform_file_path); | |
346 } | |
347 NOTREACHED() << "Subclasses must provide implementation if it has no" | |
348 << "underlying_file_util"; | |
349 return base::PLATFORM_FILE_ERROR_FAILED; | |
350 } | |
351 | |
352 PlatformFileError FileApiFileUtil::ReadDirectory( | |
353 FileSystemOperationContext* context, | |
354 const FilePath& file_path, | |
355 std::vector<base::FileUtilProxy::Entry>* entries) { | |
356 if (underlying_file_util_.get()) { | |
357 return underlying_file_util_->ReadDirectory(context, file_path, entries); | |
358 } | |
359 NOTREACHED() << "Subclasses must provide implementation if it has no" | |
360 << "underlying_file_util"; | |
361 return base::PLATFORM_FILE_ERROR_FAILED; | |
362 } | |
363 | |
364 PlatformFileError FileApiFileUtil::CreateDirectory( | |
365 FileSystemOperationContext* context, | |
366 const FilePath& file_path, | |
367 bool exclusive, | |
368 bool recursive) { | |
369 if (underlying_file_util_.get()) { | |
370 return underlying_file_util_->CreateDirectory( | |
371 context, file_path, exclusive, recursive); | |
372 } | |
373 NOTREACHED() << "Subclasses must provide implementation if it has no" | |
374 << "underlying_file_util"; | |
375 return base::PLATFORM_FILE_ERROR_FAILED; | |
376 } | |
377 | |
378 PlatformFileError FileApiFileUtil::Touch( | |
379 FileSystemOperationContext* context, | |
380 const FilePath& file_path, | |
381 const base::Time& last_access_time, | |
382 const base::Time& last_modified_time) { | |
383 if (underlying_file_util_.get()) { | |
384 return underlying_file_util_->Touch( | |
385 context, file_path, last_access_time, last_modified_time); | |
386 } | |
387 NOTREACHED() << "Subclasses must provide implementation if it has no" | |
388 << "underlying_file_util"; | |
389 return base::PLATFORM_FILE_ERROR_FAILED; | |
390 } | |
391 | |
392 PlatformFileError FileApiFileUtil::Truncate( | |
393 FileSystemOperationContext* context, | |
394 const FilePath& file_path, | |
395 int64 length) { | |
396 if (underlying_file_util_.get()) { | |
397 return underlying_file_util_->Truncate(context, file_path, length); | |
398 } | |
399 NOTREACHED() << "Subclasses must provide implementation if it has no" | |
400 << "underlying_file_util"; | |
401 return base::PLATFORM_FILE_ERROR_FAILED; | |
402 } | |
403 | |
404 PlatformFileError FileApiFileUtil::CopyOrMoveFile( | |
405 FileSystemOperationContext* context, | |
406 const FilePath& src_file_path, | |
407 const FilePath& dest_file_path, | |
408 bool copy) { | |
409 if (underlying_file_util_.get()) { | |
410 return underlying_file_util_->CopyOrMoveFile( | |
411 context, src_file_path, dest_file_path, copy); | |
412 } | |
413 NOTREACHED() << "Subclasses must provide implementation if it has no" | |
414 << "underlying_file_util"; | |
415 return base::PLATFORM_FILE_ERROR_FAILED; | |
416 } | |
417 | |
418 PlatformFileError FileApiFileUtil::CopyInForeignFile( | |
419 FileSystemOperationContext* context, | |
420 const FilePath& src_file_path, | |
421 const FilePath& dest_file_path) { | |
422 if (underlying_file_util_.get()) { | |
423 return underlying_file_util_->CopyInForeignFile( | |
424 context, src_file_path, dest_file_path); | |
425 } | |
426 NOTREACHED() << "Subclasses must provide implementation if it has no" | |
427 << "underlying_file_util"; | |
428 return base::PLATFORM_FILE_ERROR_FAILED; | |
429 } | |
430 | |
431 PlatformFileError FileApiFileUtil::DeleteFile( | |
432 FileSystemOperationContext* context, | |
433 const FilePath& file_path) { | |
434 if (underlying_file_util_.get()) { | |
435 return underlying_file_util_->DeleteFile(context, file_path); | |
436 } | |
437 NOTREACHED() << "Subclasses must provide implementation if it has no" | |
438 << "underlying_file_util"; | |
439 return base::PLATFORM_FILE_ERROR_FAILED; | |
440 } | |
441 | |
442 PlatformFileError FileApiFileUtil::DeleteSingleDirectory( | |
443 FileSystemOperationContext* context, | |
444 const FilePath& file_path) { | |
445 if (underlying_file_util_.get()) { | |
446 return underlying_file_util_->DeleteSingleDirectory(context, file_path); | |
447 } | |
448 NOTREACHED() << "Subclasses must provide implementation if it has no" | |
449 << "underlying_file_util"; | |
450 return base::PLATFORM_FILE_ERROR_FAILED; | |
451 } | |
452 | |
453 bool FileApiFileUtil::PathExists( | |
454 FileSystemOperationContext* context, | |
455 const FilePath& file_path) { | |
456 if (underlying_file_util_.get()) { | |
457 return underlying_file_util_->PathExists(context, file_path); | |
458 } | |
459 NOTREACHED() << "Subclasses must provide implementation if it has no" | |
460 << "underlying_file_util"; | |
461 return false; | |
462 } | |
463 | |
464 bool FileApiFileUtil::DirectoryExists( | |
465 FileSystemOperationContext* context, | |
466 const FilePath& file_path) { | |
467 if (underlying_file_util_.get()) { | |
468 return underlying_file_util_->DirectoryExists(context, file_path); | |
469 } | |
470 NOTREACHED() << "Subclasses must provide implementation if it has no" | |
471 << "underlying_file_util"; | |
472 return false; | |
473 } | |
474 | |
475 bool FileApiFileUtil::IsDirectoryEmpty( | |
476 FileSystemOperationContext* context, | |
477 const FilePath& file_path) { | |
478 if (underlying_file_util_.get()) { | |
479 return underlying_file_util_->IsDirectoryEmpty(context, file_path); | |
480 } | |
481 NOTREACHED() << "Subclasses must provide implementation if it has no" | |
482 << "underlying_file_util"; | |
483 return false; | |
484 } | |
485 | |
486 FileApiFileUtil::AbstractFileEnumerator* FileApiFileUtil::CreateFileEnumerator( | |
487 FileSystemOperationContext* context, | |
550 const FilePath& root_path) { | 488 const FilePath& root_path) { |
551 return new FileSystemFileEnumerator( | 489 if (underlying_file_util_.get()) { |
552 root_path, true, static_cast<file_util::FileEnumerator::FileType>( | 490 return underlying_file_util_->CreateFileEnumerator(context, root_path); |
553 file_util::FileEnumerator::FILES | | 491 } |
554 file_util::FileEnumerator::DIRECTORIES)); | 492 NOTREACHED() << "Subclasses must provide implementation if it has no" |
493 << "underlying_file_util"; | |
494 return NULL; | |
555 } | 495 } |
556 | 496 |
557 } // namespace fileapi | 497 } // namespace fileapi |
OLD | NEW |