Chromium Code Reviews| Index: net/base/upload_data_stream.cc |
| diff --git a/net/base/upload_data_stream.cc b/net/base/upload_data_stream.cc |
| index b96680efc3eeaf056276a44b1c2942d4f42f1378..5820fcc9c2a41f9fda6c678ed5cbd750e4e9ac9b 100644 |
| --- a/net/base/upload_data_stream.cc |
| +++ b/net/base/upload_data_stream.cc |
| @@ -4,12 +4,11 @@ |
| #include "net/base/upload_data_stream.h" |
| -#include "base/file_util.h" |
| #include "base/logging.h" |
| #include "base/threading/thread_restrictions.h" |
| -#include "net/base/file_stream.h" |
| #include "net/base/io_buffer.h" |
| #include "net/base/net_errors.h" |
| +#include "net/base/upload_element_reader.h" |
| namespace net { |
| @@ -27,64 +26,84 @@ UploadDataStream::UploadDataStream(UploadData* upload_data) |
| total_size_(0), |
| current_position_(0), |
| initialized_successfully_(false) { |
| + const std::vector<UploadElement>& elements = *upload_data_->elements(); |
| + for (size_t i = 0; i < elements.size(); ++i) { |
| + const UploadElement& element = elements[i]; |
| + UploadElementReader* reader = NULL; |
|
satorux1
2012/08/28 20:42:35
maybe
UploadElementReader* reader = UploadElement
hashimoto
2012/08/28 21:41:20
Done.
|
| + switch (element.type()) { |
| + case UploadElement::TYPE_BYTES: |
| + reader = new UploadBytesElementReader(element.bytes(), |
| + element.bytes_length()); |
| + break; |
| + case UploadElement::TYPE_FILE: |
| + reader = new UploadFileElementReader( |
| + element.file_path(), |
| + element.file_range_offset(), |
| + element.file_range_length(), |
| + element.expected_file_modification_time()); |
| + break; |
| + } |
| + DCHECK(reader); |
| + element_readers_.push_back(reader); |
| + } |
| } |
| UploadDataStream::~UploadDataStream() { |
| + // Temporarily allow until fix: http://crbug.com/72001. |
| + base::ThreadRestrictions::ScopedAllowIO allow_io; |
| + element_readers_.clear(); |
| } |
| int UploadDataStream::Init() { |
| DCHECK(!initialized_successfully_); |
| - std::vector<UploadElement>* elements = upload_data_->elements_mutable(); |
| - { |
| + |
| + uint64 total_size = 0; |
| + for (size_t i = 0; i < element_readers_.size(); ++i) { |
| + // Temporarily allow until fix: http://crbug.com/72001. |
| base::ThreadRestrictions::ScopedAllowIO allow_io; |
| - total_size_ = 0; |
| - if (!is_chunked()) { |
| - for (size_t i = 0; i < elements->size(); ++i) |
| - total_size_ += (*elements)[i].GetContentLength(); |
| - } |
| - } |
| - // If the underlying file has been changed and the expected file |
| - // modification time is set, treat it as error. Note that the expected |
| - // modification time from WebKit is based on time_t precision. So we |
| - // have to convert both to time_t to compare. This check is used for |
| - // sliced files. |
| - for (size_t i = 0; i < elements->size(); ++i) { |
| - const UploadElement& element = (*elements)[i]; |
| - if (element.type() == UploadElement::TYPE_FILE && |
| - !element.expected_file_modification_time().is_null()) { |
| - // Temporarily allow until fix: http://crbug.com/72001. |
| - base::ThreadRestrictions::ScopedAllowIO allow_io; |
| - base::PlatformFileInfo info; |
| - if (file_util::GetFileInfo(element.file_path(), &info) && |
| - element.expected_file_modification_time().ToTimeT() != |
| - info.last_modified.ToTimeT()) { |
| - return ERR_UPLOAD_FILE_CHANGED; |
| - } |
| - } |
| + UploadElementReader* reader = element_readers_[i]; |
| + const int result = reader->InitSync(); |
| + if (result != OK) |
| + return result; |
| + if (!is_chunked()) |
| + total_size += reader->GetContentLength(); |
| } |
| - |
| - // Reset the offset, as upload_data_ may already be read (i.e. UploadData |
| - // can be reused for a new UploadDataStream). |
| - for (size_t i = 0; i < elements->size(); ++i) |
| - (*elements)[i].ResetOffset(); |
| + total_size_ = total_size; |
| initialized_successfully_ = true; |
| return OK; |
| } |
| int UploadDataStream::Read(IOBuffer* buf, int buf_len) { |
| - std::vector<UploadElement>& elements = |
| - *upload_data_->elements_mutable(); |
| + DCHECK(initialized_successfully_); |
| + |
| + // Initialize readers for newly appended chunks. |
| + if (is_chunked()) { |
| + const std::vector<UploadElement>& elements = *upload_data_->elements(); |
| + DCHECK_LE(element_readers_.size(), elements.size()); |
| + |
| + for (size_t i = element_readers_.size(); i < elements.size(); ++i) { |
| + const UploadElement& element = elements[i]; |
| + DCHECK(element.type() == UploadElement::TYPE_BYTES); |
| + UploadElementReader* reader = |
| + new UploadBytesElementReader(element.bytes(), element.bytes_length()); |
| + |
| + const int rv = reader->InitSync(); |
| + DCHECK_EQ(rv, OK); |
| + element_readers_.push_back(reader); |
| + } |
| + } |
| int bytes_copied = 0; |
| - while (bytes_copied < buf_len && element_index_ < elements.size()) { |
| - UploadElement& element = elements[element_index_]; |
| + while (bytes_copied < buf_len && element_index_ < element_readers_.size()) { |
| + // Temporarily allow until fix: http://crbug.com/72001. |
| + base::ThreadRestrictions::ScopedAllowIO allow_io; |
| - bytes_copied += element.ReadSync(buf->data() + bytes_copied, |
| + UploadElementReader* reader = element_readers_[element_index_]; |
| + bytes_copied += reader->ReadSync(buf->data() + bytes_copied, |
| buf_len - bytes_copied); |
| - |
| - if (element.BytesRemaining() == 0) |
| + if (reader->BytesRemaining() == 0) |
| ++element_index_; |
| if (is_chunked() && !merge_chunks_) |
| @@ -99,6 +118,7 @@ int UploadDataStream::Read(IOBuffer* buf, int buf_len) { |
| } |
| bool UploadDataStream::IsEOF() const { |
| + DCHECK(initialized_successfully_); |
| const std::vector<UploadElement>& elements = *upload_data_->elements(); |
| // Check if all elements are consumed. |
| @@ -119,9 +139,8 @@ bool UploadDataStream::IsInMemory() const { |
| if (is_chunked()) |
| return false; |
| - const std::vector<UploadElement>& elements = *upload_data_->elements(); |
| - for (size_t i = 0; i < elements.size(); ++i) { |
| - if (elements[i].type() != UploadElement::TYPE_BYTES) |
| + for (size_t i = 0; i < element_readers_.size(); ++i) { |
| + if (!element_readers_[i]->IsInMemory()) |
| return false; |
| } |
| return true; |