OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/chromeos/drive/drive_url_request_job.h" | 5 #include "chrome/browser/chromeos/drive/drive_url_request_job.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstring> | 8 #include <cstring> |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 weak_ptr_factory_.GetWeakPtr())); | 467 weak_ptr_factory_.GetWeakPtr())); |
468 } | 468 } |
469 | 469 |
470 void DriveURLRequestJob::OnUrlFetchDownloadData( | 470 void DriveURLRequestJob::OnUrlFetchDownloadData( |
471 google_apis::GDataErrorCode error, | 471 google_apis::GDataErrorCode error, |
472 scoped_ptr<std::string> download_data) { | 472 scoped_ptr<std::string> download_data) { |
473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
474 | 474 |
475 if (download_data->empty()) | 475 if (download_data->empty()) |
476 return; | 476 return; |
477 // Copy from download data into download buffer. | 477 |
478 download_buf_.assign(download_data->data(), download_data->length()); | 478 // Move the ownership from |download_data| to |pending_downloaded_data_|. |
479 download_buf_remaining_.set(download_buf_.data(), download_buf_.size()); | 479 pending_downloaded_data_.push_back(download_data.release()); |
| 480 |
480 // If this is the first data we have, report request has started successfully. | 481 // If this is the first data we have, report request has started successfully. |
481 if (!streaming_download_) { | 482 if (!streaming_download_) { |
482 streaming_download_ = true; | 483 streaming_download_ = true; |
483 DVLOG(1) << "Request started successfully: expected_download_size=" | 484 DVLOG(1) << "Request started successfully: expected_download_size=" |
484 << remaining_bytes_; | 485 << remaining_bytes_; |
485 NotifySuccess(); | 486 NotifySuccess(); |
486 return; | 487 return; |
487 } | 488 } |
488 | 489 |
489 // Otherwise, read from download data into read buffer of response. | 490 // Otherwise, read from download data into read buffer of response. |
(...skipping 23 matching lines...) Expand all Loading... |
513 // read. | 514 // read. |
514 *bytes_read = BytesReadCompleted(); | 515 *bytes_read = BytesReadCompleted(); |
515 DVLOG(1) << "Has data: bytes_read=" << *bytes_read | 516 DVLOG(1) << "Has data: bytes_read=" << *bytes_read |
516 << ", buf_remaining=0, download_remaining=" << remaining_bytes_; | 517 << ", buf_remaining=0, download_remaining=" << remaining_bytes_; |
517 return true; | 518 return true; |
518 } | 519 } |
519 | 520 |
520 bool DriveURLRequestJob::ReadFromDownloadData() { | 521 bool DriveURLRequestJob::ReadFromDownloadData() { |
521 DCHECK(streaming_download_); | 522 DCHECK(streaming_download_); |
522 | 523 |
523 // If download buffer is empty or there's no read buffer, return false. | 524 // If either download data or read buffer is not available, do nothing. |
524 if (download_buf_remaining_.empty() || | 525 if (pending_downloaded_data_.empty() || |
525 !read_buf_ || read_buf_remaining_.empty()) { | 526 !read_buf_ || read_buf_remaining_.empty()) { |
526 return false; | 527 return false; |
527 } | 528 } |
528 | 529 |
529 // Number of bytes to read is the lesser of remaining bytes in read buffer or | 530 // Copy the downloaded data to |read_buf_| as much as possible. |
530 // written bytes in download buffer. | 531 size_t index = 0; |
531 int bytes_to_read = std::min(read_buf_remaining_.size(), | 532 for (; |
532 download_buf_remaining_.size()); | 533 index < pending_downloaded_data_.size() && !read_buf_remaining_.empty(); |
533 // If read buffer doesn't have enough space, there will be bytes in download | 534 ++index) { |
534 // buffer that will not be copied to read buffer. | 535 const std::string& chunk = *pending_downloaded_data_[index]; |
535 int bytes_not_copied = download_buf_remaining_.size() - bytes_to_read; | 536 DCHECK(!chunk.empty()); |
536 // Copy from download buffer to read buffer. | 537 if (chunk.size() > read_buf_remaining_.size()) { |
537 const size_t offset = read_buf_remaining_.data() - read_buf_->data(); | 538 // There is no enough space to store the chunk'ed data. |
538 std::memmove(read_buf_->data() + offset, download_buf_remaining_.data(), | 539 // So copy the first part, consume it, and end the loop without |
539 bytes_to_read); | 540 // increment |index|. |
540 // Advance read buffer. | 541 int bytes_to_read = read_buf_remaining_.size(); |
541 RecordBytesRead(bytes_to_read); | 542 const size_t offset = read_buf_remaining_.data() - read_buf_->data(); |
542 DVLOG(1) << "Copied from download data: bytes_read=" << bytes_to_read; | 543 std::memmove(read_buf_->data() + offset, chunk.data(), bytes_to_read); |
543 // If download buffer has bytes that are not copied over, move them to | 544 RecordBytesRead(bytes_to_read); |
544 // beginning of download buffer. | 545 DVLOG(1) << "Copied from download data: bytes_read=" << bytes_to_read; |
545 if (bytes_not_copied > 0) | 546 pending_downloaded_data_[index]->erase(0, bytes_to_read); |
546 download_buf_remaining_.remove_prefix(bytes_to_read); | 547 break; |
| 548 } |
| 549 |
| 550 const size_t offset = read_buf_remaining_.data() - read_buf_->data(); |
| 551 std::memmove(read_buf_->data() + offset, chunk.data(), chunk.size()); |
| 552 RecordBytesRead(chunk.size()); |
| 553 DVLOG(1) << "Copied from download data: bytes_read=" << chunk.size(); |
| 554 } |
| 555 |
| 556 // Consume the copied downloaded data. |
| 557 pending_downloaded_data_.erase(pending_downloaded_data_.begin(), |
| 558 pending_downloaded_data_.begin() + index); |
547 | 559 |
548 // Return true if read buffer is filled up or there's no more bytes to read. | 560 // Return true if read buffer is filled up or there's no more bytes to read. |
549 return read_buf_remaining_.empty() || remaining_bytes_ == 0; | 561 return read_buf_remaining_.empty() || remaining_bytes_ == 0; |
550 } | 562 } |
551 | 563 |
552 void DriveURLRequestJob::OnGetFileByResourceId( | 564 void DriveURLRequestJob::OnGetFileByResourceId( |
553 DriveFileError error, | 565 DriveFileError error, |
554 const base::FilePath& local_file_path, | 566 const base::FilePath& local_file_path, |
555 const std::string& mime_type, | 567 const std::string& mime_type, |
556 DriveFileType file_type) { | 568 DriveFileType file_type) { |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 response_info_.reset(new net::HttpResponseInfo()); | 805 response_info_.reset(new net::HttpResponseInfo()); |
794 response_info_->headers = headers; | 806 response_info_->headers = headers; |
795 | 807 |
796 set_expected_content_size(remaining_bytes_); | 808 set_expected_content_size(remaining_bytes_); |
797 headers_set_ = true; | 809 headers_set_ = true; |
798 | 810 |
799 NotifyHeadersComplete(); | 811 NotifyHeadersComplete(); |
800 } | 812 } |
801 | 813 |
802 } // namespace drive | 814 } // namespace drive |
OLD | NEW |