Add reset button for each preference in gesture config UI
[chromium-blink-merge.git] / net / quic / quic_packet_generator.cc
blobe6aeac76f07ba4b11396928edd5cf25f914c08fb
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
3 // found in the LICENSE file.
5 #include "net/quic/quic_packet_generator.h"
7 #include "base/logging.h"
8 #include "net/quic/quic_fec_group.h"
9 #include "net/quic/quic_utils.h"
11 using base::StringPiece;
13 namespace net {
15 QuicPacketGenerator::QuicPacketGenerator(DelegateInterface* delegate,
16 DebugDelegateInterface* debug_delegate,
17 QuicPacketCreator* creator)
18 : delegate_(delegate),
19 debug_delegate_(debug_delegate),
20 packet_creator_(creator),
21 should_flush_(true),
22 should_send_ack_(false),
23 should_send_feedback_(false) {
26 QuicPacketGenerator::~QuicPacketGenerator() {
27 for (QuicFrames::iterator it = queued_control_frames_.begin();
28 it != queued_control_frames_.end(); ++it) {
29 switch (it->type) {
30 case PADDING_FRAME:
31 delete it->padding_frame;
32 break;
33 case STREAM_FRAME:
34 delete it->stream_frame;
35 break;
36 case ACK_FRAME:
37 delete it->ack_frame;
38 break;
39 case CONGESTION_FEEDBACK_FRAME:
40 delete it->congestion_feedback_frame;
41 break;
42 case RST_STREAM_FRAME:
43 delete it->rst_stream_frame;
44 break;
45 case CONNECTION_CLOSE_FRAME:
46 delete it->connection_close_frame;
47 break;
48 case GOAWAY_FRAME:
49 delete it->goaway_frame;
50 break;
51 case NUM_FRAME_TYPES:
52 DCHECK(false) << "Cannot delete type: " << it->type;
57 void QuicPacketGenerator::SetShouldSendAck(bool also_send_feedback) {
58 should_send_ack_ = true;
59 should_send_feedback_ = also_send_feedback;
60 SendQueuedFrames();
64 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) {
65 queued_control_frames_.push_back(frame);
66 SendQueuedFrames();
69 QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id,
70 StringPiece data,
71 QuicStreamOffset offset,
72 bool fin) {
73 SendQueuedFrames();
75 size_t total_bytes_consumed = 0;
76 bool fin_consumed = false;
78 while (delegate_->CanWrite(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA)) {
79 QuicFrame frame;
80 size_t bytes_consumed = packet_creator_->CreateStreamFrame(
81 id, data, offset + total_bytes_consumed, fin, &frame);
82 bool success = AddFrame(frame);
83 DCHECK(success);
85 total_bytes_consumed += bytes_consumed;
86 fin_consumed = fin && bytes_consumed == data.size();
87 data.remove_prefix(bytes_consumed);
88 DCHECK(data.empty() || packet_creator_->BytesFree() == 0u);
90 // TODO(ianswett): Restore packet reordering.
91 if (should_flush_ || !packet_creator_->HasRoomForStreamFrame()) {
92 SerializeAndSendPacket();
95 if (data.empty()) {
96 // We're done writing the data. Exit the loop.
97 // We don't make this a precondition because we could have 0 bytes of data
98 // if we're simply writing a fin.
99 break;
103 // Ensure the FEC group is closed at the end of this method unless other
104 // writes are pending.
105 if (should_flush_ && packet_creator_->ShouldSendFec(true)) {
106 SerializedPacket serialized_fec = packet_creator_->SerializeFec();
107 DCHECK(serialized_fec.packet);
108 delegate_->OnSerializedPacket(serialized_fec);
111 DCHECK(!should_flush_ || !packet_creator_->HasPendingFrames());
112 return QuicConsumedData(total_bytes_consumed, fin_consumed);
115 void QuicPacketGenerator::SendQueuedFrames() {
116 packet_creator_->MaybeStartFEC();
117 while (HasPendingFrames() && delegate_->CanWrite(NOT_RETRANSMISSION,
118 packet_creator_->HasPendingFrames() ?
119 HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA)) {
120 if (!AddNextPendingFrame()) {
121 // Packet was full, so serialize and send it.
122 SerializeAndSendPacket();
126 if (should_flush_) {
127 if (packet_creator_->HasPendingFrames()) {
128 SerializeAndSendPacket();
131 // Ensure the FEC group is closed at the end of this method unless other
132 // writes are pending.
133 if (packet_creator_->ShouldSendFec(true)) {
134 SerializedPacket serialized_fec = packet_creator_->SerializeFec();
135 DCHECK(serialized_fec.packet);
136 delegate_->OnSerializedPacket(serialized_fec);
137 packet_creator_->MaybeStartFEC();
142 void QuicPacketGenerator::StartBatchOperations() {
143 should_flush_ = false;
146 void QuicPacketGenerator::FinishBatchOperations() {
147 should_flush_ = true;
148 SendQueuedFrames();
151 bool QuicPacketGenerator::HasQueuedFrames() const {
152 return packet_creator_->HasPendingFrames() || HasPendingFrames();
155 bool QuicPacketGenerator::HasPendingFrames() const {
156 return should_send_ack_ || should_send_feedback_ ||
157 !queued_control_frames_.empty();
160 bool QuicPacketGenerator::AddNextPendingFrame() {
161 if (should_send_ack_) {
162 pending_ack_frame_.reset(delegate_->CreateAckFrame());
163 if (!AddFrame(QuicFrame(pending_ack_frame_.get()))) {
164 // packet was full
165 return false;
167 should_send_ack_ = false;
168 return true;
171 if (should_send_feedback_) {
172 pending_feedback_frame_.reset(delegate_->CreateFeedbackFrame());
173 if (!AddFrame(QuicFrame(pending_feedback_frame_.get()))) {
174 // packet was full
175 return false;
177 should_send_feedback_ = false;
178 return true;
181 DCHECK(!queued_control_frames_.empty());
182 if (!AddFrame(queued_control_frames_.back())) {
183 // packet was full
184 return false;
186 queued_control_frames_.pop_back();
187 return true;
190 bool QuicPacketGenerator::AddFrame(const QuicFrame& frame) {
191 bool success = packet_creator_->AddSavedFrame(frame);
192 if (success && debug_delegate_) {
193 debug_delegate_->OnFrameAddedToPacket(frame);
195 return success;
198 void QuicPacketGenerator::SerializeAndSendPacket() {
199 SerializedPacket serialized_packet = packet_creator_->SerializePacket();
200 DCHECK(serialized_packet.packet);
201 delegate_->OnSerializedPacket(serialized_packet);
203 if (packet_creator_->ShouldSendFec(false)) {
204 SerializedPacket serialized_fec = packet_creator_->SerializeFec();
205 DCHECK(serialized_fec.packet);
206 delegate_->OnSerializedPacket(serialized_fec);
207 packet_creator_->MaybeStartFEC();
211 } // namespace net