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/file_system_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 FileSystemFileUtil* 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 FileSystemFileUtil::FileSystemFileUtil() { |
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 FileSystemFileUtil::FileSystemFileUtil(FileSystemFileUtil* 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 FileSystemFileUtil::~FileSystemFileUtil() { |
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 } | |
77 | |
78 PlatformFileError FileSystemFileUtil::GetLocalFilePath( | |
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* unused, | |
140 const FilePath& file_path, | |
141 bool exclusive, | |
142 bool recursive) { | |
143 // If parent dir of file doesn't exist. | |
144 if (!recursive && !file_util::PathExists(file_path.DirName())) | |
145 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
146 | |
147 bool path_exists = file_util::PathExists(file_path); | |
148 if (exclusive && path_exists) | |
149 return base::PLATFORM_FILE_ERROR_EXISTS; | |
150 | |
151 // If file exists at the path. | |
152 if (path_exists && !file_util::DirectoryExists(file_path)) | |
153 return base::PLATFORM_FILE_ERROR_EXISTS; | |
154 | |
155 if (!file_util::CreateDirectory(file_path)) | |
156 return base::PLATFORM_FILE_ERROR_FAILED; | |
157 return base::PLATFORM_FILE_OK; | |
158 } | 37 } |
159 | 38 |
160 PlatformFileError FileSystemFileUtil::Copy( | 39 PlatformFileError FileSystemFileUtil::Copy( |
161 FileSystemOperationContext* context, | 40 FileSystemOperationContext* context, |
162 const FilePath& src_file_path, | 41 const FilePath& src_file_path, |
163 const FilePath& dest_file_path) { | 42 const FilePath& dest_file_path) { |
164 PlatformFileError error_code; | 43 PlatformFileError error_code; |
165 error_code = | 44 error_code = |
166 PerformCommonCheckAndPreparationForMoveAndCopy( | 45 PerformCommonCheckAndPreparationForMoveAndCopy( |
167 context, src_file_path, dest_file_path); | 46 context, src_file_path, dest_file_path); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 if (DirectoryExists(context, file_path)) { | 80 if (DirectoryExists(context, file_path)) { |
202 if (!recursive) | 81 if (!recursive) |
203 return DeleteSingleDirectory(context, file_path); | 82 return DeleteSingleDirectory(context, file_path); |
204 else | 83 else |
205 return DeleteDirectoryRecursive(context, file_path); | 84 return DeleteDirectoryRecursive(context, file_path); |
206 } else { | 85 } else { |
207 return DeleteFile(context, file_path); | 86 return DeleteFile(context, file_path); |
208 } | 87 } |
209 } | 88 } |
210 | 89 |
| 90 PlatformFileError FileSystemFileUtil::CreateOrOpen( |
| 91 FileSystemOperationContext* context, |
| 92 const FilePath& file_path, int file_flags, |
| 93 PlatformFile* file_handle, bool* created) { |
| 94 if (underlying_file_util_.get()) { |
| 95 return underlying_file_util_->CreateOrOpen( |
| 96 context, file_path, file_flags, file_handle, created); |
| 97 } |
| 98 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 99 << "underlying_file_util"; |
| 100 return base::PLATFORM_FILE_ERROR_FAILED; |
| 101 } |
| 102 |
| 103 PlatformFileError FileSystemFileUtil::Close( |
| 104 FileSystemOperationContext* context, |
| 105 PlatformFile file_handle) { |
| 106 if (underlying_file_util_.get()) { |
| 107 return underlying_file_util_->Close(context, file_handle); |
| 108 } |
| 109 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 110 << "underlying_file_util"; |
| 111 return base::PLATFORM_FILE_ERROR_FAILED; |
| 112 } |
| 113 |
| 114 PlatformFileError FileSystemFileUtil::EnsureFileExists( |
| 115 FileSystemOperationContext* context, |
| 116 const FilePath& file_path, |
| 117 bool* created) { |
| 118 if (underlying_file_util_.get()) { |
| 119 return underlying_file_util_->EnsureFileExists(context, file_path, created); |
| 120 } |
| 121 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 122 << "underlying_file_util"; |
| 123 return base::PLATFORM_FILE_ERROR_FAILED; |
| 124 } |
| 125 |
| 126 PlatformFileError FileSystemFileUtil::CreateDirectory( |
| 127 FileSystemOperationContext* context, |
| 128 const FilePath& file_path, |
| 129 bool exclusive, |
| 130 bool recursive) { |
| 131 if (underlying_file_util_.get()) { |
| 132 return underlying_file_util_->CreateDirectory( |
| 133 context, file_path, exclusive, recursive); |
| 134 } |
| 135 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 136 << "underlying_file_util"; |
| 137 return base::PLATFORM_FILE_ERROR_FAILED; |
| 138 } |
| 139 |
| 140 PlatformFileError FileSystemFileUtil::GetFileInfo( |
| 141 FileSystemOperationContext* context, |
| 142 const FilePath& file_path, |
| 143 base::PlatformFileInfo* file_info, |
| 144 FilePath* platform_file_path) { |
| 145 if (underlying_file_util_.get()) { |
| 146 return underlying_file_util_->GetFileInfo( |
| 147 context, file_path, file_info, platform_file_path); |
| 148 } |
| 149 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 150 << "underlying_file_util"; |
| 151 return base::PLATFORM_FILE_ERROR_FAILED; |
| 152 } |
| 153 |
| 154 PlatformFileError FileSystemFileUtil::ReadDirectory( |
| 155 FileSystemOperationContext* context, |
| 156 const FilePath& file_path, |
| 157 std::vector<base::FileUtilProxy::Entry>* entries) { |
| 158 if (underlying_file_util_.get()) { |
| 159 return underlying_file_util_->ReadDirectory(context, file_path, entries); |
| 160 } |
| 161 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 162 << "underlying_file_util"; |
| 163 return base::PLATFORM_FILE_ERROR_FAILED; |
| 164 } |
| 165 |
| 166 FileSystemFileUtil::AbstractFileEnumerator* |
| 167 FileSystemFileUtil::CreateFileEnumerator( |
| 168 FileSystemOperationContext* context, |
| 169 const FilePath& root_path) { |
| 170 if (underlying_file_util_.get()) { |
| 171 return underlying_file_util_->CreateFileEnumerator(context, root_path); |
| 172 } |
| 173 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 174 << "underlying_file_util"; |
| 175 return NULL; |
| 176 } |
| 177 |
| 178 PlatformFileError FileSystemFileUtil::GetLocalFilePath( |
| 179 FileSystemOperationContext* context, |
| 180 const FilePath& virtual_path, |
| 181 FilePath* local_path) { |
| 182 if (underlying_file_util_.get()) { |
| 183 return underlying_file_util_->GetLocalFilePath( |
| 184 context, virtual_path, local_path); |
| 185 } |
| 186 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 187 << "underlying_file_util"; |
| 188 return base::PLATFORM_FILE_ERROR_FAILED; |
| 189 } |
| 190 |
211 PlatformFileError FileSystemFileUtil::Touch( | 191 PlatformFileError FileSystemFileUtil::Touch( |
212 FileSystemOperationContext* unused, | 192 FileSystemOperationContext* context, |
213 const FilePath& file_path, | 193 const FilePath& file_path, |
214 const base::Time& last_access_time, | 194 const base::Time& last_access_time, |
215 const base::Time& last_modified_time) { | 195 const base::Time& last_modified_time) { |
216 if (!file_util::TouchFile( | 196 if (underlying_file_util_.get()) { |
217 file_path, last_access_time, last_modified_time)) | 197 return underlying_file_util_->Touch( |
218 return base::PLATFORM_FILE_ERROR_FAILED; | 198 context, file_path, last_access_time, last_modified_time); |
219 return base::PLATFORM_FILE_OK; | 199 } |
| 200 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 201 << "underlying_file_util"; |
| 202 return base::PLATFORM_FILE_ERROR_FAILED; |
220 } | 203 } |
221 | 204 |
222 PlatformFileError FileSystemFileUtil::Truncate( | 205 PlatformFileError FileSystemFileUtil::Truncate( |
223 FileSystemOperationContext* unused, | 206 FileSystemOperationContext* context, |
224 const FilePath& file_path, | 207 const FilePath& file_path, |
225 int64 length) { | 208 int64 length) { |
226 PlatformFileError error_code(base::PLATFORM_FILE_ERROR_FAILED); | 209 if (underlying_file_util_.get()) { |
227 PlatformFile file = | 210 return underlying_file_util_->Truncate(context, file_path, length); |
228 base::CreatePlatformFile( | 211 } |
229 file_path, | 212 NOTREACHED() << "Subclasses must provide implementation if they have no" |
230 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE, | 213 << "underlying_file_util"; |
231 NULL, | 214 return base::PLATFORM_FILE_ERROR_FAILED; |
232 &error_code); | 215 } |
233 if (error_code != base::PLATFORM_FILE_OK) { | 216 |
234 return error_code; | 217 |
235 } | 218 bool FileSystemFileUtil::PathExists( |
236 DCHECK_NE(base::kInvalidPlatformFileValue, file); | 219 FileSystemOperationContext* context, |
237 if (!base::TruncatePlatformFile(file, length)) | 220 const FilePath& file_path) { |
238 error_code = base::PLATFORM_FILE_ERROR_FAILED; | 221 if (underlying_file_util_.get()) { |
239 base::ClosePlatformFile(file); | 222 return underlying_file_util_->PathExists(context, file_path); |
240 return error_code; | 223 } |
| 224 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 225 << "underlying_file_util"; |
| 226 return false; |
| 227 } |
| 228 |
| 229 bool FileSystemFileUtil::DirectoryExists( |
| 230 FileSystemOperationContext* context, |
| 231 const FilePath& file_path) { |
| 232 if (underlying_file_util_.get()) { |
| 233 return underlying_file_util_->DirectoryExists(context, file_path); |
| 234 } |
| 235 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 236 << "underlying_file_util"; |
| 237 return false; |
| 238 } |
| 239 |
| 240 bool FileSystemFileUtil::IsDirectoryEmpty( |
| 241 FileSystemOperationContext* context, |
| 242 const FilePath& file_path) { |
| 243 if (underlying_file_util_.get()) { |
| 244 return underlying_file_util_->IsDirectoryEmpty(context, file_path); |
| 245 } |
| 246 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 247 << "underlying_file_util"; |
| 248 return false; |
| 249 } |
| 250 |
| 251 PlatformFileError FileSystemFileUtil::CopyOrMoveFile( |
| 252 FileSystemOperationContext* context, |
| 253 const FilePath& src_file_path, |
| 254 const FilePath& dest_file_path, |
| 255 bool copy) { |
| 256 if (underlying_file_util_.get()) { |
| 257 return underlying_file_util_->CopyOrMoveFile( |
| 258 context, src_file_path, dest_file_path, copy); |
| 259 } |
| 260 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 261 << "underlying_file_util"; |
| 262 return base::PLATFORM_FILE_ERROR_FAILED; |
| 263 } |
| 264 |
| 265 PlatformFileError FileSystemFileUtil::CopyInForeignFile( |
| 266 FileSystemOperationContext* context, |
| 267 const FilePath& src_file_path, |
| 268 const FilePath& dest_file_path) { |
| 269 if (underlying_file_util_.get()) { |
| 270 return underlying_file_util_->CopyInForeignFile( |
| 271 context, src_file_path, dest_file_path); |
| 272 } |
| 273 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 274 << "underlying_file_util"; |
| 275 return base::PLATFORM_FILE_ERROR_FAILED; |
| 276 } |
| 277 |
| 278 PlatformFileError FileSystemFileUtil::DeleteFile( |
| 279 FileSystemOperationContext* context, |
| 280 const FilePath& file_path) { |
| 281 if (underlying_file_util_.get()) { |
| 282 return underlying_file_util_->DeleteFile(context, file_path); |
| 283 } |
| 284 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 285 << "underlying_file_util"; |
| 286 return base::PLATFORM_FILE_ERROR_FAILED; |
| 287 } |
| 288 |
| 289 PlatformFileError FileSystemFileUtil::DeleteSingleDirectory( |
| 290 FileSystemOperationContext* context, |
| 291 const FilePath& file_path) { |
| 292 if (underlying_file_util_.get()) { |
| 293 return underlying_file_util_->DeleteSingleDirectory(context, file_path); |
| 294 } |
| 295 NOTREACHED() << "Subclasses must provide implementation if they have no" |
| 296 << "underlying_file_util"; |
| 297 return base::PLATFORM_FILE_ERROR_FAILED; |
241 } | 298 } |
242 | 299 |
243 PlatformFileError | 300 PlatformFileError |
244 FileSystemFileUtil::PerformCommonCheckAndPreparationForMoveAndCopy( | 301 FileSystemFileUtil::PerformCommonCheckAndPreparationForMoveAndCopy( |
245 FileSystemOperationContext* context, | 302 FileSystemOperationContext* context, |
246 const FilePath& src_file_path, | 303 const FilePath& src_file_path, |
247 const FilePath& dest_file_path) { | 304 const FilePath& dest_file_path) { |
248 bool same_file_system = | 305 bool same_file_system = |
249 (context->src_origin_url() == context->dest_origin_url()) && | 306 (context->src_origin_url() == context->dest_origin_url()) && |
250 (context->src_type() == context->dest_type()); | 307 (context->src_type() == context->dest_type()); |
251 FileSystemFileUtil* dest_util = context->dest_file_system_file_util(); | 308 FileSystemFileUtil* dest_util = context->dest_file_util(); |
252 DCHECK(dest_util); | 309 DCHECK(dest_util); |
253 scoped_ptr<FileSystemOperationContext> local_dest_context; | 310 scoped_ptr<FileSystemOperationContext> local_dest_context; |
254 FileSystemOperationContext* dest_context = NULL; | 311 FileSystemOperationContext* dest_context = NULL; |
255 if (same_file_system) { | 312 if (same_file_system) { |
256 dest_context = context; | 313 dest_context = context; |
257 DCHECK(context->src_file_system_file_util() == | 314 DCHECK(context->src_file_util() == context->dest_file_util()); |
258 context->dest_file_system_file_util()); | |
259 } else { | 315 } else { |
260 local_dest_context.reset(context->CreateInheritedContextForDest()); | 316 local_dest_context.reset(context->CreateInheritedContextForDest()); |
261 // All the single-path virtual FSFU methods expect the context information | 317 // All the single-path virtual FSFU methods expect the context information |
262 // to be in the src_* variables, not the dest_* variables, so we have to | 318 // to be in the src_* variables, not the dest_* variables, so we have to |
263 // make a new context if we want to call them on the dest_file_path. | 319 // make a new context if we want to call them on the dest_file_path. |
264 dest_context = local_dest_context.get(); | 320 dest_context = local_dest_context.get(); |
265 } | 321 } |
266 | 322 |
267 // Exits earlier if the source path does not exist. | 323 // Exits earlier if the source path does not exist. |
268 if (!PathExists(context, src_file_path)) | 324 if (!PathExists(context, src_file_path)) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; | 366 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; |
311 return base::PLATFORM_FILE_ERROR_FAILED; | 367 return base::PLATFORM_FILE_ERROR_FAILED; |
312 } | 368 } |
313 // Reflect changes in usage back to the original context. | 369 // Reflect changes in usage back to the original context. |
314 if (!same_file_system) | 370 if (!same_file_system) |
315 context->set_allowed_bytes_growth(dest_context->allowed_bytes_growth()); | 371 context->set_allowed_bytes_growth(dest_context->allowed_bytes_growth()); |
316 } | 372 } |
317 return base::PLATFORM_FILE_OK; | 373 return base::PLATFORM_FILE_OK; |
318 } | 374 } |
319 | 375 |
320 PlatformFileError FileSystemFileUtil::CopyOrMoveFile( | |
321 FileSystemOperationContext* unused, | |
322 const FilePath& src_file_path, | |
323 const FilePath& dest_file_path, | |
324 bool copy) { | |
325 if (copy) { | |
326 if (file_util::CopyFile(src_file_path, dest_file_path)) | |
327 return base::PLATFORM_FILE_OK; | |
328 } else { | |
329 DCHECK(!file_util::DirectoryExists(src_file_path)); | |
330 if (file_util::Move(src_file_path, dest_file_path)) | |
331 return base::PLATFORM_FILE_OK; | |
332 } | |
333 return base::PLATFORM_FILE_ERROR_FAILED; | |
334 } | |
335 | |
336 PlatformFileError FileSystemFileUtil::CopyInForeignFile( | |
337 FileSystemOperationContext* context, | |
338 const FilePath& src_file_path, | |
339 const FilePath& dest_file_path) { | |
340 return CopyOrMoveFile(context, src_file_path, dest_file_path, true); | |
341 } | |
342 | |
343 PlatformFileError FileSystemFileUtil::CopyOrMoveDirectory( | 376 PlatformFileError FileSystemFileUtil::CopyOrMoveDirectory( |
344 FileSystemOperationContext* context, | 377 FileSystemOperationContext* context, |
345 const FilePath& src_file_path, | 378 const FilePath& src_file_path, |
346 const FilePath& dest_file_path, | 379 const FilePath& dest_file_path, |
347 bool copy) { | 380 bool copy) { |
348 FileSystemFileUtil* dest_util = context->dest_file_system_file_util(); | 381 FileSystemFileUtil* dest_util = context->dest_file_util(); |
349 // All the single-path virtual FSFU methods expect the context information to | 382 // All the single-path virtual FSFU methods expect the context information to |
350 // be in the src_* variables, not the dest_* variables, so we have to make a | 383 // be in the src_* variables, not the dest_* variables, so we have to make a |
351 // new context if we want to call them on the dest_file_path. | 384 // new context if we want to call them on the dest_file_path. |
352 scoped_ptr<FileSystemOperationContext> dest_context( | 385 scoped_ptr<FileSystemOperationContext> dest_context( |
353 context->CreateInheritedContextForDest()); | 386 context->CreateInheritedContextForDest()); |
354 | 387 |
355 // Re-check PerformCommonCheckAndPreparationForMoveAndCopy() by DCHECK. | 388 // Re-check PerformCommonCheckAndPreparationForMoveAndCopy() by DCHECK. |
356 DCHECK(DirectoryExists(context, src_file_path)); | 389 DCHECK(DirectoryExists(context, src_file_path)); |
357 DCHECK(ParentExists(dest_context.get(), dest_util, dest_file_path)); | 390 DCHECK(ParentExists(dest_context.get(), dest_util, dest_file_path)); |
358 DCHECK(!dest_util->PathExists(dest_context.get(), dest_file_path)); | 391 DCHECK(!dest_util->PathExists(dest_context.get(), dest_file_path)); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 } | 434 } |
402 | 435 |
403 PlatformFileError FileSystemFileUtil::CopyOrMoveFileHelper( | 436 PlatformFileError FileSystemFileUtil::CopyOrMoveFileHelper( |
404 FileSystemOperationContext* context, | 437 FileSystemOperationContext* context, |
405 const FilePath& src_file_path, | 438 const FilePath& src_file_path, |
406 const FilePath& dest_file_path, | 439 const FilePath& dest_file_path, |
407 bool copy) { | 440 bool copy) { |
408 // CopyOrMoveFile here is the virtual overridden member function. | 441 // CopyOrMoveFile here is the virtual overridden member function. |
409 if ((context->src_origin_url() == context->dest_origin_url()) && | 442 if ((context->src_origin_url() == context->dest_origin_url()) && |
410 (context->src_type() == context->dest_type())) { | 443 (context->src_type() == context->dest_type())) { |
411 DCHECK(context->src_file_system_file_util() == | 444 DCHECK(context->src_file_util() == context->dest_file_util()); |
412 context->dest_file_system_file_util()); | |
413 return CopyOrMoveFile(context, src_file_path, dest_file_path, copy); | 445 return CopyOrMoveFile(context, src_file_path, dest_file_path, copy); |
414 } | 446 } |
415 base::PlatformFileInfo file_info; | 447 base::PlatformFileInfo file_info; |
416 FilePath platform_file_path; | 448 FilePath platform_file_path; |
417 PlatformFileError error_code; | 449 PlatformFileError error_code; |
418 error_code = | 450 error_code = |
419 GetFileInfo(context, src_file_path, &file_info, &platform_file_path); | 451 GetFileInfo(context, src_file_path, &file_info, &platform_file_path); |
420 if (error_code != base::PLATFORM_FILE_OK) | 452 if (error_code != base::PLATFORM_FILE_OK) |
421 return error_code; | 453 return error_code; |
422 | 454 |
423 DCHECK(context->dest_file_system_file_util()); | 455 DCHECK(context->dest_file_util()); |
424 error_code = context->dest_file_system_file_util()->CopyInForeignFile( | 456 error_code = context->dest_file_util()->CopyInForeignFile( |
425 context, platform_file_path, dest_file_path); | 457 context, platform_file_path, dest_file_path); |
426 if (copy || error_code != base::PLATFORM_FILE_OK) | 458 if (copy || error_code != base::PLATFORM_FILE_OK) |
427 return error_code; | 459 return error_code; |
428 return DeleteFile(context, src_file_path); | 460 return DeleteFile(context, src_file_path); |
429 } | 461 } |
430 | 462 |
431 | |
432 PlatformFileError FileSystemFileUtil::DeleteFile( | |
433 FileSystemOperationContext* unused, | |
434 const FilePath& file_path) { | |
435 if (!file_util::PathExists(file_path)) | |
436 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
437 if (file_util::DirectoryExists(file_path)) | |
438 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; | |
439 if (!file_util::Delete(file_path, false)) | |
440 return base::PLATFORM_FILE_ERROR_FAILED; | |
441 return base::PLATFORM_FILE_OK; | |
442 } | |
443 | |
444 PlatformFileError FileSystemFileUtil::DeleteSingleDirectory( | |
445 FileSystemOperationContext* unused, | |
446 const FilePath& file_path) { | |
447 if (!file_util::PathExists(file_path)) | |
448 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
449 if (!file_util::DirectoryExists(file_path)) { | |
450 // TODO(dmikurube): Check if this error code is appropriate. | |
451 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | |
452 } | |
453 if (!file_util::IsDirectoryEmpty(file_path)) { | |
454 // TODO(dmikurube): Check if this error code is appropriate. | |
455 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; | |
456 } | |
457 if (!file_util::Delete(file_path, false)) | |
458 return base::PLATFORM_FILE_ERROR_FAILED; | |
459 return base::PLATFORM_FILE_OK; | |
460 } | |
461 | |
462 PlatformFileError FileSystemFileUtil::DeleteDirectoryRecursive( | 463 PlatformFileError FileSystemFileUtil::DeleteDirectoryRecursive( |
463 FileSystemOperationContext* context, | 464 FileSystemOperationContext* context, |
464 const FilePath& file_path) { | 465 const FilePath& file_path) { |
465 scoped_ptr<AbstractFileEnumerator> file_enum( | 466 scoped_ptr<AbstractFileEnumerator> file_enum( |
466 CreateFileEnumerator(context, file_path)); | 467 CreateFileEnumerator(context, file_path)); |
467 FilePath file_path_each; | 468 FilePath file_path_each; |
468 | 469 |
469 std::stack<FilePath> directories; | 470 std::stack<FilePath> directories; |
470 while (!(file_path_each = file_enum->Next()).empty()) { | 471 while (!(file_path_each = file_enum->Next()).empty()) { |
471 if (file_enum->IsDirectory()) { | 472 if (file_enum->IsDirectory()) { |
(...skipping 12 matching lines...) Expand all Loading... |
484 PlatformFileError error = DeleteSingleDirectory(context, directories.top()); | 485 PlatformFileError error = DeleteSingleDirectory(context, directories.top()); |
485 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) | 486 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) |
486 return base::PLATFORM_FILE_ERROR_FAILED; | 487 return base::PLATFORM_FILE_ERROR_FAILED; |
487 else if (error != base::PLATFORM_FILE_OK) | 488 else if (error != base::PLATFORM_FILE_OK) |
488 return error; | 489 return error; |
489 directories.pop(); | 490 directories.pop(); |
490 } | 491 } |
491 return DeleteSingleDirectory(context, file_path); | 492 return DeleteSingleDirectory(context, file_path); |
492 } | 493 } |
493 | 494 |
494 bool FileSystemFileUtil::PathExists( | |
495 FileSystemOperationContext* unused, | |
496 const FilePath& file_path) { | |
497 return file_util::PathExists(file_path); | |
498 } | |
499 | |
500 bool FileSystemFileUtil::DirectoryExists( | |
501 FileSystemOperationContext* unused, | |
502 const FilePath& file_path) { | |
503 return file_util::DirectoryExists(file_path); | |
504 } | |
505 | |
506 bool FileSystemFileUtil::IsDirectoryEmpty( | |
507 FileSystemOperationContext* unused, | |
508 const FilePath& file_path) { | |
509 return file_util::IsDirectoryEmpty(file_path); | |
510 } | |
511 | |
512 class FileSystemFileEnumerator | |
513 : public FileSystemFileUtil::AbstractFileEnumerator { | |
514 public: | |
515 FileSystemFileEnumerator(const FilePath& root_path, | |
516 bool recursive, | |
517 file_util::FileEnumerator::FileType file_type) | |
518 : file_enum_(root_path, recursive, file_type) { | |
519 } | |
520 | |
521 ~FileSystemFileEnumerator() {} | |
522 | |
523 virtual FilePath Next(); | |
524 virtual bool IsDirectory(); | |
525 | |
526 private: | |
527 file_util::FileEnumerator file_enum_; | |
528 }; | |
529 | |
530 FilePath FileSystemFileEnumerator::Next() { | |
531 return file_enum_.Next(); | |
532 } | |
533 | |
534 bool FileSystemFileEnumerator::IsDirectory() { | |
535 file_util::FileEnumerator::FindInfo file_util_info; | |
536 file_enum_.GetFindInfo(&file_util_info); | |
537 return file_util::FileEnumerator::IsDirectory(file_util_info); | |
538 } | |
539 | |
540 FileSystemFileUtil::AbstractFileEnumerator* | |
541 FileSystemFileUtil::CreateFileEnumerator( | |
542 FileSystemOperationContext* unused, | |
543 const FilePath& root_path) { | |
544 return new FileSystemFileEnumerator( | |
545 root_path, true, static_cast<file_util::FileEnumerator::FileType>( | |
546 file_util::FileEnumerator::FILES | | |
547 file_util::FileEnumerator::DIRECTORIES)); | |
548 } | |
549 | |
550 } // namespace fileapi | 495 } // namespace fileapi |
OLD | NEW |