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

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: move resetoffset to init 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
« no previous file with comments | « 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 17 matching lines...) Expand all
50 base::ThreadRestrictions::ScopedAllowIO allow_io; 48 base::ThreadRestrictions::ScopedAllowIO allow_io;
51 base::PlatformFileInfo info; 49 base::PlatformFileInfo info;
52 if (file_util::GetFileInfo(element.file_path(), &info) && 50 if (file_util::GetFileInfo(element.file_path(), &info) &&
53 element.expected_file_modification_time().ToTimeT() != 51 element.expected_file_modification_time().ToTimeT() !=
54 info.last_modified.ToTimeT()) { 52 info.last_modified.ToTimeT()) {
55 return ERR_UPLOAD_FILE_CHANGED; 53 return ERR_UPLOAD_FILE_CHANGED;
56 } 54 }
57 } 55 }
58 } 56 }
59 57
58 // Reset the offset, as upload_data_ may already be read (i.e. UploadData
59 // can be reused for a new UploadDataStream).
60 upload_data_->ResetOffset();
61
60 initialized_successfully_ = true; 62 initialized_successfully_ = true;
61 return OK; 63 return OK;
62 } 64 }
63 65
64 int UploadDataStream::Read(IOBuffer* buf, int buf_len) { 66 int UploadDataStream::Read(IOBuffer* buf, int buf_len) {
65 std::vector<UploadData::Element>& elements = *upload_data_->elements(); 67 std::vector<UploadData::Element>& elements = *upload_data_->elements();
66 68
67 int bytes_copied = 0; 69 int bytes_copied = 0;
68 while (bytes_copied < buf_len && element_index_ < elements.size()) { 70 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_]; 71 UploadData::Element& element = elements[element_index_];
73 72
74 const size_t free_buffer_space = buf_len - bytes_copied; 73 bytes_copied += element.ReadSync(buf->data() + bytes_copied,
75 if (element.type() == UploadData::TYPE_BYTES || 74 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 75
81 const size_t num_bytes_to_copy = std::min(num_bytes_left_in_element, 76 if (element.BytesRemaining() == 0)
82 free_buffer_space); 77 ++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 78
143 if (is_chunked() && !merge_chunks_) 79 if (is_chunked() && !merge_chunks_)
144 break; 80 break;
145 } 81 }
146 82
147 current_position_ += bytes_copied; 83 current_position_ += bytes_copied;
148 if (is_chunked() && !IsEOF() && bytes_copied == 0) 84 if (is_chunked() && !IsEOF() && bytes_copied == 0)
149 return ERR_IO_PENDING; 85 return ERR_IO_PENDING;
150 86
151 return bytes_copied; 87 return bytes_copied;
152 } 88 }
153 89
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 { 90 bool UploadDataStream::IsEOF() const {
167 const std::vector<UploadData::Element>& elements = *upload_data_->elements(); 91 const std::vector<UploadData::Element>& elements = *upload_data_->elements();
168 92
169 // Check if all elements are consumed. 93 // Check if all elements are consumed.
170 if (element_index_ == elements.size()) { 94 if (element_index_ == elements.size()) {
171 // If the upload data is chunked, check if the last element is the 95 // If the upload data is chunked, check if the last element is the
172 // last chunk. 96 // last chunk.
173 if (!upload_data_->is_chunked() || 97 if (!upload_data_->is_chunked() ||
174 (!elements.empty() && elements.back().is_last_chunk())) { 98 (!elements.empty() && elements.back().is_last_chunk())) {
175 return true; 99 return true;
176 } 100 }
177 } 101 }
178 return false; 102 return false;
179 } 103 }
180 104
181 bool UploadDataStream::IsInMemory() const { 105 bool UploadDataStream::IsInMemory() const {
182 DCHECK(initialized_successfully_); 106 DCHECK(initialized_successfully_);
183 107
184 return upload_data_->IsInMemory(); 108 return upload_data_->IsInMemory();
185 } 109 }
186 110
187 } // namespace net 111 } // namespace net
OLDNEW
« no previous file with comments | « net/base/upload_data_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698