Chromium Code Reviews| Index: net/base/upload_data.cc |
| diff --git a/net/base/upload_data.cc b/net/base/upload_data.cc |
| index d4453070922e44f4a8daa853e5a7d1d594a20add..6847f30cf1ebe3ddff4c82793e32ea231bb6e388 100644 |
| --- a/net/base/upload_data.cc |
| +++ b/net/base/upload_data.cc |
| @@ -37,6 +37,7 @@ UploadData::Element::Element() |
| override_content_length_(false), |
| content_length_computed_(false), |
| content_length_(-1), |
| + offset_(0), |
| file_stream_(NULL) { |
| } |
| @@ -82,7 +83,7 @@ uint64 UploadData::Element::GetContentLength() { |
| // We need to open the file here to decide if we should report the file's |
| // size or zero. We cache the open file, so that we can still read it when |
| // it comes time to. |
| - file_stream_ = NewFileStreamForReading(); |
| + file_stream_ = OpenFileStream(); |
| if (!file_stream_) |
| return 0; |
| @@ -98,16 +99,22 @@ uint64 UploadData::Element::GetContentLength() { |
| return content_length_; |
| } |
| -FileStream* UploadData::Element::NewFileStreamForReading() { |
| - // In common usage GetContentLength() will call this first and store the |
| - // result into |file_| and a subsequent call (from UploadDataStream) will |
| - // get the cached open FileStream. |
| - if (file_stream_) { |
| - FileStream* file = file_stream_; |
| - file_stream_ = NULL; |
| - return file; |
| +int UploadData::Element::ReadSync(char* buf, int buf_len) { |
| + if (type_ == UploadData::TYPE_BYTES || type_ == UploadData::TYPE_CHUNK) { |
| + return ReadFromMemorySync(buf, buf_len); |
| + } else if (type_ == UploadData::TYPE_FILE) { |
| + return ReadFromFileSync(buf, buf_len); |
| } |
| + NOTREACHED(); |
| + return 0; |
| +} |
| + |
| +uint64 UploadData::Element::BytesRemaining() { |
| + return GetContentLength() - offset_; |
| +} |
| + |
| +FileStream* UploadData::Element::OpenFileStream() { |
| scoped_ptr<FileStream> file(new FileStream(NULL)); |
| int64 rv = file->OpenSync( |
| file_path_, |
| @@ -131,6 +138,59 @@ FileStream* UploadData::Element::NewFileStreamForReading() { |
| return file.release(); |
| } |
| +int UploadData::Element::ReadFromMemorySync(char* buf, int buf_len) { |
|
willchan no longer on Chromium
2012/02/24 21:54:40
Can you DCHECK that buf_len is positive (it should
satorux1
2012/02/24 22:35:22
Done. Updated the comment as well.
|
| + DCHECK(type_ == UploadData::TYPE_BYTES || type_ == UploadData::TYPE_CHUNK); |
| + |
| + const size_t num_bytes_to_read = std::min(BytesRemaining(), |
| + static_cast<size_t>(buf_len)); |
| + |
| + // Check if we have anything to copy first, because we are getting |
| + // the address of an element in |bytes_| and that will throw an |
| + // exception if |bytes_| is an empty vector. |
| + if (num_bytes_to_read > 0) { |
| + memcpy(buf, &bytes_[offset_], num_bytes_to_read); |
| + } |
| + |
| + offset_ += num_bytes_to_read; |
| + return num_bytes_to_read; |
| +} |
| + |
| +int UploadData::Element::ReadFromFileSync(char* buf, int buf_len) { |
|
willchan no longer on Chromium
2012/02/24 21:54:40
Ditto on DCHECK'ing |buf_len|'s values.
satorux1
2012/02/24 22:35:22
Done.
|
| + DCHECK_EQ(UploadData::TYPE_FILE, type_); |
| + |
| + // Open the file of the current element if not yet opened. |
| + // In common usage, GetContentLength() opened it already. |
| + if (!file_stream_) { |
| + // Temporarily allow until fix: http://crbug.com/72001. |
| + base::ThreadRestrictions::ScopedAllowIO allow_io; |
| + file_stream_ = OpenFileStream(); |
| + } |
| + |
| + const int num_bytes_to_read = |
| + static_cast<int>(std::min(BytesRemaining(), |
| + static_cast<uint64>(buf_len))); |
| + if (num_bytes_to_read > 0) { |
| + int num_bytes_consumed = 0; |
| + // Temporarily allow until fix: http://crbug.com/72001. |
| + base::ThreadRestrictions::ScopedAllowIO allow_io; |
| + // file_stream_ is NULL if the target file is |
| + // missing or not readable. |
| + if (file_stream_) { |
| + num_bytes_consumed = |
| + file_stream_->ReadSync(buf, num_bytes_to_read); |
| + } |
| + if (num_bytes_consumed <= 0) { |
| + // If there's less data to read than we initially observed, then |
| + // pad with zero. Otherwise the server will hang waiting for the |
| + // rest of the data. |
| + memset(buf, 0, num_bytes_to_read); |
| + } |
| + } |
| + |
| + offset_ += num_bytes_to_read; |
| + return num_bytes_to_read; |
| +} |
| + |
| UploadData::UploadData() |
| : identifier_(0), |
| chunk_callback_(NULL), |