| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "net/base/upload_data_stream.h" | 5 #include "net/base/upload_data_stream.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "net/base/io_buffer.h" | 8 #include "net/base/io_buffer.h" |
| 9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
| 10 #include "net/base/upload_element_reader.h" | 10 #include "net/base/upload_element_reader.h" |
| 11 | 11 |
| 12 namespace net { | 12 namespace net { |
| 13 | 13 |
| 14 bool UploadDataStream::merge_chunks_ = true; | 14 bool UploadDataStream::merge_chunks_ = true; |
| 15 | 15 |
| 16 // static | 16 // static |
| 17 void UploadDataStream::ResetMergeChunks() { | 17 void UploadDataStream::ResetMergeChunks() { |
| 18 // WARNING: merge_chunks_ must match the above initializer. | 18 // WARNING: merge_chunks_ must match the above initializer. |
| 19 merge_chunks_ = true; | 19 merge_chunks_ = true; |
| 20 } | 20 } |
| 21 | 21 |
| 22 UploadDataStream::UploadDataStream(UploadData* upload_data) | 22 UploadDataStream::UploadDataStream(UploadData* upload_data) |
| 23 : upload_data_(upload_data), | 23 : upload_data_(upload_data), |
| 24 element_index_(0), | 24 element_index_(0), |
| 25 total_size_(0), | 25 total_size_(0), |
| 26 current_position_(0), | 26 current_position_(0), |
| 27 initialized_successfully_(false) { | 27 initialized_successfully_(false), |
| 28 weak_ptr_factory_(this) { |
| 28 const std::vector<UploadElement>& elements = *upload_data_->elements(); | 29 const std::vector<UploadElement>& elements = *upload_data_->elements(); |
| 29 for (size_t i = 0; i < elements.size(); ++i) | 30 for (size_t i = 0; i < elements.size(); ++i) |
| 30 element_readers_.push_back(UploadElementReader::Create(elements[i])); | 31 element_readers_.push_back(UploadElementReader::Create(elements[i])); |
| 31 } | 32 } |
| 32 | 33 |
| 33 UploadDataStream::~UploadDataStream() { | 34 UploadDataStream::~UploadDataStream() { |
| 34 } | 35 } |
| 35 | 36 |
| 36 int UploadDataStream::Init() { | 37 int UploadDataStream::Init(const CompletionCallback& callback) { |
| 37 DCHECK(!initialized_successfully_); | 38 DCHECK(!initialized_successfully_); |
| 38 | 39 |
| 39 uint64 total_size = 0; | 40 // Use fast path when initialization can be done synchronously. |
| 41 if (IsInMemory()) |
| 42 return InitSync(); |
| 43 |
| 44 InitInternal(0, callback, OK); |
| 45 return ERR_IO_PENDING; |
| 46 } |
| 47 |
| 48 int UploadDataStream::InitSync() { |
| 49 DCHECK(!initialized_successfully_); |
| 50 |
| 51 // Initialize all readers synchronously. |
| 40 for (size_t i = 0; i < element_readers_.size(); ++i) { | 52 for (size_t i = 0; i < element_readers_.size(); ++i) { |
| 41 UploadElementReader* reader = element_readers_[i]; | 53 UploadElementReader* reader = element_readers_[i]; |
| 42 const int result = reader->InitSync(); | 54 const int result = reader->InitSync(); |
| 43 if (result != OK) | 55 if (result != OK) { |
| 56 element_readers_.clear(); |
| 44 return result; | 57 return result; |
| 45 if (!is_chunked()) | 58 } |
| 46 total_size += reader->GetContentLength(); | |
| 47 } | 59 } |
| 48 total_size_ = total_size; | |
| 49 | 60 |
| 50 initialized_successfully_ = true; | 61 FinalizeInitialization(); |
| 51 return OK; | 62 return OK; |
| 52 } | 63 } |
| 53 | 64 |
| 54 int UploadDataStream::Read(IOBuffer* buf, int buf_len) { | 65 int UploadDataStream::Read(IOBuffer* buf, int buf_len) { |
| 55 DCHECK(initialized_successfully_); | 66 DCHECK(initialized_successfully_); |
| 56 | 67 |
| 57 // Initialize readers for newly appended chunks. | 68 // Initialize readers for newly appended chunks. |
| 58 if (is_chunked()) { | 69 if (is_chunked()) { |
| 59 const std::vector<UploadElement>& elements = *upload_data_->elements(); | 70 const std::vector<UploadElement>& elements = *upload_data_->elements(); |
| 60 DCHECK_LE(element_readers_.size(), elements.size()); | 71 DCHECK_LE(element_readers_.size(), elements.size()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 if (is_chunked()) | 122 if (is_chunked()) |
| 112 return false; | 123 return false; |
| 113 | 124 |
| 114 for (size_t i = 0; i < element_readers_.size(); ++i) { | 125 for (size_t i = 0; i < element_readers_.size(); ++i) { |
| 115 if (!element_readers_[i]->IsInMemory()) | 126 if (!element_readers_[i]->IsInMemory()) |
| 116 return false; | 127 return false; |
| 117 } | 128 } |
| 118 return true; | 129 return true; |
| 119 } | 130 } |
| 120 | 131 |
| 132 void UploadDataStream::InitInternal(int start_index, |
| 133 const CompletionCallback& callback, |
| 134 int previous_result) { |
| 135 DCHECK(!initialized_successfully_); |
| 136 DCHECK_NE(ERR_IO_PENDING, previous_result); |
| 137 |
| 138 // Check the last result. |
| 139 if (previous_result != OK) { |
| 140 element_readers_.clear(); |
| 141 callback.Run(previous_result); |
| 142 return; |
| 143 } |
| 144 |
| 145 // Call Init() for all elements. |
| 146 for (size_t i = start_index; i < element_readers_.size(); ++i) { |
| 147 UploadElementReader* reader = element_readers_[i]; |
| 148 // When new_result is ERR_IO_PENDING, InitInternal() will be called |
| 149 // with start_index == i + 1 when reader->Init() finishes. |
| 150 const int new_result = reader->Init( |
| 151 base::Bind(&UploadDataStream::InitInternal, |
| 152 weak_ptr_factory_.GetWeakPtr(), |
| 153 i + 1, |
| 154 callback)); |
| 155 if (new_result != OK) { |
| 156 if (new_result != ERR_IO_PENDING) { |
| 157 element_readers_.clear(); |
| 158 callback.Run(new_result); |
| 159 } |
| 160 return; |
| 161 } |
| 162 } |
| 163 |
| 164 // Finalize initialization. |
| 165 FinalizeInitialization(); |
| 166 callback.Run(OK); |
| 167 } |
| 168 |
| 169 void UploadDataStream::FinalizeInitialization() { |
| 170 DCHECK(!initialized_successfully_); |
| 171 if (!is_chunked()) { |
| 172 uint64 total_size = 0; |
| 173 for (size_t i = 0; i < element_readers_.size(); ++i) { |
| 174 UploadElementReader* reader = element_readers_[i]; |
| 175 total_size += reader->GetContentLength(); |
| 176 } |
| 177 total_size_ = total_size; |
| 178 } |
| 179 initialized_successfully_ = true; |
| 180 } |
| 181 |
| 121 } // namespace net | 182 } // namespace net |
| OLD | NEW |