Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: chrome/browser/chromeos/drive/drive_url_request_job.cc

Issue 13065007: Fix data overwriting issue on ReadFromDownloadData. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address review comments. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/chromeos/drive/drive_url_request_job.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/drive/drive_url_request_job.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698