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 |