| 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 "storage/browser/fileapi/file_writer_delegate.h" | 5 #include "storage/browser/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/files/file_util_proxy.h" | 9 #include "base/files/file_util_proxy.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 FileWriterDelegate::FileWriterDelegate( | 25 FileWriterDelegate::FileWriterDelegate( |
| 26 scoped_ptr<FileStreamWriter> file_stream_writer, | 26 scoped_ptr<FileStreamWriter> file_stream_writer, |
| 27 FlushPolicy flush_policy) | 27 FlushPolicy flush_policy) |
| 28 : file_stream_writer_(file_stream_writer.Pass()), | 28 : file_stream_writer_(file_stream_writer.Pass()), |
| 29 writing_started_(false), | 29 writing_started_(false), |
| 30 flush_policy_(flush_policy), | 30 flush_policy_(flush_policy), |
| 31 bytes_written_backlog_(0), | 31 bytes_written_backlog_(0), |
| 32 bytes_written_(0), | 32 bytes_written_(0), |
| 33 bytes_read_(0), | 33 bytes_read_(0), |
| 34 total_bytes_read_(0), |
| 34 io_buffer_(new net::IOBufferWithSize(kReadBufSize)), | 35 io_buffer_(new net::IOBufferWithSize(kReadBufSize)), |
| 35 weak_factory_(this) { | 36 weak_factory_(this) { |
| 36 } | 37 } |
| 37 | 38 |
| 38 FileWriterDelegate::~FileWriterDelegate() { | 39 FileWriterDelegate::~FileWriterDelegate() { |
| 39 } | 40 } |
| 40 | 41 |
| 41 void FileWriterDelegate::Start(scoped_ptr<net::URLRequest> request, | 42 void FileWriterDelegate::Start(scoped_ptr<net::URLRequest> request, |
| 42 const DelegateWriteCallback& write_callback) { | 43 const DelegateWriteCallback& write_callback) { |
| 43 write_callback_ = write_callback; | 44 write_callback_ = write_callback; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 FROM_HERE, | 129 FROM_HERE, |
| 129 base::Bind(&FileWriterDelegate::OnDataReceived, | 130 base::Bind(&FileWriterDelegate::OnDataReceived, |
| 130 weak_factory_.GetWeakPtr(), bytes_read_)); | 131 weak_factory_.GetWeakPtr(), bytes_read_)); |
| 131 } else if (!request_->status().is_io_pending()) { | 132 } else if (!request_->status().is_io_pending()) { |
| 132 OnError(base::File::FILE_ERROR_FAILED); | 133 OnError(base::File::FILE_ERROR_FAILED); |
| 133 } | 134 } |
| 134 } | 135 } |
| 135 | 136 |
| 136 void FileWriterDelegate::OnDataReceived(int bytes_read) { | 137 void FileWriterDelegate::OnDataReceived(int bytes_read) { |
| 137 bytes_read_ = bytes_read; | 138 bytes_read_ = bytes_read; |
| 139 total_bytes_read_ += bytes_read; |
| 138 if (!bytes_read_) { // We're done. | 140 if (!bytes_read_) { // We're done. |
| 141 if (total_bytes_read_ == 0) { |
| 142 // Need to call Write (even though no data was received). This is because |
| 143 // the file is created lazily upon first receipt of data, so without it |
| 144 // no empty file would be created. |
| 145 Write(); |
| 146 } |
| 139 OnProgress(0, true); | 147 OnProgress(0, true); |
| 140 } else { | 148 } else { |
| 141 // This could easily be optimized to rotate between a pool of buffers, so | 149 // This could easily be optimized to rotate between a pool of buffers, so |
| 142 // that we could read and write at the same time. It's not yet clear that | 150 // that we could read and write at the same time. It's not yet clear that |
| 143 // it's necessary. | 151 // it's necessary. |
| 144 cursor_ = new net::DrainableIOBuffer(io_buffer_.get(), bytes_read_); | 152 cursor_ = new net::DrainableIOBuffer(io_buffer_.get(), bytes_read_); |
| 145 Write(); | 153 Write(); |
| 146 } | 154 } |
| 147 } | 155 } |
| 148 | 156 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 base::File::Error error, | 235 base::File::Error error, |
| 228 int bytes_written, | 236 int bytes_written, |
| 229 WriteProgressStatus progress_status) { | 237 WriteProgressStatus progress_status) { |
| 230 if (flush_policy_ == FlushPolicy::NO_FLUSH_ON_COMPLETION) { | 238 if (flush_policy_ == FlushPolicy::NO_FLUSH_ON_COMPLETION) { |
| 231 write_callback_.Run(error, bytes_written, progress_status); | 239 write_callback_.Run(error, bytes_written, progress_status); |
| 232 return; | 240 return; |
| 233 } | 241 } |
| 234 // DCHECK_EQ on enum classes is not supported. | 242 // DCHECK_EQ on enum classes is not supported. |
| 235 DCHECK(flush_policy_ == FlushPolicy::FLUSH_ON_COMPLETION); | 243 DCHECK(flush_policy_ == FlushPolicy::FLUSH_ON_COMPLETION); |
| 236 | 244 |
| 237 int flush_error = file_stream_writer_->Flush( | 245 int flush_error = 0; |
| 238 base::Bind(&FileWriterDelegate::OnFlushed, weak_factory_.GetWeakPtr(), | 246 if (bytes_written) { |
| 239 error, bytes_written, progress_status)); | 247 flush_error = file_stream_writer_->Flush( |
| 248 base::Bind(&FileWriterDelegate::OnFlushed, weak_factory_.GetWeakPtr(), |
| 249 error, bytes_written, progress_status)); |
| 250 } |
| 240 if (flush_error != net::ERR_IO_PENDING) | 251 if (flush_error != net::ERR_IO_PENDING) |
| 241 OnFlushed(error, bytes_written, progress_status, flush_error); | 252 OnFlushed(error, bytes_written, progress_status, flush_error); |
| 242 } | 253 } |
| 243 | 254 |
| 244 void FileWriterDelegate::OnFlushed(base::File::Error error, | 255 void FileWriterDelegate::OnFlushed(base::File::Error error, |
| 245 int bytes_written, | 256 int bytes_written, |
| 246 WriteProgressStatus progress_status, | 257 WriteProgressStatus progress_status, |
| 247 int flush_error) { | 258 int flush_error) { |
| 248 if (error == base::File::FILE_OK && flush_error != net::OK) { | 259 if (error == base::File::FILE_OK && flush_error != net::OK) { |
| 249 // If the Flush introduced an error, overwrite the status. | 260 // If the Flush introduced an error, overwrite the status. |
| 250 // Otherwise, keep the original error status. | 261 // Otherwise, keep the original error status. |
| 251 error = NetErrorToFileError(flush_error); | 262 error = NetErrorToFileError(flush_error); |
| 252 progress_status = GetCompletionStatusOnError(); | 263 progress_status = GetCompletionStatusOnError(); |
| 253 } | 264 } |
| 254 write_callback_.Run(error, bytes_written, progress_status); | 265 write_callback_.Run(error, bytes_written, progress_status); |
| 255 } | 266 } |
| 256 | 267 |
| 257 } // namespace storage | 268 } // namespace storage |
| OLD | NEW |