Chromium Code Reviews| 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 |