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

Side by Side Diff: net/base/upload_data_stream.cc

Issue 9452040: net: Move the logic reading upload elements to UploadData::Element. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 10 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
« net/base/upload_data.cc ('K') | « net/base/upload_data_stream.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 (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/file_util.h" 7 #include "base/file_util.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/threading/thread_restrictions.h" 9 #include "base/threading/thread_restrictions.h"
10 #include "net/base/file_stream.h" 10 #include "net/base/file_stream.h"
11 #include "net/base/io_buffer.h" 11 #include "net/base/io_buffer.h"
12 #include "net/base/net_errors.h" 12 #include "net/base/net_errors.h"
13 13
14 namespace net { 14 namespace net {
15 15
16 bool UploadDataStream::merge_chunks_ = true; 16 bool UploadDataStream::merge_chunks_ = true;
17 17
18 UploadDataStream::UploadDataStream(UploadData* upload_data) 18 UploadDataStream::UploadDataStream(UploadData* upload_data)
19 : upload_data_(upload_data), 19 : upload_data_(upload_data),
20 element_index_(0), 20 element_index_(0),
21 element_offset_(0),
22 element_file_bytes_remaining_(0),
23 total_size_(0), 21 total_size_(0),
24 current_position_(0), 22 current_position_(0),
25 initialized_successfully_(false) { 23 initialized_successfully_(false) {
26 } 24 }
27 25
28 UploadDataStream::~UploadDataStream() { 26 UploadDataStream::~UploadDataStream() {
29 } 27 }
30 28
31 int UploadDataStream::Init() { 29 int UploadDataStream::Init() {
32 DCHECK(!initialized_successfully_); 30 DCHECK(!initialized_successfully_);
(...skipping 26 matching lines...) Expand all
59 57
60 initialized_successfully_ = true; 58 initialized_successfully_ = true;
61 return OK; 59 return OK;
62 } 60 }
63 61
64 int UploadDataStream::Read(IOBuffer* buf, int buf_len) { 62 int UploadDataStream::Read(IOBuffer* buf, int buf_len) {
65 std::vector<UploadData::Element>& elements = *upload_data_->elements(); 63 std::vector<UploadData::Element>& elements = *upload_data_->elements();
66 64
67 int bytes_copied = 0; 65 int bytes_copied = 0;
68 while (bytes_copied < buf_len && element_index_ < elements.size()) { 66 while (bytes_copied < buf_len && element_index_ < elements.size()) {
69 bool advance_to_next_element = false;
70
71 // This is not const as GetContentLength() is not const.
72 UploadData::Element& element = elements[element_index_]; 67 UploadData::Element& element = elements[element_index_];
73 68
74 const size_t free_buffer_space = buf_len - bytes_copied; 69 bytes_copied += element.ReadSync(buf->data() + bytes_copied,
75 if (element.type() == UploadData::TYPE_BYTES || 70 buf_len - bytes_copied);
76 element.type() == UploadData::TYPE_CHUNK) {
77 const std::vector<char>& element_data = element.bytes();
78 const size_t num_bytes_left_in_element =
79 element_data.size() - element_offset_;
80 71
81 const size_t num_bytes_to_copy = std::min(num_bytes_left_in_element, 72 if (element.BytesRemaining() == 0)
82 free_buffer_space); 73 ++element_index_;
83
84 // Check if we have anything to copy first, because we are getting
85 // the address of an element in |element_data| and that will throw an
86 // exception if |element_data| is an empty vector.
87 if (num_bytes_to_copy > 0) {
88 memcpy(buf->data() + bytes_copied, &element_data[element_offset_],
89 num_bytes_to_copy);
90 bytes_copied += num_bytes_to_copy;
91 element_offset_ += num_bytes_to_copy;
92 }
93
94 // Advance to the next element if we have consumed all data in the
95 // current element.
96 if (element_offset_ == element_data.size())
97 advance_to_next_element = true;
98 } else {
99 DCHECK(element.type() == UploadData::TYPE_FILE);
100
101 // Open the file of the current element if not yet opened.
102 if (!element_file_stream_.get()) {
103 element_file_bytes_remaining_ = element.GetContentLength();
104 // Temporarily allow until fix: http://crbug.com/72001.
105 base::ThreadRestrictions::ScopedAllowIO allow_io;
106 element_file_stream_.reset(element.NewFileStreamForReading());
107 }
108
109 const int num_bytes_to_read =
110 static_cast<int>(std::min(element_file_bytes_remaining_,
111 static_cast<uint64>(free_buffer_space)));
112 if (num_bytes_to_read > 0) {
113 int num_bytes_consumed = 0;
114 // Temporarily allow until fix: http://crbug.com/72001.
115 base::ThreadRestrictions::ScopedAllowIO allow_io;
116 // element_file_stream_.get() is NULL if the target file is
117 // missing or not readable.
118 if (element_file_stream_.get()) {
119 num_bytes_consumed =
120 element_file_stream_->ReadSync(buf->data() + bytes_copied,
121 num_bytes_to_read);
122 }
123 if (num_bytes_consumed <= 0) {
124 // If there's less data to read than we initially observed, then
125 // pad with zero. Otherwise the server will hang waiting for the
126 // rest of the data.
127 memset(buf->data() + bytes_copied, 0, num_bytes_to_read);
128 num_bytes_consumed = num_bytes_to_read;
129 }
130 bytes_copied += num_bytes_consumed;
131 element_file_bytes_remaining_ -= num_bytes_consumed;
132 }
133
134 // Advance to the next element if we have consumed all data in the
135 // current element.
136 if (element_file_bytes_remaining_ == 0)
137 advance_to_next_element = true;
138 }
139
140 if (advance_to_next_element)
141 AdvanceToNextElement();
142 74
143 if (is_chunked() && !merge_chunks_) 75 if (is_chunked() && !merge_chunks_)
144 break; 76 break;
145 } 77 }
146 78
147 current_position_ += bytes_copied; 79 current_position_ += bytes_copied;
148 if (is_chunked() && !IsEOF() && bytes_copied == 0) 80 if (is_chunked() && !IsEOF() && bytes_copied == 0)
149 return ERR_IO_PENDING; 81 return ERR_IO_PENDING;
150 82
151 return bytes_copied; 83 return bytes_copied;
152 } 84 }
153 85
154 void UploadDataStream::AdvanceToNextElement() {
155 ++element_index_;
156 element_offset_ = 0;
157 element_file_bytes_remaining_ = 0;
158 if (element_file_stream_.get()) {
159 // Temporarily allow until fix: http://crbug.com/72001.
160 base::ThreadRestrictions::ScopedAllowIO allow_io;
161 element_file_stream_->CloseSync();
162 element_file_stream_.reset();
163 }
164 }
165
166 bool UploadDataStream::IsEOF() const { 86 bool UploadDataStream::IsEOF() const {
167 const std::vector<UploadData::Element>& elements = *upload_data_->elements(); 87 const std::vector<UploadData::Element>& elements = *upload_data_->elements();
168 88
169 // Check if all elements are consumed. 89 // Check if all elements are consumed.
170 if (element_index_ == elements.size()) { 90 if (element_index_ == elements.size()) {
171 // If the upload data is chunked, check if the last element is the 91 // If the upload data is chunked, check if the last element is the
172 // last chunk. 92 // last chunk.
173 if (!upload_data_->is_chunked() || 93 if (!upload_data_->is_chunked() ||
174 (!elements.empty() && elements.back().is_last_chunk())) { 94 (!elements.empty() && elements.back().is_last_chunk())) {
175 return true; 95 return true;
176 } 96 }
177 } 97 }
178 return false; 98 return false;
179 } 99 }
180 100
181 bool UploadDataStream::IsInMemory() const { 101 bool UploadDataStream::IsInMemory() const {
182 DCHECK(initialized_successfully_); 102 DCHECK(initialized_successfully_);
183 103
184 return upload_data_->IsInMemory(); 104 return upload_data_->IsInMemory();
185 } 105 }
186 106
187 } // namespace net 107 } // namespace net
OLDNEW
« net/base/upload_data.cc ('K') | « net/base/upload_data_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698