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

Side by Side Diff: net/quic/core/quic_frame_list.cc

Issue 2560423002: Remove unused QuicFrameList (Closed)
Patch Set: Created 4 years 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
« no previous file with comments | « net/quic/core/quic_frame_list.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
(Empty)
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/quic/core/quic_frame_list.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10
11 using std::string;
12
13 namespace net {
14
15 QuicFrameList::FrameData::FrameData(QuicStreamOffset offset,
16 string segment,
17 const QuicTime timestamp)
18 : offset(offset), segment(segment), timestamp(timestamp) {}
19
20 QuicFrameList::QuicFrameList() {}
21
22 QuicFrameList::~QuicFrameList() {
23 Clear();
24 }
25
26 void QuicFrameList::Clear() {
27 frame_list_.clear();
28 num_bytes_buffered_ = 0;
29 }
30
31 bool QuicFrameList::Empty() const {
32 return frame_list_.empty();
33 }
34
35 QuicErrorCode QuicFrameList::OnStreamData(QuicStreamOffset offset,
36 base::StringPiece data,
37 QuicTime timestamp,
38 size_t* const bytes_buffered) {
39 *bytes_buffered = 0;
40 const size_t data_len = data.size();
41 auto insertion_point = FindInsertionPoint(offset, data_len);
42 if (IsDuplicate(offset, data_len, insertion_point)) {
43 return QUIC_NO_ERROR;
44 }
45
46 if (FrameOverlapsBufferedData(offset, data_len, insertion_point)) {
47 return QUIC_INVALID_STREAM_DATA;
48 }
49
50 DVLOG(1) << "Buffering stream data at offset " << offset;
51 // Inserting an empty string and then copying to avoid the extra copy.
52 insertion_point =
53 frame_list_.insert(insertion_point, FrameData(offset, "", timestamp));
54 data.CopyToString(&insertion_point->segment);
55 *bytes_buffered = data_len;
56 num_bytes_buffered_ += data_len;
57 return QUIC_NO_ERROR;
58 }
59
60 // Finds the place the frame should be inserted. If an identical frame is
61 // present, stops on the identical frame.
62 std::list<QuicFrameList::FrameData>::iterator QuicFrameList::FindInsertionPoint(
63 QuicStreamOffset offset,
64 size_t len) {
65 if (frame_list_.empty()) {
66 return frame_list_.begin();
67 }
68 // If it's after all buffered_frames, return the end.
69 if (offset >=
70 (frame_list_.rbegin()->offset + frame_list_.rbegin()->segment.length())) {
71 return frame_list_.end();
72 }
73 auto iter = frame_list_.begin();
74 // Only advance the iterator if the data begins after the already received
75 // frame. If the new frame overlaps with an existing frame, the iterator will
76 // still point to the frame it overlaps with.
77 while (iter != frame_list_.end() &&
78 offset >= iter->offset + iter->segment.length()) {
79 ++iter;
80 }
81 return iter;
82 }
83
84 // Returns true if |frame| contains data which overlaps buffered data
85 // (indicating an invalid stream frame has been received).
86 bool QuicFrameList::FrameOverlapsBufferedData(
87 QuicStreamOffset offset,
88 size_t data_len,
89 std::list<FrameData>::const_iterator insertion_point) const {
90 if (frame_list_.empty() || insertion_point == frame_list_.end()) {
91 return false;
92 }
93 // If there is a buffered frame with a higher starting offset, then check to
94 // see if the new frame overlaps the beginning of the higher frame.
95 if (offset < insertion_point->offset &&
96 offset + data_len > insertion_point->offset) {
97 DVLOG(1) << "New frame overlaps next frame: " << offset << " + " << data_len
98 << " > " << insertion_point->offset;
99 return true;
100 }
101 // If there is a buffered frame with a lower starting offset, then check to
102 // see if the buffered frame runs into the new frame.
103 if (offset >= insertion_point->offset &&
104 offset < insertion_point->offset + insertion_point->segment.length()) {
105 DVLOG(1) << "Preceeding frame overlaps new frame: "
106 << insertion_point->offset << " + "
107 << insertion_point->segment.length() << " > " << offset;
108 return true;
109 }
110
111 return false;
112 }
113
114 // Returns true if the sequencer has received this frame before.
115 bool QuicFrameList::IsDuplicate(
116 QuicStreamOffset offset,
117 size_t data_len,
118 std::list<FrameData>::const_iterator insertion_point) const {
119 // A frame is duplicate if the frame offset is smaller than the bytes consumed
120 // or identical to an already received frame.
121 return offset < total_bytes_read_ || (insertion_point != frame_list_.end() &&
122 offset == insertion_point->offset);
123 }
124
125 int QuicFrameList::GetReadableRegions(struct iovec* iov, int iov_len) const {
126 std::list<FrameData>::const_iterator it = frame_list_.begin();
127 int index = 0;
128 QuicStreamOffset offset = total_bytes_read_;
129 while (it != frame_list_.end() && index < iov_len) {
130 if (it->offset != offset) {
131 return index;
132 }
133
134 iov[index].iov_base =
135 static_cast<void*>(const_cast<char*>(it->segment.data()));
136 iov[index].iov_len = it->segment.size();
137 offset += it->segment.size();
138
139 ++index;
140 ++it;
141 }
142 return index;
143 }
144
145 bool QuicFrameList::GetReadableRegion(iovec* iov, QuicTime* timestamp) const {
146 std::list<FrameData>::const_iterator it = frame_list_.begin();
147 if (it == frame_list_.end() || it->offset != total_bytes_read_) {
148 return false;
149 }
150 iov->iov_base = static_cast<void*>(const_cast<char*>(it->segment.data()));
151 iov->iov_len = it->segment.size();
152 *timestamp = it->timestamp;
153 return true;
154 }
155
156 bool QuicFrameList::MarkConsumed(size_t bytes_used) {
157 size_t end_offset = total_bytes_read_ + bytes_used;
158 while (!frame_list_.empty() && end_offset != total_bytes_read_) {
159 std::list<FrameData>::iterator it = frame_list_.begin();
160 if (it->offset != total_bytes_read_) {
161 return false;
162 }
163
164 if (it->offset + it->segment.length() <= end_offset) {
165 total_bytes_read_ += it->segment.length();
166 num_bytes_buffered_ -= it->segment.length();
167 // This chunk is entirely consumed.
168 frame_list_.erase(it);
169 continue;
170 }
171
172 // Partially consume this frame.
173 size_t delta = end_offset - it->offset;
174 total_bytes_read_ += delta;
175 num_bytes_buffered_ -= delta;
176 string new_data = it->segment.substr(delta);
177 const QuicTime timestamp = it->timestamp;
178 frame_list_.erase(it);
179 frame_list_.push_front(FrameData(total_bytes_read_, new_data, timestamp));
180 break;
181 }
182 return true;
183 }
184
185 size_t QuicFrameList::Readv(const struct iovec* iov, size_t iov_len) {
186 std::list<FrameData>::iterator it = frame_list_.begin();
187 size_t iov_index = 0;
188 size_t iov_offset = 0;
189 size_t frame_offset = 0;
190 QuicStreamOffset initial_bytes_consumed = total_bytes_read_;
191
192 while (iov_index < iov_len && it != frame_list_.end() &&
193 it->offset == total_bytes_read_) {
194 int bytes_to_read = std::min(iov[iov_index].iov_len - iov_offset,
195 it->segment.size() - frame_offset);
196
197 char* iov_ptr = static_cast<char*>(iov[iov_index].iov_base) + iov_offset;
198 memcpy(iov_ptr, it->segment.data() + frame_offset, bytes_to_read);
199 frame_offset += bytes_to_read;
200 iov_offset += bytes_to_read;
201
202 if (iov[iov_index].iov_len == iov_offset) {
203 // We've filled this buffer.
204 iov_offset = 0;
205 ++iov_index;
206 }
207 if (it->segment.size() == frame_offset) {
208 // We've copied this whole frame
209 total_bytes_read_ += it->segment.size();
210 num_bytes_buffered_ -= it->segment.size();
211 frame_list_.erase(it);
212 it = frame_list_.begin();
213 frame_offset = 0;
214 }
215 }
216 // Done copying. If there is a partial frame, update it.
217 if (frame_offset != 0) {
218 frame_list_.push_front(FrameData(it->offset + frame_offset,
219 it->segment.substr(frame_offset),
220 it->timestamp));
221 frame_list_.erase(it);
222 total_bytes_read_ += frame_offset;
223 num_bytes_buffered_ -= frame_offset;
224 }
225 return total_bytes_read_ - initial_bytes_consumed;
226 }
227
228 size_t QuicFrameList::FlushBufferedFrames() {
229 QuicStreamOffset initial_bytes_consumed = total_bytes_read_;
230 if (!frame_list_.empty()) {
231 // Consume all of the bytes up to the last byte yet seen, including the
232 // ones that haven't arrived yet.
233 auto it = frame_list_.back();
234 total_bytes_read_ = it.offset + it.segment.length();
235 frame_list_.clear();
236 }
237 return total_bytes_read_ - initial_bytes_consumed;
238 }
239
240 bool QuicFrameList::HasBytesToRead() const {
241 return !frame_list_.empty() &&
242 frame_list_.begin()->offset == total_bytes_read_;
243 }
244
245 QuicStreamOffset QuicFrameList::BytesConsumed() const {
246 return total_bytes_read_;
247 }
248
249 size_t QuicFrameList::BytesBuffered() const {
250 return num_bytes_buffered_;
251 }
252
253 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/core/quic_frame_list.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698