| Index: chrome/browser/chromeos/drive/drive_url_request_job.cc
|
| diff --git a/chrome/browser/chromeos/drive/drive_url_request_job.cc b/chrome/browser/chromeos/drive/drive_url_request_job.cc
|
| index 7e49895fdb8afe84e48ad505e21fb6dca256293f..6e34cf2fbf85a6030a11e6e36f3a3c23eda82182 100644
|
| --- a/chrome/browser/chromeos/drive/drive_url_request_job.cc
|
| +++ b/chrome/browser/chromeos/drive/drive_url_request_job.cc
|
| @@ -474,9 +474,10 @@ void DriveURLRequestJob::OnUrlFetchDownloadData(
|
|
|
| if (download_data->empty())
|
| return;
|
| - // Copy from download data into download buffer.
|
| - download_buf_.assign(download_data->data(), download_data->length());
|
| - download_buf_remaining_.set(download_buf_.data(), download_buf_.size());
|
| +
|
| + // Move the ownership from |download_data| to |pending_downloaded_data_|.
|
| + pending_downloaded_data_.push_back(download_data.release());
|
| +
|
| // If this is the first data we have, report request has started successfully.
|
| if (!streaming_download_) {
|
| streaming_download_ = true;
|
| @@ -520,30 +521,41 @@ bool DriveURLRequestJob::ContinueReadFromDownloadData(int* bytes_read) {
|
| bool DriveURLRequestJob::ReadFromDownloadData() {
|
| DCHECK(streaming_download_);
|
|
|
| - // If download buffer is empty or there's no read buffer, return false.
|
| - if (download_buf_remaining_.empty() ||
|
| + // If either download data or read buffer is not available, do nothing.
|
| + if (pending_downloaded_data_.empty() ||
|
| !read_buf_ || read_buf_remaining_.empty()) {
|
| return false;
|
| }
|
|
|
| - // Number of bytes to read is the lesser of remaining bytes in read buffer or
|
| - // written bytes in download buffer.
|
| - int bytes_to_read = std::min(read_buf_remaining_.size(),
|
| - download_buf_remaining_.size());
|
| - // If read buffer doesn't have enough space, there will be bytes in download
|
| - // buffer that will not be copied to read buffer.
|
| - int bytes_not_copied = download_buf_remaining_.size() - bytes_to_read;
|
| - // Copy from download buffer to read buffer.
|
| - const size_t offset = read_buf_remaining_.data() - read_buf_->data();
|
| - std::memmove(read_buf_->data() + offset, download_buf_remaining_.data(),
|
| - bytes_to_read);
|
| - // Advance read buffer.
|
| - RecordBytesRead(bytes_to_read);
|
| - DVLOG(1) << "Copied from download data: bytes_read=" << bytes_to_read;
|
| - // If download buffer has bytes that are not copied over, move them to
|
| - // beginning of download buffer.
|
| - if (bytes_not_copied > 0)
|
| - download_buf_remaining_.remove_prefix(bytes_to_read);
|
| + // Copy the downloaded data to |read_buf_| as much as possible.
|
| + size_t index = 0;
|
| + for (;
|
| + index < pending_downloaded_data_.size() && !read_buf_remaining_.empty();
|
| + ++index) {
|
| + const std::string& chunk = *pending_downloaded_data_[index];
|
| + DCHECK(!chunk.empty());
|
| + if (chunk.size() > read_buf_remaining_.size()) {
|
| + // There is no enough space to store the chunk'ed data.
|
| + // So copy the first part, consume it, and end the loop without
|
| + // increment |index|.
|
| + int bytes_to_read = read_buf_remaining_.size();
|
| + const size_t offset = read_buf_remaining_.data() - read_buf_->data();
|
| + std::memmove(read_buf_->data() + offset, chunk.data(), bytes_to_read);
|
| + RecordBytesRead(bytes_to_read);
|
| + DVLOG(1) << "Copied from download data: bytes_read=" << bytes_to_read;
|
| + pending_downloaded_data_[index]->erase(0, bytes_to_read);
|
| + break;
|
| + }
|
| +
|
| + const size_t offset = read_buf_remaining_.data() - read_buf_->data();
|
| + std::memmove(read_buf_->data() + offset, chunk.data(), chunk.size());
|
| + RecordBytesRead(chunk.size());
|
| + DVLOG(1) << "Copied from download data: bytes_read=" << chunk.size();
|
| + }
|
| +
|
| + // Consume the copied downloaded data.
|
| + pending_downloaded_data_.erase(pending_downloaded_data_.begin(),
|
| + pending_downloaded_data_.begin() + index);
|
|
|
| // Return true if read buffer is filled up or there's no more bytes to read.
|
| return read_buf_remaining_.empty() || remaining_bytes_ == 0;
|
|
|