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 |