| OLD | NEW |
| 1 // Copyright (c) 2010 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/obfuscated_file_util_proxy.h" |
| 6 |
| 5 #include "base/file_util_proxy.h" | 7 #include "base/file_util_proxy.h" |
| 6 | |
| 7 #include "base/message_loop_proxy.h" | 8 #include "base/message_loop_proxy.h" |
| 8 | 9 #include "webkit/fileapi/file_system_path_manager.h" |
| 9 // TODO(jianli): Move the code from anonymous namespace to base namespace so | 10 #include "webkit/fileapi/obfuscated_file_util.h" |
| 10 // that all of the base:: prefixes would be unnecessary. | 11 #include "webkit/fileapi/sandboxed_file_system_context.h" |
| 11 namespace { | |
| 12 | 12 |
| 13 namespace { | 13 namespace { |
| 14 | 14 |
| 15 // Performs common checks for move and copy. | |
| 16 // This also removes the destination directory if it's non-empty and all other | |
| 17 // checks are passed (so that the copy/move correctly overwrites the | |
| 18 // destination). | |
| 19 static base::PlatformFileError PerformCommonCheckAndPreparationForMoveAndCopy( | |
| 20 const FilePath& src_file_path, | |
| 21 const FilePath& dest_file_path) { | |
| 22 // Exits earlier if the source path does not exist. | |
| 23 if (!file_util::PathExists(src_file_path)) | |
| 24 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
| 25 | |
| 26 // The parent of the |dest_file_path| does not exist. | |
| 27 if (!file_util::DirectoryExists(dest_file_path.DirName())) | |
| 28 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
| 29 | |
| 30 // It is an error to try to copy/move an entry into its child. | |
| 31 if (src_file_path.IsParent(dest_file_path)) | |
| 32 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; | |
| 33 | |
| 34 // Now it is ok to return if the |dest_file_path| does not exist. | |
| 35 if (!file_util::PathExists(dest_file_path)) | |
| 36 return base::PLATFORM_FILE_OK; | |
| 37 | |
| 38 // |src_file_path| exists and is a directory. | |
| 39 // |dest_file_path| exists and is a file. | |
| 40 bool src_is_directory = file_util::DirectoryExists(src_file_path); | |
| 41 bool dest_is_directory = file_util::DirectoryExists(dest_file_path); | |
| 42 if (src_is_directory && !dest_is_directory) | |
| 43 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | |
| 44 | |
| 45 // |src_file_path| exists and is a file. | |
| 46 // |dest_file_path| exists and is a directory. | |
| 47 if (!src_is_directory && dest_is_directory) | |
| 48 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; | |
| 49 | |
| 50 // It is an error to copy/move an entry into the same path. | |
| 51 if (src_file_path.value() == dest_file_path.value()) | |
| 52 return base::PLATFORM_FILE_ERROR_EXISTS; | |
| 53 | |
| 54 if (dest_is_directory) { | |
| 55 // It is an error to copy/move an entry to a non-empty directory. | |
| 56 // Otherwise the copy/move attempt must overwrite the destination, but | |
| 57 // the file_util's Copy or Move method doesn't perform overwrite | |
| 58 // on all platforms, so we delete the destination directory here. | |
| 59 // TODO(kinuko): may be better to change the file_util::{Copy,Move}. | |
| 60 if (!file_util::Delete(dest_file_path, false /* recursive */)) { | |
| 61 if (!file_util::IsDirectoryEmpty(dest_file_path)) | |
| 62 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; | |
| 63 return base::PLATFORM_FILE_ERROR_FAILED; | |
| 64 } | |
| 65 } | |
| 66 return base::PLATFORM_FILE_OK; | |
| 67 } | |
| 68 | |
| 69 } // anonymous namespace | |
| 70 | |
| 71 class MessageLoopRelay | 15 class MessageLoopRelay |
| 72 : public base::RefCountedThreadSafe<MessageLoopRelay> { | 16 : public base::RefCountedThreadSafe<MessageLoopRelay> { |
| 73 public: | 17 public: |
| 74 MessageLoopRelay() | 18 MessageLoopRelay() |
| 75 : origin_message_loop_proxy_( | 19 : origin_message_loop_proxy_( |
| 76 base::MessageLoopProxy::CreateForCurrentThread()), | 20 base::MessageLoopProxy::CreateForCurrentThread()), |
| 77 error_code_(base::PLATFORM_FILE_OK) { | 21 error_code_(base::PLATFORM_FILE_OK) { |
| 78 } | 22 } |
| 79 | 23 |
| 80 bool Start(scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | 24 bool Start(scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 111 } | 55 } |
| 112 | 56 |
| 113 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; | 57 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; |
| 114 base::PlatformFileError error_code_; | 58 base::PlatformFileError error_code_; |
| 115 }; | 59 }; |
| 116 | 60 |
| 117 class RelayCreateOrOpen : public MessageLoopRelay { | 61 class RelayCreateOrOpen : public MessageLoopRelay { |
| 118 public: | 62 public: |
| 119 RelayCreateOrOpen( | 63 RelayCreateOrOpen( |
| 120 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | 64 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
| 121 const FilePath& file_path, | 65 const FilePath& root_path, |
| 66 const FilePath& virtual_path, |
| 122 int file_flags, | 67 int file_flags, |
| 123 base::FileUtilProxy::CreateOrOpenCallback* callback) | 68 base::FileUtilProxyBase::CreateOrOpenCallback* callback) |
| 124 : message_loop_proxy_(message_loop_proxy), | 69 : message_loop_proxy_(message_loop_proxy), |
| 125 file_path_(file_path), | 70 root_path_(root_path), |
| 71 virtual_path_(virtual_path), |
| 126 file_flags_(file_flags), | 72 file_flags_(file_flags), |
| 127 callback_(callback), | 73 callback_(callback), |
| 128 file_handle_(base::kInvalidPlatformFileValue), | 74 file_handle_(base::kInvalidPlatformFileValue), |
| 129 created_(false) { | 75 created_(false) { |
| 130 DCHECK(callback); | 76 DCHECK(callback); |
| 131 } | 77 } |
| 132 | 78 |
| 133 protected: | 79 protected: |
| 134 virtual ~RelayCreateOrOpen() { | 80 virtual ~RelayCreateOrOpen() { |
| 135 if (file_handle_ != base::kInvalidPlatformFileValue) | 81 if (file_handle_ != base::kInvalidPlatformFileValue) |
| 136 base::FileUtilProxy::Close(message_loop_proxy_, file_handle_, NULL); | 82 base::FileUtilProxy::GetInstance()->Close( |
| 83 message_loop_proxy_, file_handle_, NULL); |
| 137 } | 84 } |
| 138 | 85 |
| 139 virtual void RunWork() { | 86 virtual void RunWork() { |
| 140 if (!file_util::DirectoryExists(file_path_.DirName())) { | |
| 141 // If its parent does not exist, should return NOT_FOUND error. | |
| 142 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); | |
| 143 return; | |
| 144 } | |
| 145 base::PlatformFileError error_code = base::PLATFORM_FILE_OK; | 87 base::PlatformFileError error_code = base::PLATFORM_FILE_OK; |
| 146 file_handle_ = base::CreatePlatformFile(file_path_, file_flags_, | 88 file_handle_ = obfuscated_file_util::CreateOrOpen( |
| 147 &created_, &error_code); | 89 root_path_, virtual_path_, file_flags_, &created_, &error_code); |
| 148 set_error_code(error_code); | 90 set_error_code(error_code); |
| 149 } | 91 } |
| 150 | 92 |
| 151 virtual void RunCallback() { | 93 virtual void RunCallback() { |
| 152 callback_->Run(error_code(), base::PassPlatformFile(&file_handle_), | 94 callback_->Run(error_code(), base::PassPlatformFile(&file_handle_), |
| 153 created_); | 95 created_); |
| 154 delete callback_; | 96 delete callback_; |
| 155 } | 97 } |
| 156 | 98 |
| 157 private: | 99 private: |
| 158 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | 100 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; |
| 159 FilePath file_path_; | 101 FilePath root_path_; |
| 102 FilePath virtual_path_; |
| 160 int file_flags_; | 103 int file_flags_; |
| 161 base::FileUtilProxy::CreateOrOpenCallback* callback_; | 104 base::FileUtilProxyBase::CreateOrOpenCallback* callback_; |
| 162 base::PlatformFile file_handle_; | 105 base::PlatformFile file_handle_; |
| 163 bool created_; | 106 bool created_; |
| 164 }; | 107 }; |
| 165 | 108 |
| 166 class RelayCreateTemporary : public MessageLoopRelay { | |
| 167 public: | |
| 168 RelayCreateTemporary( | |
| 169 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | |
| 170 base::FileUtilProxy::CreateTemporaryCallback* callback) | |
| 171 : message_loop_proxy_(message_loop_proxy), | |
| 172 callback_(callback), | |
| 173 file_handle_(base::kInvalidPlatformFileValue) { | |
| 174 DCHECK(callback); | |
| 175 } | |
| 176 | |
| 177 protected: | |
| 178 virtual ~RelayCreateTemporary() { | |
| 179 if (file_handle_ != base::kInvalidPlatformFileValue) | |
| 180 base::FileUtilProxy::Close(message_loop_proxy_, file_handle_, NULL); | |
| 181 } | |
| 182 | |
| 183 virtual void RunWork() { | |
| 184 // TODO(darin): file_util should have a variant of CreateTemporaryFile | |
| 185 // that returns a FilePath and a PlatformFile. | |
| 186 file_util::CreateTemporaryFile(&file_path_); | |
| 187 | |
| 188 // Use a fixed set of flags that are appropriate for writing to a temporary | |
| 189 // file from the IO thread using a net::FileStream. | |
| 190 int file_flags = | |
| 191 base::PLATFORM_FILE_CREATE_ALWAYS | | |
| 192 base::PLATFORM_FILE_WRITE | | |
| 193 base::PLATFORM_FILE_ASYNC | | |
| 194 base::PLATFORM_FILE_TEMPORARY; | |
| 195 base::PlatformFileError error_code = base::PLATFORM_FILE_OK; | |
| 196 file_handle_ = base::CreatePlatformFile(file_path_, file_flags, | |
| 197 NULL, &error_code); | |
| 198 set_error_code(error_code); | |
| 199 } | |
| 200 | |
| 201 virtual void RunCallback() { | |
| 202 callback_->Run(error_code(), base::PassPlatformFile(&file_handle_), | |
| 203 file_path_); | |
| 204 delete callback_; | |
| 205 } | |
| 206 | |
| 207 private: | |
| 208 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | |
| 209 base::FileUtilProxy::CreateTemporaryCallback* callback_; | |
| 210 base::PlatformFile file_handle_; | |
| 211 FilePath file_path_; | |
| 212 }; | |
| 213 | |
| 214 class RelayWithStatusCallback : public MessageLoopRelay { | 109 class RelayWithStatusCallback : public MessageLoopRelay { |
| 215 public: | 110 public: |
| 216 explicit RelayWithStatusCallback( | 111 explicit RelayWithStatusCallback( |
| 217 base::FileUtilProxy::StatusCallback* callback) | 112 base::FileUtilProxyBase::StatusCallback* callback) |
| 218 : callback_(callback) { | 113 : callback_(callback) { |
| 219 // It is OK for callback to be NULL. | 114 // It is OK for callback to be NULL. |
| 220 } | 115 } |
| 221 | 116 |
| 222 protected: | 117 protected: |
| 223 virtual void RunCallback() { | 118 virtual void RunCallback() { |
| 224 // The caller may not have been interested in the result. | 119 // The caller may not have been interested in the result. |
| 225 if (callback_) { | 120 if (callback_) { |
| 226 callback_->Run(error_code()); | 121 callback_->Run(error_code()); |
| 227 delete callback_; | 122 delete callback_; |
| 228 } | 123 } |
| 229 } | 124 } |
| 230 | 125 |
| 231 private: | 126 private: |
| 232 base::FileUtilProxy::StatusCallback* callback_; | 127 base::FileUtilProxyBase::StatusCallback* callback_; |
| 233 }; | |
| 234 | |
| 235 class RelayClose : public RelayWithStatusCallback { | |
| 236 public: | |
| 237 RelayClose(base::PlatformFile file_handle, | |
| 238 base::FileUtilProxy::StatusCallback* callback) | |
| 239 : RelayWithStatusCallback(callback), | |
| 240 file_handle_(file_handle) { | |
| 241 } | |
| 242 | |
| 243 protected: | |
| 244 virtual void RunWork() { | |
| 245 if (!base::ClosePlatformFile(file_handle_)) | |
| 246 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 247 } | |
| 248 | |
| 249 private: | |
| 250 base::PlatformFile file_handle_; | |
| 251 }; | |
| 252 | |
| 253 class RelayEnsureFileExists : public MessageLoopRelay { | |
| 254 public: | |
| 255 RelayEnsureFileExists( | |
| 256 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | |
| 257 const FilePath& file_path, | |
| 258 base::FileUtilProxy::EnsureFileExistsCallback* callback) | |
| 259 : message_loop_proxy_(message_loop_proxy), | |
| 260 file_path_(file_path), | |
| 261 callback_(callback), | |
| 262 created_(false) { | |
| 263 DCHECK(callback); | |
| 264 } | |
| 265 | |
| 266 protected: | |
| 267 virtual void RunWork() { | |
| 268 if (!file_util::DirectoryExists(file_path_.DirName())) { | |
| 269 // If its parent does not exist, should return NOT_FOUND error. | |
| 270 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); | |
| 271 return; | |
| 272 } | |
| 273 base::PlatformFileError error_code = base::PLATFORM_FILE_OK; | |
| 274 // Tries to create the |file_path_| exclusively. This should fail | |
| 275 // with PLATFORM_FILE_ERROR_EXISTS if the path already exists. | |
| 276 base::PlatformFile handle = base::CreatePlatformFile( | |
| 277 file_path_, | |
| 278 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_READ, | |
| 279 &created_, &error_code); | |
| 280 if (error_code == base::PLATFORM_FILE_ERROR_EXISTS) { | |
| 281 // Make sure created_ is false. | |
| 282 created_ = false; | |
| 283 error_code = base::PLATFORM_FILE_OK; | |
| 284 } | |
| 285 if (handle != base::kInvalidPlatformFileValue) | |
| 286 base::ClosePlatformFile(handle); | |
| 287 set_error_code(error_code); | |
| 288 } | |
| 289 | |
| 290 virtual void RunCallback() { | |
| 291 callback_->Run(error_code(), created_); | |
| 292 delete callback_; | |
| 293 } | |
| 294 | |
| 295 private: | |
| 296 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | |
| 297 FilePath file_path_; | |
| 298 base::FileUtilProxy::EnsureFileExistsCallback* callback_; | |
| 299 bool created_; | |
| 300 }; | |
| 301 | |
| 302 class RelayDelete : public RelayWithStatusCallback { | |
| 303 public: | |
| 304 RelayDelete(const FilePath& file_path, | |
| 305 bool recursive, | |
| 306 base::FileUtilProxy::StatusCallback* callback) | |
| 307 : RelayWithStatusCallback(callback), | |
| 308 file_path_(file_path), | |
| 309 recursive_(recursive) { | |
| 310 } | |
| 311 | |
| 312 protected: | |
| 313 virtual void RunWork() { | |
| 314 if (!file_util::PathExists(file_path_)) { | |
| 315 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); | |
| 316 return; | |
| 317 } | |
| 318 if (!file_util::Delete(file_path_, recursive_)) { | |
| 319 if (!recursive_ && !file_util::IsDirectoryEmpty(file_path_)) { | |
| 320 set_error_code(base::PLATFORM_FILE_ERROR_NOT_EMPTY); | |
| 321 return; | |
| 322 } | |
| 323 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 324 } | |
| 325 } | |
| 326 | |
| 327 private: | |
| 328 FilePath file_path_; | |
| 329 bool recursive_; | |
| 330 }; | |
| 331 | |
| 332 class RelayCopy : public RelayWithStatusCallback { | |
| 333 public: | |
| 334 RelayCopy(const FilePath& src_file_path, | |
| 335 const FilePath& dest_file_path, | |
| 336 base::FileUtilProxy::StatusCallback* callback) | |
| 337 : RelayWithStatusCallback(callback), | |
| 338 src_file_path_(src_file_path), | |
| 339 dest_file_path_(dest_file_path) { | |
| 340 } | |
| 341 | |
| 342 protected: | |
| 343 virtual void RunWork() { | |
| 344 set_error_code(PerformCommonCheckAndPreparationForMoveAndCopy( | |
| 345 src_file_path_, dest_file_path_)); | |
| 346 if (error_code() != base::PLATFORM_FILE_OK) | |
| 347 return; | |
| 348 if (!file_util::CopyDirectory(src_file_path_, dest_file_path_, | |
| 349 true /* recursive */)) | |
| 350 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 351 } | |
| 352 | |
| 353 private: | |
| 354 FilePath src_file_path_; | |
| 355 FilePath dest_file_path_; | |
| 356 }; | |
| 357 | |
| 358 class RelayMove : public RelayWithStatusCallback { | |
| 359 public: | |
| 360 RelayMove(const FilePath& src_file_path, | |
| 361 const FilePath& dest_file_path, | |
| 362 base::FileUtilProxy::StatusCallback* callback) | |
| 363 : RelayWithStatusCallback(callback), | |
| 364 src_file_path_(src_file_path), | |
| 365 dest_file_path_(dest_file_path) { | |
| 366 } | |
| 367 | |
| 368 protected: | |
| 369 virtual void RunWork() { | |
| 370 set_error_code(PerformCommonCheckAndPreparationForMoveAndCopy( | |
| 371 src_file_path_, dest_file_path_)); | |
| 372 if (error_code() != base::PLATFORM_FILE_OK) | |
| 373 return; | |
| 374 if (!file_util::Move(src_file_path_, dest_file_path_)) | |
| 375 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 376 } | |
| 377 | |
| 378 private: | |
| 379 FilePath src_file_path_; | |
| 380 FilePath dest_file_path_; | |
| 381 }; | 128 }; |
| 382 | 129 |
| 383 class RelayCreateDirectory : public RelayWithStatusCallback { | 130 class RelayCreateDirectory : public RelayWithStatusCallback { |
| 384 public: | 131 public: |
| 385 RelayCreateDirectory( | 132 RelayCreateDirectory( |
| 386 const FilePath& file_path, | 133 const FilePath& root_path, |
| 134 const FilePath& virtual_path, |
| 387 bool exclusive, | 135 bool exclusive, |
| 388 bool recursive, | 136 base::FileUtilProxyBase::StatusCallback* callback) |
| 389 base::FileUtilProxy::StatusCallback* callback) | |
| 390 : RelayWithStatusCallback(callback), | 137 : RelayWithStatusCallback(callback), |
| 391 file_path_(file_path), | 138 root_path_(root_path), |
| 392 exclusive_(exclusive), | 139 virtual_path_(virtual_path), |
| 393 recursive_(recursive) { | 140 exclusive_(exclusive) { |
| 394 } | 141 } |
| 395 | 142 |
| 396 protected: | 143 protected: |
| 397 virtual void RunWork() { | 144 virtual void RunWork() { |
| 398 bool path_exists = file_util::PathExists(file_path_); | 145 base::PlatformFileError error_code; |
| 399 // If parent dir of file doesn't exist. | 146 obfuscated_file_util::CreateDirectory( |
| 400 if (!recursive_ && !file_util::PathExists(file_path_.DirName())) { | 147 root_path_, virtual_path_, exclusive_, &error_code); |
| 401 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); | 148 set_error_code(error_code); |
| 402 return; | |
| 403 } | |
| 404 if (exclusive_ && path_exists) { | |
| 405 set_error_code(base::PLATFORM_FILE_ERROR_EXISTS); | |
| 406 return; | |
| 407 } | |
| 408 // If file exists at the path. | |
| 409 if (path_exists && !file_util::DirectoryExists(file_path_)) { | |
| 410 set_error_code(base::PLATFORM_FILE_ERROR_EXISTS); | |
| 411 return; | |
| 412 } | |
| 413 if (!file_util::CreateDirectory(file_path_)) | |
| 414 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 415 } | 149 } |
| 416 | 150 |
| 417 private: | 151 private: |
| 418 FilePath file_path_; | 152 FilePath root_path_; |
| 153 FilePath virtual_path_; |
| 419 bool exclusive_; | 154 bool exclusive_; |
| 420 bool recursive_; | |
| 421 }; | |
| 422 | |
| 423 class RelayReadDirectory : public MessageLoopRelay { | |
| 424 public: | |
| 425 RelayReadDirectory(const FilePath& file_path, | |
| 426 base::FileUtilProxy::ReadDirectoryCallback* callback) | |
| 427 : callback_(callback), file_path_(file_path) { | |
| 428 DCHECK(callback); | |
| 429 } | |
| 430 | |
| 431 protected: | |
| 432 virtual void RunWork() { | |
| 433 // TODO(kkanetkar): Implement directory read in multiple chunks. | |
| 434 if (!file_util::DirectoryExists(file_path_)) { | |
| 435 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); | |
| 436 return; | |
| 437 } | |
| 438 | |
| 439 file_util::FileEnumerator file_enum( | |
| 440 file_path_, false, static_cast<file_util::FileEnumerator::FILE_TYPE>( | |
| 441 file_util::FileEnumerator::FILES | | |
| 442 file_util::FileEnumerator::DIRECTORIES)); | |
| 443 FilePath current; | |
| 444 while (!(current = file_enum.Next()).empty()) { | |
| 445 base::FileUtilProxy::Entry entry; | |
| 446 file_util::FileEnumerator::FindInfo info; | |
| 447 file_enum.GetFindInfo(&info); | |
| 448 entry.is_directory = file_enum.IsDirectory(info); | |
| 449 // This will just give the entry's name instead of entire path | |
| 450 // if we use current.value(). | |
| 451 entry.name = file_util::FileEnumerator::GetFilename(info).value(); | |
| 452 entries_.push_back(entry); | |
| 453 } | |
| 454 } | |
| 455 | |
| 456 virtual void RunCallback() { | |
| 457 callback_->Run(error_code(), entries_); | |
| 458 delete callback_; | |
| 459 } | |
| 460 | |
| 461 private: | |
| 462 base::FileUtilProxy::ReadDirectoryCallback* callback_; | |
| 463 FilePath file_path_; | |
| 464 std::vector<base::FileUtilProxy::Entry> entries_; | |
| 465 }; | |
| 466 | |
| 467 class RelayGetFileInfo : public MessageLoopRelay { | |
| 468 public: | |
| 469 RelayGetFileInfo(const FilePath& file_path, | |
| 470 base::FileUtilProxy::GetFileInfoCallback* callback) | |
| 471 : callback_(callback), | |
| 472 file_path_(file_path) { | |
| 473 DCHECK(callback); | |
| 474 } | |
| 475 | |
| 476 protected: | |
| 477 virtual void RunWork() { | |
| 478 if (!file_util::PathExists(file_path_)) { | |
| 479 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); | |
| 480 return; | |
| 481 } | |
| 482 if (!file_util::GetFileInfo(file_path_, &file_info_)) | |
| 483 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 484 } | |
| 485 | |
| 486 virtual void RunCallback() { | |
| 487 callback_->Run(error_code(), file_info_); | |
| 488 delete callback_; | |
| 489 } | |
| 490 | |
| 491 private: | |
| 492 base::FileUtilProxy::GetFileInfoCallback* callback_; | |
| 493 FilePath file_path_; | |
| 494 base::PlatformFileInfo file_info_; | |
| 495 }; | |
| 496 | |
| 497 class RelayGetFileInfoFromPlatformFile : public MessageLoopRelay { | |
| 498 public: | |
| 499 RelayGetFileInfoFromPlatformFile( | |
| 500 base::PlatformFile file, | |
| 501 base::FileUtilProxy::GetFileInfoCallback* callback) | |
| 502 : callback_(callback), | |
| 503 file_(file) { | |
| 504 DCHECK(callback); | |
| 505 } | |
| 506 | |
| 507 protected: | |
| 508 virtual void RunWork() { | |
| 509 if (!base::GetPlatformFileInfo(file_, &file_info_)) | |
| 510 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 511 } | |
| 512 | |
| 513 virtual void RunCallback() { | |
| 514 callback_->Run(error_code(), file_info_); | |
| 515 delete callback_; | |
| 516 } | |
| 517 | |
| 518 private: | |
| 519 base::FileUtilProxy::GetFileInfoCallback* callback_; | |
| 520 base::PlatformFile file_; | |
| 521 base::PlatformFileInfo file_info_; | |
| 522 }; | |
| 523 | |
| 524 class RelayRead : public MessageLoopRelay { | |
| 525 public: | |
| 526 RelayRead(base::PlatformFile file, | |
| 527 int64 offset, | |
| 528 char* buffer, | |
| 529 int bytes_to_read, | |
| 530 base::FileUtilProxy::ReadWriteCallback* callback) | |
| 531 : file_(file), | |
| 532 offset_(offset), | |
| 533 buffer_(buffer), | |
| 534 bytes_to_read_(bytes_to_read), | |
| 535 callback_(callback), | |
| 536 bytes_read_(0) { | |
| 537 } | |
| 538 | |
| 539 protected: | |
| 540 virtual void RunWork() { | |
| 541 bytes_read_ = base::ReadPlatformFile(file_, offset_, buffer_, | |
| 542 bytes_to_read_); | |
| 543 if (bytes_read_ < 0) | |
| 544 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 545 } | |
| 546 | |
| 547 virtual void RunCallback() { | |
| 548 if (callback_) { | |
| 549 callback_->Run(error_code(), bytes_read_); | |
| 550 delete callback_; | |
| 551 } | |
| 552 } | |
| 553 | |
| 554 private: | |
| 555 base::PlatformFile file_; | |
| 556 int64 offset_; | |
| 557 char* buffer_; | |
| 558 int bytes_to_read_; | |
| 559 base::FileUtilProxy::ReadWriteCallback* callback_; | |
| 560 int bytes_read_; | |
| 561 }; | |
| 562 | |
| 563 class RelayWrite : public MessageLoopRelay { | |
| 564 public: | |
| 565 RelayWrite(base::PlatformFile file, | |
| 566 int64 offset, | |
| 567 const char* buffer, | |
| 568 int bytes_to_write, | |
| 569 base::FileUtilProxy::ReadWriteCallback* callback) | |
| 570 : file_(file), | |
| 571 offset_(offset), | |
| 572 buffer_(buffer), | |
| 573 bytes_to_write_(bytes_to_write), | |
| 574 callback_(callback) { | |
| 575 } | |
| 576 | |
| 577 protected: | |
| 578 virtual void RunWork() { | |
| 579 bytes_written_ = base::WritePlatformFile(file_, offset_, buffer_, | |
| 580 bytes_to_write_); | |
| 581 if (bytes_written_ < 0) | |
| 582 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 583 } | |
| 584 | |
| 585 virtual void RunCallback() { | |
| 586 if (callback_) { | |
| 587 callback_->Run(error_code(), bytes_written_); | |
| 588 delete callback_; | |
| 589 } | |
| 590 } | |
| 591 | |
| 592 private: | |
| 593 base::PlatformFile file_; | |
| 594 int64 offset_; | |
| 595 const char* buffer_; | |
| 596 int bytes_to_write_; | |
| 597 base::FileUtilProxy::ReadWriteCallback* callback_; | |
| 598 int bytes_written_; | |
| 599 }; | |
| 600 | |
| 601 class RelayTouch : public RelayWithStatusCallback { | |
| 602 public: | |
| 603 RelayTouch(base::PlatformFile file, | |
| 604 const base::Time& last_access_time, | |
| 605 const base::Time& last_modified_time, | |
| 606 base::FileUtilProxy::StatusCallback* callback) | |
| 607 : RelayWithStatusCallback(callback), | |
| 608 file_(file), | |
| 609 last_access_time_(last_access_time), | |
| 610 last_modified_time_(last_modified_time) { | |
| 611 } | |
| 612 | |
| 613 protected: | |
| 614 virtual void RunWork() { | |
| 615 if (!base::TouchPlatformFile(file_, last_access_time_, last_modified_time_)) | |
| 616 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 617 } | |
| 618 | |
| 619 private: | |
| 620 base::PlatformFile file_; | |
| 621 base::Time last_access_time_; | |
| 622 base::Time last_modified_time_; | |
| 623 }; | |
| 624 | |
| 625 class RelayTouchFilePath : public RelayWithStatusCallback { | |
| 626 public: | |
| 627 RelayTouchFilePath(const FilePath& file_path, | |
| 628 const base::Time& last_access_time, | |
| 629 const base::Time& last_modified_time, | |
| 630 base::FileUtilProxy::StatusCallback* callback) | |
| 631 : RelayWithStatusCallback(callback), | |
| 632 file_path_(file_path), | |
| 633 last_access_time_(last_access_time), | |
| 634 last_modified_time_(last_modified_time) { | |
| 635 } | |
| 636 | |
| 637 protected: | |
| 638 virtual void RunWork() { | |
| 639 if (!file_util::TouchFile( | |
| 640 file_path_, last_access_time_, last_modified_time_)) | |
| 641 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 642 } | |
| 643 | |
| 644 private: | |
| 645 FilePath file_path_; | |
| 646 base::Time last_access_time_; | |
| 647 base::Time last_modified_time_; | |
| 648 }; | |
| 649 | |
| 650 class RelayTruncatePlatformFile : public RelayWithStatusCallback { | |
| 651 public: | |
| 652 RelayTruncatePlatformFile(base::PlatformFile file, | |
| 653 int64 length, | |
| 654 base::FileUtilProxy::StatusCallback* callback) | |
| 655 : RelayWithStatusCallback(callback), | |
| 656 file_(file), | |
| 657 length_(length) { | |
| 658 } | |
| 659 | |
| 660 protected: | |
| 661 virtual void RunWork() { | |
| 662 if (!base::TruncatePlatformFile(file_, length_)) | |
| 663 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 664 } | |
| 665 | |
| 666 private: | |
| 667 base::PlatformFile file_; | |
| 668 int64 length_; | |
| 669 }; | |
| 670 | |
| 671 class RelayTruncate : public RelayWithStatusCallback { | |
| 672 public: | |
| 673 RelayTruncate(const FilePath& path, | |
| 674 int64 length, | |
| 675 base::FileUtilProxy::StatusCallback* callback) | |
| 676 : RelayWithStatusCallback(callback), | |
| 677 path_(path), | |
| 678 length_(length) { | |
| 679 } | |
| 680 | |
| 681 protected: | |
| 682 virtual void RunWork() { | |
| 683 base::PlatformFileError error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 684 base::PlatformFile file = | |
| 685 base::CreatePlatformFile( | |
| 686 path_, | |
| 687 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE, | |
| 688 NULL, | |
| 689 &error_code); | |
| 690 if (error_code != base::PLATFORM_FILE_OK) { | |
| 691 set_error_code(error_code); | |
| 692 return; | |
| 693 } | |
| 694 if (!base::TruncatePlatformFile(file, length_)) | |
| 695 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 696 base::ClosePlatformFile(file); | |
| 697 } | |
| 698 | |
| 699 private: | |
| 700 FilePath path_; | |
| 701 int64 length_; | |
| 702 }; | |
| 703 | |
| 704 class RelayFlush : public RelayWithStatusCallback { | |
| 705 public: | |
| 706 RelayFlush(base::PlatformFile file, | |
| 707 base::FileUtilProxy::StatusCallback* callback) | |
| 708 : RelayWithStatusCallback(callback), | |
| 709 file_(file) { | |
| 710 } | |
| 711 | |
| 712 protected: | |
| 713 virtual void RunWork() { | |
| 714 if (!base::FlushPlatformFile(file_)) | |
| 715 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
| 716 } | |
| 717 | |
| 718 private: | |
| 719 base::PlatformFile file_; | |
| 720 }; | 155 }; |
| 721 | 156 |
| 722 bool Start(const tracked_objects::Location& from_here, | 157 bool Start(const tracked_objects::Location& from_here, |
| 723 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | 158 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
| 724 scoped_refptr<MessageLoopRelay> relay) { | 159 scoped_refptr<MessageLoopRelay> relay) { |
| 725 return relay->Start(message_loop_proxy, from_here); | 160 return relay->Start(message_loop_proxy, from_here); |
| 726 } | 161 } |
| 727 | 162 |
| 728 } // namespace | 163 } // namespace |
| 729 | 164 |
| 730 namespace base { | 165 namespace fileapi { |
| 731 | 166 |
| 732 // static | 167 bool ObfuscatedFileUtilProxy::CreateDirectory( |
| 733 bool FileUtilProxy::CreateOrOpen( | 168 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
| 734 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 735 const FilePath& file_path, int file_flags, | |
| 736 CreateOrOpenCallback* callback) { | |
| 737 return Start(FROM_HERE, message_loop_proxy, new RelayCreateOrOpen( | |
| 738 message_loop_proxy, file_path, file_flags, callback)); | |
| 739 } | |
| 740 | |
| 741 // static | |
| 742 bool FileUtilProxy::CreateTemporary( | |
| 743 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 744 CreateTemporaryCallback* callback) { | |
| 745 return Start(FROM_HERE, message_loop_proxy, | |
| 746 new RelayCreateTemporary(message_loop_proxy, callback)); | |
| 747 } | |
| 748 | |
| 749 // static | |
| 750 bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 751 base::PlatformFile file_handle, | |
| 752 StatusCallback* callback) { | |
| 753 return Start(FROM_HERE, message_loop_proxy, | |
| 754 new RelayClose(file_handle, callback)); | |
| 755 } | |
| 756 | |
| 757 // static | |
| 758 bool FileUtilProxy::EnsureFileExists( | |
| 759 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 760 const FilePath& file_path, | |
| 761 EnsureFileExistsCallback* callback) { | |
| 762 return Start(FROM_HERE, message_loop_proxy, new RelayEnsureFileExists( | |
| 763 message_loop_proxy, file_path, callback)); | |
| 764 } | |
| 765 | |
| 766 // Retrieves the information about a file. It is invalid to pass NULL for the | |
| 767 // callback. | |
| 768 bool FileUtilProxy::GetFileInfo( | |
| 769 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 770 const FilePath& file_path, | |
| 771 GetFileInfoCallback* callback) { | |
| 772 return Start(FROM_HERE, message_loop_proxy, new RelayGetFileInfo( | |
| 773 file_path, callback)); | |
| 774 } | |
| 775 | |
| 776 // static | |
| 777 bool FileUtilProxy::GetFileInfoFromPlatformFile( | |
| 778 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 779 PlatformFile file, | |
| 780 GetFileInfoCallback* callback) { | |
| 781 return Start(FROM_HERE, message_loop_proxy, | |
| 782 new RelayGetFileInfoFromPlatformFile(file, callback)); | |
| 783 } | |
| 784 | |
| 785 // static | |
| 786 bool FileUtilProxy::ReadDirectory( | |
| 787 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 788 const FilePath& file_path, | |
| 789 ReadDirectoryCallback* callback) { | |
| 790 return Start(FROM_HERE, message_loop_proxy, new RelayReadDirectory( | |
| 791 file_path, callback)); | |
| 792 } | |
| 793 | |
| 794 // static | |
| 795 bool FileUtilProxy::CreateDirectory( | |
| 796 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 797 const FilePath& file_path, | 169 const FilePath& file_path, |
| 798 bool exclusive, | 170 bool exclusive, |
| 799 bool recursive, | 171 bool recursive, |
| 800 StatusCallback* callback) { | 172 base::FileUtilProxyBase::StatusCallback* callback) { |
| 173 CHECK(!recursive); |
| 174 FilePath root_path, virtual_path; |
| 175 CrackPath(file_path, &root_path, &virtual_path); |
| 801 return Start(FROM_HERE, message_loop_proxy, new RelayCreateDirectory( | 176 return Start(FROM_HERE, message_loop_proxy, new RelayCreateDirectory( |
| 802 file_path, exclusive, recursive, callback)); | 177 root_path, virtual_path, exclusive, callback)); |
| 803 } | 178 } |
| 804 | 179 |
| 805 // static | 180 void ObfuscatedFileUtilProxy::CrackPath( |
| 806 bool FileUtilProxy::Copy(scoped_refptr<MessageLoopProxy> message_loop_proxy, | 181 const FilePath& file_path, FilePath* root_path, FilePath* virtual_path) { |
| 807 const FilePath& src_file_path, | 182 CHECK(file_system_context_->path_manager()->CrackFileSystemPath( |
| 808 const FilePath& dest_file_path, | 183 file_path, NULL, NULL, root_path, virtual_path)); |
| 809 StatusCallback* callback) { | |
| 810 return Start(FROM_HERE, message_loop_proxy, | |
| 811 new RelayCopy(src_file_path, dest_file_path, callback)); | |
| 812 } | 184 } |
| 813 | 185 |
| 814 // static | 186 } // namespace fileapi |
| 815 bool FileUtilProxy::Move(scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 816 const FilePath& src_file_path, | |
| 817 const FilePath& dest_file_path, | |
| 818 StatusCallback* callback) { | |
| 819 return Start(FROM_HERE, message_loop_proxy, | |
| 820 new RelayMove(src_file_path, dest_file_path, callback)); | |
| 821 } | |
| 822 | |
| 823 // static | |
| 824 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 825 const FilePath& file_path, | |
| 826 bool recursive, | |
| 827 StatusCallback* callback) { | |
| 828 return Start(FROM_HERE, message_loop_proxy, | |
| 829 new RelayDelete(file_path, recursive, callback)); | |
| 830 } | |
| 831 | |
| 832 // static | |
| 833 bool FileUtilProxy::RecursiveDelete( | |
| 834 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 835 const FilePath& file_path, | |
| 836 StatusCallback* callback) { | |
| 837 return Start(FROM_HERE, message_loop_proxy, | |
| 838 new RelayDelete(file_path, true, callback)); | |
| 839 } | |
| 840 | |
| 841 // static | |
| 842 bool FileUtilProxy::Read( | |
| 843 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 844 PlatformFile file, | |
| 845 int64 offset, | |
| 846 char* buffer, | |
| 847 int bytes_to_read, | |
| 848 ReadWriteCallback* callback) { | |
| 849 return Start(FROM_HERE, message_loop_proxy, | |
| 850 new RelayRead(file, offset, buffer, bytes_to_read, callback)); | |
| 851 } | |
| 852 | |
| 853 // static | |
| 854 bool FileUtilProxy::Write( | |
| 855 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 856 PlatformFile file, | |
| 857 int64 offset, | |
| 858 const char* buffer, | |
| 859 int bytes_to_write, | |
| 860 ReadWriteCallback* callback) { | |
| 861 return Start(FROM_HERE, message_loop_proxy, | |
| 862 new RelayWrite(file, offset, buffer, bytes_to_write, callback)); | |
| 863 } | |
| 864 | |
| 865 // static | |
| 866 bool FileUtilProxy::Touch( | |
| 867 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 868 PlatformFile file, | |
| 869 const base::Time& last_access_time, | |
| 870 const base::Time& last_modified_time, | |
| 871 StatusCallback* callback) { | |
| 872 return Start(FROM_HERE, message_loop_proxy, | |
| 873 new RelayTouch(file, last_access_time, last_modified_time, | |
| 874 callback)); | |
| 875 } | |
| 876 | |
| 877 // static | |
| 878 bool FileUtilProxy::Touch( | |
| 879 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 880 const FilePath& file_path, | |
| 881 const base::Time& last_access_time, | |
| 882 const base::Time& last_modified_time, | |
| 883 StatusCallback* callback) { | |
| 884 return Start(FROM_HERE, message_loop_proxy, | |
| 885 new RelayTouchFilePath(file_path, last_access_time, | |
| 886 last_modified_time, callback)); | |
| 887 } | |
| 888 | |
| 889 // static | |
| 890 bool FileUtilProxy::Truncate( | |
| 891 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 892 PlatformFile file, | |
| 893 int64 length, | |
| 894 StatusCallback* callback) { | |
| 895 return Start(FROM_HERE, message_loop_proxy, | |
| 896 new RelayTruncatePlatformFile(file, length, callback)); | |
| 897 } | |
| 898 | |
| 899 // static | |
| 900 bool FileUtilProxy::Truncate( | |
| 901 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 902 const FilePath& path, | |
| 903 int64 length, | |
| 904 StatusCallback* callback) { | |
| 905 return Start(FROM_HERE, message_loop_proxy, | |
| 906 new RelayTruncate(path, length, callback)); | |
| 907 } | |
| 908 | |
| 909 // static | |
| 910 bool FileUtilProxy::Flush( | |
| 911 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 912 PlatformFile file, | |
| 913 StatusCallback* callback) { | |
| 914 return Start(FROM_HERE, message_loop_proxy, new RelayFlush(file, callback)); | |
| 915 } | |
| 916 | |
| 917 } // namespace base | |
| OLD | NEW |