| 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/file_util_helper.h" | 5 #include "webkit/fileapi/file_util_helper.h" |
| 6 | 6 |
| 7 #include <stack> | 7 #include <stack> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "webkit/fileapi/file_system_file_util.h" | 10 #include "webkit/fileapi/file_system_file_util.h" |
| 11 #include "webkit/fileapi/file_system_operation_context.h" | 11 #include "webkit/fileapi/file_system_operation_context.h" |
| 12 #include "webkit/fileapi/file_system_url.h" | 12 #include "webkit/fileapi/file_system_url.h" |
| 13 #include "webkit/fileapi/file_system_util.h" | 13 #include "webkit/fileapi/file_system_util.h" |
| 14 | 14 |
| 15 using base::PlatformFileError; | 15 using base::PlatformFileError; |
| 16 | 16 |
| 17 namespace fileapi { | 17 namespace fileapi { |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 // A helper class to delete a temporary file. | 21 // A helper class to delete a temporary file. |
| 22 class ScopedFileDeleter { | 22 class ScopedFileDeleter { |
| 23 public: | 23 public: |
| 24 explicit ScopedFileDeleter(const FilePath& path) : path_(path) {} | 24 explicit ScopedFileDeleter(const base::FilePath& path) : path_(path) {} |
| 25 ~ScopedFileDeleter() { | 25 ~ScopedFileDeleter() { |
| 26 file_util::Delete(path_, false /* recursive */); | 26 file_util::Delete(path_, false /* recursive */); |
| 27 } | 27 } |
| 28 | 28 |
| 29 private: | 29 private: |
| 30 FilePath path_; | 30 base::FilePath path_; |
| 31 }; | 31 }; |
| 32 | 32 |
| 33 bool IsInRoot(const FileSystemURL& url) { | 33 bool IsInRoot(const FileSystemURL& url) { |
| 34 // If path is in the root, path.DirName() will be ".", | 34 // If path is in the root, path.DirName() will be ".", |
| 35 // since we use paths with no leading '/'. | 35 // since we use paths with no leading '/'. |
| 36 FilePath parent = url.path().DirName(); | 36 base::FilePath parent = url.path().DirName(); |
| 37 return parent.empty() || parent == FilePath(FILE_PATH_LITERAL(".")); | 37 return parent.empty() || parent == base::FilePath(FILE_PATH_LITERAL(".")); |
| 38 } | 38 } |
| 39 | 39 |
| 40 // A helper class for cross-FileUtil Copy/Move operations. | 40 // A helper class for cross-FileUtil Copy/Move operations. |
| 41 class CrossFileUtilHelper { | 41 class CrossFileUtilHelper { |
| 42 public: | 42 public: |
| 43 enum Operation { | 43 enum Operation { |
| 44 OPERATION_COPY, | 44 OPERATION_COPY, |
| 45 OPERATION_MOVE | 45 OPERATION_MOVE |
| 46 }; | 46 }; |
| 47 | 47 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 if (error != base::PLATFORM_FILE_OK) | 153 if (error != base::PLATFORM_FILE_OK) |
| 154 return error; | 154 return error; |
| 155 | 155 |
| 156 typedef std::pair<FileSystemURL, base::Time> MovedDirectoryPair; | 156 typedef std::pair<FileSystemURL, base::Time> MovedDirectoryPair; |
| 157 typedef std::vector<MovedDirectoryPair> MovedDirectories; | 157 typedef std::vector<MovedDirectoryPair> MovedDirectories; |
| 158 MovedDirectories directories; | 158 MovedDirectories directories; |
| 159 | 159 |
| 160 // Store modified timestamp of the root directory. | 160 // Store modified timestamp of the root directory. |
| 161 if (operation_ == OPERATION_MOVE) { | 161 if (operation_ == OPERATION_MOVE) { |
| 162 base::PlatformFileInfo file_info; | 162 base::PlatformFileInfo file_info; |
| 163 FilePath platform_file_path; | 163 base::FilePath platform_file_path; |
| 164 error = src_util_->GetFileInfo( | 164 error = src_util_->GetFileInfo( |
| 165 context_, src_url, &file_info, &platform_file_path); | 165 context_, src_url, &file_info, &platform_file_path); |
| 166 if (error != base::PLATFORM_FILE_OK) | 166 if (error != base::PLATFORM_FILE_OK) |
| 167 return error; | 167 return error; |
| 168 directories.push_back( | 168 directories.push_back( |
| 169 std::make_pair(dest_url, file_info.last_modified)); | 169 std::make_pair(dest_url, file_info.last_modified)); |
| 170 } | 170 } |
| 171 | 171 |
| 172 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum( | 172 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum( |
| 173 src_util_->CreateFileEnumerator(context_, | 173 src_util_->CreateFileEnumerator(context_, |
| 174 src_url, | 174 src_url, |
| 175 true /* recursive */)); | 175 true /* recursive */)); |
| 176 FilePath src_file_path_each; | 176 base::FilePath src_file_path_each; |
| 177 while (!(src_file_path_each = file_enum->Next()).empty()) { | 177 while (!(src_file_path_each = file_enum->Next()).empty()) { |
| 178 FilePath dest_file_path_each(dest_url.path()); | 178 base::FilePath dest_file_path_each(dest_url.path()); |
| 179 src_url.path().AppendRelativePath( | 179 src_url.path().AppendRelativePath( |
| 180 src_file_path_each, &dest_file_path_each); | 180 src_file_path_each, &dest_file_path_each); |
| 181 | 181 |
| 182 if (file_enum->IsDirectory()) { | 182 if (file_enum->IsDirectory()) { |
| 183 error = dest_util_->CreateDirectory( | 183 error = dest_util_->CreateDirectory( |
| 184 context_, | 184 context_, |
| 185 dest_url.WithPath(dest_file_path_each), | 185 dest_url.WithPath(dest_file_path_each), |
| 186 true /* exclusive */, false /* recursive */); | 186 true /* exclusive */, false /* recursive */); |
| 187 if (error != base::PLATFORM_FILE_OK) | 187 if (error != base::PLATFORM_FILE_OK) |
| 188 return error; | 188 return error; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 if (same_file_system_) { | 222 if (same_file_system_) { |
| 223 DCHECK(src_util_ == dest_util_); | 223 DCHECK(src_util_ == dest_util_); |
| 224 // Source and destination are in the same FileSystemFileUtil; now we can | 224 // Source and destination are in the same FileSystemFileUtil; now we can |
| 225 // safely call FileSystemFileUtil method on src_util_ (== dest_util_). | 225 // safely call FileSystemFileUtil method on src_util_ (== dest_util_). |
| 226 return src_util_->CopyOrMoveFile(context_, src_url, dest_url, | 226 return src_util_->CopyOrMoveFile(context_, src_url, dest_url, |
| 227 operation_ == OPERATION_COPY); | 227 operation_ == OPERATION_COPY); |
| 228 } | 228 } |
| 229 | 229 |
| 230 // Resolve the src_url's underlying file path. | 230 // Resolve the src_url's underlying file path. |
| 231 base::PlatformFileInfo file_info; | 231 base::PlatformFileInfo file_info; |
| 232 FilePath platform_file_path; | 232 base::FilePath platform_file_path; |
| 233 SnapshotFilePolicy snapshot_policy; | 233 SnapshotFilePolicy snapshot_policy; |
| 234 | 234 |
| 235 PlatformFileError error = src_util_->CreateSnapshotFile( | 235 PlatformFileError error = src_util_->CreateSnapshotFile( |
| 236 context_, src_url, &file_info, &platform_file_path, &snapshot_policy); | 236 context_, src_url, &file_info, &platform_file_path, &snapshot_policy); |
| 237 if (error != base::PLATFORM_FILE_OK) | 237 if (error != base::PLATFORM_FILE_OK) |
| 238 return error; | 238 return error; |
| 239 | 239 |
| 240 // For now we don't support non-snapshot file case. | 240 // For now we don't support non-snapshot file case. |
| 241 // TODO(kinuko): Address this case too. | 241 // TODO(kinuko): Address this case too. |
| 242 DCHECK(!platform_file_path.empty()); | 242 DCHECK(!platform_file_path.empty()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 258 } // anonymous namespace | 258 } // anonymous namespace |
| 259 | 259 |
| 260 // static | 260 // static |
| 261 bool FileUtilHelper::DirectoryExists(FileSystemOperationContext* context, | 261 bool FileUtilHelper::DirectoryExists(FileSystemOperationContext* context, |
| 262 FileSystemFileUtil* file_util, | 262 FileSystemFileUtil* file_util, |
| 263 const FileSystemURL& url) { | 263 const FileSystemURL& url) { |
| 264 if (url.path().empty()) | 264 if (url.path().empty()) |
| 265 return true; | 265 return true; |
| 266 | 266 |
| 267 base::PlatformFileInfo file_info; | 267 base::PlatformFileInfo file_info; |
| 268 FilePath platform_path; | 268 base::FilePath platform_path; |
| 269 PlatformFileError error = file_util->GetFileInfo( | 269 PlatformFileError error = file_util->GetFileInfo( |
| 270 context, url, &file_info, &platform_path); | 270 context, url, &file_info, &platform_path); |
| 271 return error == base::PLATFORM_FILE_OK && file_info.is_directory; | 271 return error == base::PLATFORM_FILE_OK && file_info.is_directory; |
| 272 } | 272 } |
| 273 | 273 |
| 274 // static | 274 // static |
| 275 base::PlatformFileError FileUtilHelper::Copy( | 275 base::PlatformFileError FileUtilHelper::Copy( |
| 276 FileSystemOperationContext* context, | 276 FileSystemOperationContext* context, |
| 277 FileSystemFileUtil* src_file_util, | 277 FileSystemFileUtil* src_file_util, |
| 278 FileSystemFileUtil* dest_file_util, | 278 FileSystemFileUtil* dest_file_util, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 | 313 |
| 314 // static | 314 // static |
| 315 base::PlatformFileError FileUtilHelper::ReadDirectory( | 315 base::PlatformFileError FileUtilHelper::ReadDirectory( |
| 316 FileSystemOperationContext* context, | 316 FileSystemOperationContext* context, |
| 317 FileSystemFileUtil* file_util, | 317 FileSystemFileUtil* file_util, |
| 318 const FileSystemURL& url, | 318 const FileSystemURL& url, |
| 319 std::vector<base::FileUtilProxy::Entry>* entries) { | 319 std::vector<base::FileUtilProxy::Entry>* entries) { |
| 320 DCHECK(entries); | 320 DCHECK(entries); |
| 321 | 321 |
| 322 base::PlatformFileInfo file_info; | 322 base::PlatformFileInfo file_info; |
| 323 FilePath platform_path; | 323 base::FilePath platform_path; |
| 324 PlatformFileError error = file_util->GetFileInfo( | 324 PlatformFileError error = file_util->GetFileInfo( |
| 325 context, url, &file_info, &platform_path); | 325 context, url, &file_info, &platform_path); |
| 326 if (error != base::PLATFORM_FILE_OK) | 326 if (error != base::PLATFORM_FILE_OK) |
| 327 return error; | 327 return error; |
| 328 if (!file_info.is_directory) | 328 if (!file_info.is_directory) |
| 329 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | 329 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
| 330 | 330 |
| 331 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum( | 331 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum( |
| 332 file_util->CreateFileEnumerator(context, url, false /* recursive */)); | 332 file_util->CreateFileEnumerator(context, url, false /* recursive */)); |
| 333 | 333 |
| 334 FilePath current; | 334 base::FilePath current; |
| 335 while (!(current = file_enum->Next()).empty()) { | 335 while (!(current = file_enum->Next()).empty()) { |
| 336 base::FileUtilProxy::Entry entry; | 336 base::FileUtilProxy::Entry entry; |
| 337 entry.is_directory = file_enum->IsDirectory(); | 337 entry.is_directory = file_enum->IsDirectory(); |
| 338 entry.name = VirtualPath::BaseName(current).value(); | 338 entry.name = VirtualPath::BaseName(current).value(); |
| 339 entry.size = file_enum->Size(); | 339 entry.size = file_enum->Size(); |
| 340 entry.last_modified_time = file_enum->LastModifiedTime(); | 340 entry.last_modified_time = file_enum->LastModifiedTime(); |
| 341 entries->push_back(entry); | 341 entries->push_back(entry); |
| 342 } | 342 } |
| 343 return base::PLATFORM_FILE_OK; | 343 return base::PLATFORM_FILE_OK; |
| 344 } | 344 } |
| 345 | 345 |
| 346 // static | 346 // static |
| 347 base::PlatformFileError FileUtilHelper::DeleteDirectoryRecursive( | 347 base::PlatformFileError FileUtilHelper::DeleteDirectoryRecursive( |
| 348 FileSystemOperationContext* context, | 348 FileSystemOperationContext* context, |
| 349 FileSystemFileUtil* file_util, | 349 FileSystemFileUtil* file_util, |
| 350 const FileSystemURL& url) { | 350 const FileSystemURL& url) { |
| 351 | 351 |
| 352 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum( | 352 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum( |
| 353 file_util->CreateFileEnumerator(context, url, true /* recursive */)); | 353 file_util->CreateFileEnumerator(context, url, true /* recursive */)); |
| 354 FilePath file_path_each; | 354 base::FilePath file_path_each; |
| 355 std::stack<FilePath> directories; | 355 std::stack<base::FilePath> directories; |
| 356 while (!(file_path_each = file_enum->Next()).empty()) { | 356 while (!(file_path_each = file_enum->Next()).empty()) { |
| 357 if (file_enum->IsDirectory()) { | 357 if (file_enum->IsDirectory()) { |
| 358 directories.push(file_path_each); | 358 directories.push(file_path_each); |
| 359 } else { | 359 } else { |
| 360 PlatformFileError error = file_util->DeleteFile( | 360 PlatformFileError error = file_util->DeleteFile( |
| 361 context, url.WithPath(file_path_each)); | 361 context, url.WithPath(file_path_each)); |
| 362 if (error != base::PLATFORM_FILE_ERROR_NOT_FOUND && | 362 if (error != base::PLATFORM_FILE_ERROR_NOT_FOUND && |
| 363 error != base::PLATFORM_FILE_OK) | 363 error != base::PLATFORM_FILE_OK) |
| 364 return error; | 364 return error; |
| 365 } | 365 } |
| 366 } | 366 } |
| 367 | 367 |
| 368 while (!directories.empty()) { | 368 while (!directories.empty()) { |
| 369 PlatformFileError error = file_util->DeleteDirectory( | 369 PlatformFileError error = file_util->DeleteDirectory( |
| 370 context, url.WithPath(directories.top())); | 370 context, url.WithPath(directories.top())); |
| 371 if (error != base::PLATFORM_FILE_ERROR_NOT_FOUND && | 371 if (error != base::PLATFORM_FILE_ERROR_NOT_FOUND && |
| 372 error != base::PLATFORM_FILE_OK) | 372 error != base::PLATFORM_FILE_OK) |
| 373 return error; | 373 return error; |
| 374 directories.pop(); | 374 directories.pop(); |
| 375 } | 375 } |
| 376 return file_util->DeleteDirectory(context, url); | 376 return file_util->DeleteDirectory(context, url); |
| 377 } | 377 } |
| 378 | 378 |
| 379 } // namespace fileapi | 379 } // namespace fileapi |
| OLD | NEW |