Chromium Code Reviews| 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; |
| 138 if (!bytes_read_) { // We're done. | 139 total_bytes_read_ += bytes_read; |
| 139 OnProgress(0, true); | 140 |
| 140 } else { | 141 if (bytes_read_ || !total_bytes_read_) { |
| 142 // If we received bytes then write them. Zero bytes signals EOF, but if no | |
|
jsbell
2015/02/25 19:53:27
Excellent comment, thanks!
| |
| 143 // bytes were ever read then still call Write(). This is necessary because | |
| 144 // the file is created when the first chunk of data is received, but we need | |
| 145 // to support zero length files so explicitly write zero bytes to force the | |
| 146 // file creation. | |
|
michaeln
2015/02/25 20:35:43
Should we fix this problem directly in the FileStr
cmumford
2015/02/25 22:37:29
Was reading the comment above net::FileStream::Wri
cmumford
2015/02/25 23:52:49
On second thought, I'm back to the idea of fixing
michaeln
2015/02/26 02:05:37
Maybe fix that class w/o altering behavior for exi
| |
| 147 // | |
| 141 // This could easily be optimized to rotate between a pool of buffers, so | 148 // 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 | 149 // that we could read and write at the same time. It's not yet clear that |
| 143 // it's necessary. | 150 // it's necessary. |
| 144 cursor_ = new net::DrainableIOBuffer(io_buffer_.get(), bytes_read_); | 151 cursor_ = new net::DrainableIOBuffer(io_buffer_.get(), bytes_read_); |
| 145 Write(); | 152 Write(); |
| 146 } | 153 } |
| 154 if (!bytes_read_) // We're done. | |
| 155 OnProgress(0, true); | |
| 147 } | 156 } |
| 148 | 157 |
| 149 void FileWriterDelegate::Write() { | 158 void FileWriterDelegate::Write() { |
| 150 writing_started_ = true; | 159 writing_started_ = true; |
| 151 int64 bytes_to_write = bytes_read_ - bytes_written_; | 160 int64 bytes_to_write = bytes_read_ - bytes_written_; |
|
michaeln
2015/02/25 20:35:43
It looks like bytes_to_write here will go negative
michaeln
2015/02/25 21:55:42
oh, nm it cant be < zero
| |
| 152 int write_response = | 161 int write_response = |
| 153 file_stream_writer_->Write(cursor_.get(), | 162 file_stream_writer_->Write(cursor_.get(), |
|
michaeln
2015/02/25 21:55:42
I'm not sure if this is depending on a return valu
cmumford
2015/02/25 22:37:30
I think that now that I won't be calling Write() I
michaeln
2015/02/26 02:05:37
The lack of a file being created by FileStreamWrit
| |
| 154 static_cast<int>(bytes_to_write), | 163 static_cast<int>(bytes_to_write), |
| 155 base::Bind(&FileWriterDelegate::OnDataWritten, | 164 base::Bind(&FileWriterDelegate::OnDataWritten, |
| 156 weak_factory_.GetWeakPtr())); | 165 weak_factory_.GetWeakPtr())); |
| 157 if (write_response > 0) { | 166 if (write_response > 0) { |
| 158 base::MessageLoop::current()->PostTask( | 167 base::MessageLoop::current()->PostTask( |
| 159 FROM_HERE, | 168 FROM_HERE, |
| 160 base::Bind(&FileWriterDelegate::OnDataWritten, | 169 base::Bind(&FileWriterDelegate::OnDataWritten, |
| 161 weak_factory_.GetWeakPtr(), write_response)); | 170 weak_factory_.GetWeakPtr(), write_response)); |
| 162 } else if (net::ERR_IO_PENDING != write_response) { | 171 } else if (net::ERR_IO_PENDING != write_response) { |
| 163 OnError(NetErrorToFileError(write_response)); | 172 OnError(NetErrorToFileError(write_response)); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 base::File::Error error, | 236 base::File::Error error, |
| 228 int bytes_written, | 237 int bytes_written, |
| 229 WriteProgressStatus progress_status) { | 238 WriteProgressStatus progress_status) { |
| 230 if (flush_policy_ == FlushPolicy::NO_FLUSH_ON_COMPLETION) { | 239 if (flush_policy_ == FlushPolicy::NO_FLUSH_ON_COMPLETION) { |
| 231 write_callback_.Run(error, bytes_written, progress_status); | 240 write_callback_.Run(error, bytes_written, progress_status); |
| 232 return; | 241 return; |
| 233 } | 242 } |
| 234 // DCHECK_EQ on enum classes is not supported. | 243 // DCHECK_EQ on enum classes is not supported. |
| 235 DCHECK(flush_policy_ == FlushPolicy::FLUSH_ON_COMPLETION); | 244 DCHECK(flush_policy_ == FlushPolicy::FLUSH_ON_COMPLETION); |
| 236 | 245 |
| 237 int flush_error = file_stream_writer_->Flush( | 246 int flush_error = 0; |
| 238 base::Bind(&FileWriterDelegate::OnFlushed, weak_factory_.GetWeakPtr(), | 247 if (bytes_written) { |
| 239 error, bytes_written, progress_status)); | 248 flush_error = file_stream_writer_->Flush( |
| 249 base::Bind(&FileWriterDelegate::OnFlushed, weak_factory_.GetWeakPtr(), | |
| 250 error, bytes_written, progress_status)); | |
| 251 } | |
| 240 if (flush_error != net::ERR_IO_PENDING) | 252 if (flush_error != net::ERR_IO_PENDING) |
| 241 OnFlushed(error, bytes_written, progress_status, flush_error); | 253 OnFlushed(error, bytes_written, progress_status, flush_error); |
| 242 } | 254 } |
| 243 | 255 |
| 244 void FileWriterDelegate::OnFlushed(base::File::Error error, | 256 void FileWriterDelegate::OnFlushed(base::File::Error error, |
| 245 int bytes_written, | 257 int bytes_written, |
| 246 WriteProgressStatus progress_status, | 258 WriteProgressStatus progress_status, |
| 247 int flush_error) { | 259 int flush_error) { |
| 248 if (error == base::File::FILE_OK && flush_error != net::OK) { | 260 if (error == base::File::FILE_OK && flush_error != net::OK) { |
| 249 // If the Flush introduced an error, overwrite the status. | 261 // If the Flush introduced an error, overwrite the status. |
| 250 // Otherwise, keep the original error status. | 262 // Otherwise, keep the original error status. |
| 251 error = NetErrorToFileError(flush_error); | 263 error = NetErrorToFileError(flush_error); |
| 252 progress_status = GetCompletionStatusOnError(); | 264 progress_status = GetCompletionStatusOnError(); |
| 253 } | 265 } |
| 254 write_callback_.Run(error, bytes_written, progress_status); | 266 write_callback_.Run(error, bytes_written, progress_status); |
| 255 } | 267 } |
| 256 | 268 |
| 257 } // namespace storage | 269 } // namespace storage |
| OLD | NEW |