1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/files/file_proxy.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind_helpers.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/file_util.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/files/file.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/location.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/task_runner.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/task_runner_util.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace { 17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void FileDeleter(base::File file) { 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace base { 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class FileHelper { 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FileHelper(FileProxy* proxy, File file) 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : file_(file.Pass()), 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) error_(File::FILE_ERROR_FAILED), 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) task_runner_(proxy->task_runner()), 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) proxy_(AsWeakPtr(proxy)) { 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void PassFile() { 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (proxy_) 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) proxy_->SetFile(file_.Pass()); 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else if (file_.IsValid()) 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) task_runner_->PostTask(FROM_HERE, Bind(&FileDeleter, Passed(&file_))); 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) protected: 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) File file_; 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) File::Error error_; 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<TaskRunner> task_runner_; 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WeakPtr<FileProxy> proxy_; 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FileHelper); 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class GenericFileHelper : public FileHelper { 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GenericFileHelper(FileProxy* proxy, File file) 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : FileHelper(proxy, file.Pass()) { 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Close() { 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) file_.Close(); 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_ = File::FILE_OK; 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void SetTimes(Time last_access_time, Time last_modified_time) { 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool rv = file_.SetTimes(last_access_time, last_modified_time); 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_ = rv ? File::FILE_OK : File::FILE_ERROR_FAILED; 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void SetLength(int64 length) { 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (file_.SetLength(length)) 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_ = File::FILE_OK; 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Flush() { 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (file_.Flush()) 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_ = File::FILE_OK; 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Reply(const FileProxy::StatusCallback& callback) { 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PassFile(); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!callback.is_null()) 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(error_); 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GenericFileHelper); 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class CreateOrOpenHelper : public FileHelper { 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateOrOpenHelper(FileProxy* proxy, File file) 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : FileHelper(proxy, file.Pass()) { 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void RunWork(const FilePath& file_path, int file_flags) { 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) file_.Initialize(file_path, file_flags); 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_ = file_.IsValid() ? File::FILE_OK : file_.error_details(); 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Reply(const FileProxy::StatusCallback& callback) { 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!callback.is_null()); 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PassFile(); 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(error_); 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CreateOrOpenHelper); 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class CreateTemporaryHelper : public FileHelper { 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateTemporaryHelper(FileProxy* proxy, File file) 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : FileHelper(proxy, file.Pass()) { 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void RunWork(uint32 additional_file_flags) { 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(darin): file_util should have a variant of CreateTemporaryFile 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // that returns a FilePath and a File. 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!CreateTemporaryFile(&file_path_)) { 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(davidben): base::CreateTemporaryFile should preserve the error 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // code. 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_ = File::FILE_ERROR_FAILED; 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint32 file_flags = File::FLAG_WRITE | 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) File::FLAG_TEMPORARY | 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) File::FLAG_CREATE_ALWAYS | 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) additional_file_flags; 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) file_.Initialize(file_path_, file_flags); 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (file_.IsValid()) { 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_ = File::FILE_OK; 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_ = file_.error_details(); 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeleteFile(file_path_, false); 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) file_path_.clear(); 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Reply(const FileProxy::CreateTemporaryCallback& callback) { 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!callback.is_null()); 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PassFile(); 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(error_, file_path_); 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FilePath file_path_; 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CreateTemporaryHelper); 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class GetInfoHelper : public FileHelper { 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetInfoHelper(FileProxy* proxy, File file) 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : FileHelper(proxy, file.Pass()) { 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void RunWork() { 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (file_.GetInfo(&file_info_)) 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_ = File::FILE_OK; 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Reply(const FileProxy::GetFileInfoCallback& callback) { 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PassFile(); 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!callback.is_null()); 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(error_, file_info_); 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) File::Info file_info_; 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GetInfoHelper); 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ReadHelper : public FileHelper { 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ReadHelper(FileProxy* proxy, File file, int bytes_to_read) 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : FileHelper(proxy, file.Pass()), 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) buffer_(new char[bytes_to_read]), 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bytes_to_read_(bytes_to_read), 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bytes_read_(0) { 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void RunWork(int64 offset) { 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bytes_read_ = file_.Read(offset, buffer_.get(), bytes_to_read_); 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_ = (bytes_read_ < 0) ? File::FILE_ERROR_FAILED : File::FILE_OK; 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Reply(const FileProxy::ReadCallback& callback) { 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PassFile(); 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!callback.is_null()); 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(error_, buffer_.get(), bytes_read_); 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<char[]> buffer_; 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int bytes_to_read_; 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int bytes_read_; 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ReadHelper); 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class WriteHelper : public FileHelper { 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WriteHelper(FileProxy* proxy, 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) File file, 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* buffer, int bytes_to_write) 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : FileHelper(proxy, file.Pass()), 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) buffer_(new char[bytes_to_write]), 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bytes_to_write_(bytes_to_write), 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bytes_written_(0) { 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) memcpy(buffer_.get(), buffer, bytes_to_write); 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void RunWork(int64 offset) { 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bytes_written_ = file_.Write(offset, buffer_.get(), bytes_to_write_); 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_ = (bytes_written_ < 0) ? File::FILE_ERROR_FAILED : File::FILE_OK; 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Reply(const FileProxy::WriteCallback& callback) { 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PassFile(); 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!callback.is_null()) 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(error_, bytes_written_); 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<char[]> buffer_; 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int bytes_to_write_; 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int bytes_written_; 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(WriteHelper); 229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)FileProxy::FileProxy(TaskRunner* task_runner) : task_runner_(task_runner) { 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)FileProxy::~FileProxy() { 237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (file_.IsValid()) 238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) task_runner_->PostTask(FROM_HERE, Bind(&FileDeleter, Passed(&file_))); 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool FileProxy::CreateOrOpen(const FilePath& file_path, 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint32 file_flags, 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const StatusCallback& callback) { 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!file_.IsValid()); 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateOrOpenHelper* helper = new CreateOrOpenHelper(this, File()); 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return task_runner_->PostTaskAndReply( 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), file_path, 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) file_flags), 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback)); 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool FileProxy::CreateTemporary(uint32 additional_file_flags, 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const CreateTemporaryCallback& callback) { 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!file_.IsValid()); 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateTemporaryHelper* helper = new CreateTemporaryHelper(this, File()); 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return task_runner_->PostTaskAndReply( 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&CreateTemporaryHelper::RunWork, Unretained(helper), 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) additional_file_flags), 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback)); 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool FileProxy::IsValid() const { 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return file_.IsValid(); 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FileProxy::SetFile(File file) { 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(!file_.IsValid()); 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) file_ = file.Pass(); 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)File FileProxy::TakeFile() { 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return file_.Pass(); 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PlatformFile FileProxy::GetPlatformFile() const { 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return file_.GetPlatformFile(); 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool FileProxy::Close(const StatusCallback& callback) { 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(file_.IsValid()); 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GenericFileHelper* helper = new GenericFileHelper(this, file_.Pass()); 284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return task_runner_->PostTaskAndReply( 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&GenericFileHelper::Close, Unretained(helper)), 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&GenericFileHelper::Reply, Owned(helper), callback)); 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool FileProxy::GetInfo(const GetFileInfoCallback& callback) { 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(file_.IsValid()); 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetInfoHelper* helper = new GetInfoHelper(this, file_.Pass()); 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return task_runner_->PostTaskAndReply( 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&GetInfoHelper::RunWork, Unretained(helper)), 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&GetInfoHelper::Reply, Owned(helper), callback)); 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool FileProxy::Read(int64 offset, 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int bytes_to_read, 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ReadCallback& callback) { 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(file_.IsValid()); 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (bytes_to_read < 0) 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ReadHelper* helper = new ReadHelper(this, file_.Pass(), bytes_to_read); 307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return task_runner_->PostTaskAndReply( 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&ReadHelper::RunWork, Unretained(helper), offset), 310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&ReadHelper::Reply, Owned(helper), callback)); 311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool FileProxy::Write(int64 offset, 314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* buffer, 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int bytes_to_write, 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const WriteCallback& callback) { 317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(file_.IsValid()); 318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (bytes_to_write <= 0 || buffer == NULL) 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WriteHelper* helper = 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new WriteHelper(this, file_.Pass(), buffer, bytes_to_write); 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return task_runner_->PostTaskAndReply( 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&WriteHelper::RunWork, Unretained(helper), offset), 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&WriteHelper::Reply, Owned(helper), callback)); 327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool FileProxy::SetTimes(Time last_access_time, 330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Time last_modified_time, 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const StatusCallback& callback) { 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(file_.IsValid()); 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GenericFileHelper* helper = new GenericFileHelper(this, file_.Pass()); 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return task_runner_->PostTaskAndReply( 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&GenericFileHelper::SetTimes, Unretained(helper), last_access_time, 337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_modified_time), 338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&GenericFileHelper::Reply, Owned(helper), callback)); 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool FileProxy::SetLength(int64 length, const StatusCallback& callback) { 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(file_.IsValid()); 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GenericFileHelper* helper = new GenericFileHelper(this, file_.Pass()); 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return task_runner_->PostTaskAndReply( 345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&GenericFileHelper::SetLength, Unretained(helper), length), 347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&GenericFileHelper::Reply, Owned(helper), callback)); 348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool FileProxy::Flush(const StatusCallback& callback) { 351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(file_.IsValid()); 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GenericFileHelper* helper = new GenericFileHelper(this, file_.Pass()); 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return task_runner_->PostTaskAndReply( 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&GenericFileHelper::Flush, Unretained(helper)), 356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Bind(&GenericFileHelper::Reply, Owned(helper), callback)); 357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace base 360