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 "content/browser/download/download_file_impl.h" | 5 #include "content/browser/download/download_file_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 } | 149 } |
150 | 150 |
151 DownloadInterruptReason DownloadFileImpl::WriteDataToFile(int64_t offset, | 151 DownloadInterruptReason DownloadFileImpl::WriteDataToFile(int64_t offset, |
152 const char* data, | 152 const char* data, |
153 size_t data_len) { | 153 size_t data_len) { |
154 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 154 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
155 WillWriteToDisk(data_len); | 155 WillWriteToDisk(data_len); |
156 return file_.WriteDataToFile(offset, data, data_len); | 156 return file_.WriteDataToFile(offset, data, data_len); |
157 } | 157 } |
158 | 158 |
| 159 bool DownloadFileImpl::CalculateBytesToWrite(SourceStream* source_stream, |
| 160 size_t bytes_available_to_write, |
| 161 size_t* bytes_to_write) { |
| 162 // If a new slice finds that its target position has already been written, |
| 163 // terminate the stream. |
| 164 if (source_stream->bytes_written() == 0) { |
| 165 for (const auto& received_slice : received_slices_) { |
| 166 if (received_slice.offset <= source_stream->offset() && |
| 167 received_slice.offset + received_slice.received_bytes > |
| 168 source_stream->offset()) { |
| 169 *bytes_to_write = 0; |
| 170 return true; |
| 171 } |
| 172 } |
| 173 } |
| 174 |
| 175 if (source_stream->length() != DownloadSaveInfo::kLengthFullContent && |
| 176 source_stream->bytes_written() + |
| 177 static_cast<int64_t>(bytes_available_to_write) >= |
| 178 source_stream->length()) { |
| 179 // Write a partial buffer as the incoming data exceeds the length limit. |
| 180 *bytes_to_write = source_stream->length() - source_stream->bytes_written(); |
| 181 return true; |
| 182 } |
| 183 |
| 184 *bytes_to_write = bytes_available_to_write; |
| 185 return false; |
| 186 } |
| 187 |
159 void DownloadFileImpl::RenameAndUniquify( | 188 void DownloadFileImpl::RenameAndUniquify( |
160 const base::FilePath& full_path, | 189 const base::FilePath& full_path, |
161 const RenameCompletionCallback& callback) { | 190 const RenameCompletionCallback& callback) { |
162 std::unique_ptr<RenameParameters> parameters( | 191 std::unique_ptr<RenameParameters> parameters( |
163 new RenameParameters(UNIQUIFY, full_path, callback)); | 192 new RenameParameters(UNIQUIFY, full_path, callback)); |
164 RenameWithRetryInternal(std::move(parameters)); | 193 RenameWithRetryInternal(std::move(parameters)); |
165 } | 194 } |
166 | 195 |
167 void DownloadFileImpl::RenameAndAnnotate( | 196 void DownloadFileImpl::RenameAndAnnotate( |
168 const base::FilePath& full_path, | 197 const base::FilePath& full_path, |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 } | 314 } |
286 | 315 |
287 void DownloadFileImpl::StreamActive(SourceStream* source_stream) { | 316 void DownloadFileImpl::StreamActive(SourceStream* source_stream) { |
288 DCHECK(source_stream->stream_reader()); | 317 DCHECK(source_stream->stream_reader()); |
289 base::TimeTicks start(base::TimeTicks::Now()); | 318 base::TimeTicks start(base::TimeTicks::Now()); |
290 base::TimeTicks now; | 319 base::TimeTicks now; |
291 scoped_refptr<net::IOBuffer> incoming_data; | 320 scoped_refptr<net::IOBuffer> incoming_data; |
292 size_t incoming_data_size = 0; | 321 size_t incoming_data_size = 0; |
293 size_t total_incoming_data_size = 0; | 322 size_t total_incoming_data_size = 0; |
294 size_t num_buffers = 0; | 323 size_t num_buffers = 0; |
| 324 size_t bytes_to_write = 0; |
295 bool should_terminate = false; | 325 bool should_terminate = false; |
296 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY); | 326 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY); |
297 DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_NONE; | 327 DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_NONE; |
298 base::TimeDelta delta( | 328 base::TimeDelta delta( |
299 base::TimeDelta::FromMilliseconds(kMaxTimeBlockingFileThreadMs)); | 329 base::TimeDelta::FromMilliseconds(kMaxTimeBlockingFileThreadMs)); |
300 | 330 |
301 // Take care of any file local activity required. | 331 // Take care of any file local activity required. |
302 do { | 332 do { |
303 state = source_stream->stream_reader()->Read(&incoming_data, | 333 state = source_stream->stream_reader()->Read(&incoming_data, |
304 &incoming_data_size); | 334 &incoming_data_size); |
305 | 335 |
306 switch (state) { | 336 switch (state) { |
307 case ByteStreamReader::STREAM_EMPTY: | 337 case ByteStreamReader::STREAM_EMPTY: |
308 break; | 338 break; |
309 case ByteStreamReader::STREAM_HAS_DATA: | 339 case ByteStreamReader::STREAM_HAS_DATA: |
310 { | 340 { |
311 ++num_buffers; | 341 ++num_buffers; |
312 base::TimeTicks write_start(base::TimeTicks::Now()); | 342 base::TimeTicks write_start(base::TimeTicks::Now()); |
313 // Stop the stream if it writes more bytes than expected. | 343 should_terminate = CalculateBytesToWrite( |
314 if (source_stream->length() != DownloadSaveInfo::kLengthFullContent && | 344 source_stream, incoming_data_size, &bytes_to_write); |
315 source_stream->bytes_written() + | 345 DCHECK_GE(incoming_data_size, bytes_to_write); |
316 static_cast<int64_t>(incoming_data_size) >= | |
317 source_stream->length()) { | |
318 should_terminate = true; | |
319 incoming_data_size = | |
320 source_stream->length() - source_stream->bytes_written(); | |
321 } | |
322 reason = WriteDataToFile( | 346 reason = WriteDataToFile( |
323 source_stream->offset() + source_stream->bytes_written(), | 347 source_stream->offset() + source_stream->bytes_written(), |
324 incoming_data.get()->data(), incoming_data_size); | 348 incoming_data.get()->data(), bytes_to_write); |
325 disk_writes_time_ += (base::TimeTicks::Now() - write_start); | 349 disk_writes_time_ += (base::TimeTicks::Now() - write_start); |
326 bytes_seen_ += incoming_data_size; | 350 bytes_seen_ += bytes_to_write; |
327 total_incoming_data_size += incoming_data_size; | 351 total_incoming_data_size += bytes_to_write; |
328 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) { | 352 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) { |
329 int64_t prev_bytes_written = source_stream->bytes_written(); | 353 int64_t prev_bytes_written = source_stream->bytes_written(); |
330 source_stream->OnWriteBytesToDisk(incoming_data_size); | 354 source_stream->OnWriteBytesToDisk(bytes_to_write); |
331 if (!is_sparse_file_) | 355 if (!is_sparse_file_) |
332 break; | 356 break; |
333 // If the write operation creates a new slice, add it to the | 357 // If the write operation creates a new slice, add it to the |
334 // |received_slices_| and update all the entries in | 358 // |received_slices_| and update all the entries in |
335 // |source_streams_|. | 359 // |source_streams_|. |
336 if (incoming_data_size > 0 && prev_bytes_written == 0) { | 360 if (bytes_to_write > 0 && prev_bytes_written == 0) { |
337 AddNewSlice(source_stream->offset(), incoming_data_size); | 361 AddNewSlice(source_stream->offset(), bytes_to_write); |
338 } else { | 362 } else { |
339 received_slices_[source_stream->index()].received_bytes += | 363 received_slices_[source_stream->index()].received_bytes += |
340 incoming_data_size; | 364 bytes_to_write; |
341 } | 365 } |
342 } | 366 } |
343 } | 367 } |
344 break; | 368 break; |
345 case ByteStreamReader::STREAM_COMPLETE: | 369 case ByteStreamReader::STREAM_COMPLETE: |
346 { | 370 { |
347 reason = static_cast<DownloadInterruptReason>( | 371 reason = static_cast<DownloadInterruptReason>( |
348 source_stream->stream_reader()->GetStatus()); | 372 source_stream->stream_reader()->GetStatus()); |
349 SendUpdate(); | 373 SendUpdate(); |
350 } | 374 } |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 const base::FilePath& new_path, | 544 const base::FilePath& new_path, |
521 const RenameCompletionCallback& completion_callback) | 545 const RenameCompletionCallback& completion_callback) |
522 : option(option), | 546 : option(option), |
523 new_path(new_path), | 547 new_path(new_path), |
524 retries_left(kMaxRenameRetries), | 548 retries_left(kMaxRenameRetries), |
525 completion_callback(completion_callback) {} | 549 completion_callback(completion_callback) {} |
526 | 550 |
527 DownloadFileImpl::RenameParameters::~RenameParameters() {} | 551 DownloadFileImpl::RenameParameters::~RenameParameters() {} |
528 | 552 |
529 } // namespace content | 553 } // namespace content |
OLD | NEW |