| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/fileapi/file_writer_delegate.h" | 5 #include "webkit/fileapi/file_writer_delegate.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/file_util_proxy.h" | 9 #include "base/file_util_proxy.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 case net::ERR_ACCESS_DENIED: | 31 case net::ERR_ACCESS_DENIED: |
| 32 return base::PLATFORM_FILE_ERROR_ACCESS_DENIED; | 32 return base::PLATFORM_FILE_ERROR_ACCESS_DENIED; |
| 33 default: | 33 default: |
| 34 return base::PLATFORM_FILE_ERROR_FAILED; | 34 return base::PLATFORM_FILE_ERROR_FAILED; |
| 35 } | 35 } |
| 36 } | 36 } |
| 37 | 37 |
| 38 } // namespace | 38 } // namespace |
| 39 | 39 |
| 40 FileWriterDelegate::FileWriterDelegate( | 40 FileWriterDelegate::FileWriterDelegate( |
| 41 const FileSystemOperation::WriteCallback& write_callback, | 41 const DelegateWriteCallback& write_callback, |
| 42 scoped_ptr<FileStreamWriter> file_stream_writer) | 42 scoped_ptr<FileStreamWriter> file_stream_writer) |
| 43 : write_callback_(write_callback), | 43 : write_callback_(write_callback), |
| 44 file_stream_writer_(file_stream_writer.Pass()), | 44 file_stream_writer_(file_stream_writer.Pass()), |
| 45 writing_started_(false), |
| 45 bytes_written_backlog_(0), | 46 bytes_written_backlog_(0), |
| 46 bytes_written_(0), | 47 bytes_written_(0), |
| 47 bytes_read_(0), | 48 bytes_read_(0), |
| 48 io_buffer_(new net::IOBufferWithSize(kReadBufSize)), | 49 io_buffer_(new net::IOBufferWithSize(kReadBufSize)), |
| 49 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 50 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| 50 } | 51 } |
| 51 | 52 |
| 52 FileWriterDelegate::~FileWriterDelegate() { | 53 FileWriterDelegate::~FileWriterDelegate() { |
| 53 } | 54 } |
| 54 | 55 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 } else { | 139 } else { |
| 139 // This could easily be optimized to rotate between a pool of buffers, so | 140 // This could easily be optimized to rotate between a pool of buffers, so |
| 140 // that we could read and write at the same time. It's not yet clear that | 141 // that we could read and write at the same time. It's not yet clear that |
| 141 // it's necessary. | 142 // it's necessary. |
| 142 cursor_ = new net::DrainableIOBuffer(io_buffer_, bytes_read_); | 143 cursor_ = new net::DrainableIOBuffer(io_buffer_, bytes_read_); |
| 143 Write(); | 144 Write(); |
| 144 } | 145 } |
| 145 } | 146 } |
| 146 | 147 |
| 147 void FileWriterDelegate::Write() { | 148 void FileWriterDelegate::Write() { |
| 149 writing_started_ = true; |
| 148 int64 bytes_to_write = bytes_read_ - bytes_written_; | 150 int64 bytes_to_write = bytes_read_ - bytes_written_; |
| 149 int write_response = | 151 int write_response = |
| 150 file_stream_writer_->Write(cursor_, | 152 file_stream_writer_->Write(cursor_, |
| 151 static_cast<int>(bytes_to_write), | 153 static_cast<int>(bytes_to_write), |
| 152 base::Bind(&FileWriterDelegate::OnDataWritten, | 154 base::Bind(&FileWriterDelegate::OnDataWritten, |
| 153 weak_factory_.GetWeakPtr())); | 155 weak_factory_.GetWeakPtr())); |
| 154 if (write_response > 0) | 156 if (write_response > 0) |
| 155 MessageLoop::current()->PostTask( | 157 MessageLoop::current()->PostTask( |
| 156 FROM_HERE, | 158 FROM_HERE, |
| 157 base::Bind(&FileWriterDelegate::OnDataWritten, | 159 base::Bind(&FileWriterDelegate::OnDataWritten, |
| 158 weak_factory_.GetWeakPtr(), write_response)); | 160 weak_factory_.GetWeakPtr(), write_response)); |
| 159 else if (net::ERR_IO_PENDING != write_response) | 161 else if (net::ERR_IO_PENDING != write_response) |
| 160 OnError(NetErrorToPlatformFileError(write_response)); | 162 OnError(NetErrorToPlatformFileError(write_response)); |
| 161 } | 163 } |
| 162 | 164 |
| 163 void FileWriterDelegate::OnDataWritten(int write_response) { | 165 void FileWriterDelegate::OnDataWritten(int write_response) { |
| 164 if (write_response > 0) { | 166 if (write_response > 0) { |
| 165 OnProgress(write_response, false); | 167 OnProgress(write_response, false); |
| 166 cursor_->DidConsume(write_response); | 168 cursor_->DidConsume(write_response); |
| 167 bytes_written_ += write_response; | 169 bytes_written_ += write_response; |
| 168 if (bytes_written_ == bytes_read_) | 170 if (bytes_written_ == bytes_read_) |
| 169 Read(); | 171 Read(); |
| 170 else | 172 else |
| 171 Write(); | 173 Write(); |
| 172 } else { | 174 } else { |
| 173 OnError(NetErrorToPlatformFileError(write_response)); | 175 OnError(NetErrorToPlatformFileError(write_response)); |
| 174 } | 176 } |
| 175 } | 177 } |
| 176 | 178 |
| 179 FileWriterDelegate::WriteProgressStatus |
| 180 FileWriterDelegate::GetCompletionStatusOnError() const { |
| 181 return writing_started_ ? ERROR_WRITE_STARTED : ERROR_WRITE_NOT_STARTED; |
| 182 } |
| 183 |
| 177 void FileWriterDelegate::OnError(base::PlatformFileError error) { | 184 void FileWriterDelegate::OnError(base::PlatformFileError error) { |
| 178 if (request_.get()) { | 185 if (request_.get()) { |
| 179 request_->set_delegate(NULL); | 186 request_->set_delegate(NULL); |
| 180 request_->Cancel(); | 187 request_->Cancel(); |
| 181 } | 188 } |
| 182 | 189 |
| 183 write_callback_.Run(error, 0, true); | 190 write_callback_.Run(error, 0, GetCompletionStatusOnError()); |
| 184 } | 191 } |
| 185 | 192 |
| 186 void FileWriterDelegate::OnProgress(int bytes_written, bool done) { | 193 void FileWriterDelegate::OnProgress(int bytes_written, bool done) { |
| 187 DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_); | 194 DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_); |
| 188 static const int kMinProgressDelayMS = 200; | 195 static const int kMinProgressDelayMS = 200; |
| 189 base::Time currentTime = base::Time::Now(); | 196 base::Time currentTime = base::Time::Now(); |
| 190 if (done || last_progress_event_time_.is_null() || | 197 if (done || last_progress_event_time_.is_null() || |
| 191 (currentTime - last_progress_event_time_).InMilliseconds() > | 198 (currentTime - last_progress_event_time_).InMilliseconds() > |
| 192 kMinProgressDelayMS) { | 199 kMinProgressDelayMS) { |
| 193 bytes_written += bytes_written_backlog_; | 200 bytes_written += bytes_written_backlog_; |
| 194 last_progress_event_time_ = currentTime; | 201 last_progress_event_time_ = currentTime; |
| 195 bytes_written_backlog_ = 0; | 202 bytes_written_backlog_ = 0; |
| 196 write_callback_.Run( | 203 |
| 197 base::PLATFORM_FILE_OK, bytes_written, done); | 204 WriteProgressStatus status = done ? SUCCESS_COMPLETED : SUCCESS_IO_PENDING; |
| 205 write_callback_.Run(base::PLATFORM_FILE_OK, bytes_written, status); |
| 198 return; | 206 return; |
| 199 } | 207 } |
| 200 bytes_written_backlog_ += bytes_written; | 208 bytes_written_backlog_ += bytes_written; |
| 201 } | 209 } |
| 202 | 210 |
| 203 void FileWriterDelegate::OnWriteCancelled(int status) { | 211 void FileWriterDelegate::OnWriteCancelled(int status) { |
| 204 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, true); | 212 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, |
| 213 GetCompletionStatusOnError()); |
| 205 } | 214 } |
| 206 | 215 |
| 207 } // namespace fileapi | 216 } // namespace fileapi |
| OLD | NEW |