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/spdy/spdy_frame_builder.h" | 5 #include "net/spdy/spdy_frame_builder.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstdint> | 8 #include <cstdint> |
9 #include <limits> | 9 #include <limits> |
10 | 10 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 // Update length field for previous frame. | 73 // Update length field for previous frame. |
74 OverwriteLength(framer, length_ - kFrameHeaderSize); | 74 OverwriteLength(framer, length_ - kFrameHeaderSize); |
75 SPDY_BUG_IF(framer.GetFrameMaximumSize() < length_) | 75 SPDY_BUG_IF(framer.GetFrameMaximumSize() < length_) |
76 << "Frame length " << length_ | 76 << "Frame length " << length_ |
77 << " is longer than the maximum allowed length."; | 77 << " is longer than the maximum allowed length."; |
78 } | 78 } |
79 | 79 |
80 offset_ += length_; | 80 offset_ += length_; |
81 length_ = 0; | 81 length_ = 0; |
82 | 82 |
| 83 // TODO(yasong): remove after OverwriteLength() is deleted. |
| 84 bool length_written = false; |
| 85 // Remember where the length field is written. Used for OverwriteLength(). |
| 86 if (output_ != nullptr && CanWrite(kLengthFieldLength)) { |
| 87 // Can write the length field. |
| 88 char* dest = nullptr; |
| 89 // |size| is the available bytes in the current memory block. |
| 90 int size = 0; |
| 91 output_->Next(&dest, &size); |
| 92 start_of_current_frame_ = dest; |
| 93 bytes_of_length_written_in_first_block_ = |
| 94 size > (int)kLengthFieldLength ? kLengthFieldLength : size; |
| 95 // If the current block is not enough for the length field, write the |
| 96 // length field here, and remember the pointer to the next block. |
| 97 if (size < (int)kLengthFieldLength) { |
| 98 // Write the first portion of the length field. |
| 99 int value = base::HostToNet32(capacity_ - offset_ - kFrameHeaderSize); |
| 100 memcpy(dest, reinterpret_cast<char*>(&value) + 1, size); |
| 101 Seek(size); |
| 102 output_->Next(&dest, &size); |
| 103 start_of_current_frame_in_next_block_ = dest; |
| 104 int size_left = |
| 105 kLengthFieldLength - bytes_of_length_written_in_first_block_; |
| 106 memcpy(dest, reinterpret_cast<char*>(&value) + 1 + size, size_left); |
| 107 Seek(size_left); |
| 108 length_written = true; |
| 109 } |
| 110 } |
| 111 |
83 // Assume all remaining capacity will be used for this frame. If not, | 112 // Assume all remaining capacity will be used for this frame. If not, |
84 // the length will get overwritten when we begin the next frame. | 113 // the length will get overwritten when we begin the next frame. |
85 // Don't check for length limits here because this may be larger than the | 114 // Don't check for length limits here because this may be larger than the |
86 // actual frame length. | 115 // actual frame length. |
87 success &= WriteUInt24(capacity_ - offset_ - kFrameHeaderSize); | 116 if (!length_written) { |
| 117 success &= WriteUInt24(capacity_ - offset_ - kFrameHeaderSize); |
| 118 } |
88 success &= WriteUInt8(type); | 119 success &= WriteUInt8(type); |
89 success &= WriteUInt8(flags); | 120 success &= WriteUInt8(flags); |
90 success &= WriteUInt32(stream_id); | 121 success &= WriteUInt32(stream_id); |
91 DCHECK_EQ(framer.GetDataFrameMinimumSize(), length_); | 122 DCHECK_EQ(framer.GetDataFrameMinimumSize(), length_); |
92 return success; | 123 return success; |
93 } | 124 } |
94 | 125 |
95 bool SpdyFrameBuilder::BeginNewFrame(const SpdyFramer& framer, | 126 bool SpdyFrameBuilder::BeginNewFrame(const SpdyFramer& framer, |
96 SpdyFrameType type, | 127 SpdyFrameType type, |
97 uint8_t flags, | 128 uint8_t flags, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 Seek(to_copy); | 193 Seek(to_copy); |
163 data_len -= to_copy; | 194 data_len -= to_copy; |
164 total_written += to_copy; | 195 total_written += to_copy; |
165 } | 196 } |
166 } | 197 } |
167 return true; | 198 return true; |
168 } | 199 } |
169 | 200 |
170 bool SpdyFrameBuilder::OverwriteLength(const SpdyFramer& framer, | 201 bool SpdyFrameBuilder::OverwriteLength(const SpdyFramer& framer, |
171 size_t length) { | 202 size_t length) { |
| 203 if (output_ != nullptr) { |
| 204 size_t value = base::HostToNet32(length); |
| 205 if (start_of_current_frame_ != nullptr && |
| 206 bytes_of_length_written_in_first_block_ == kLengthFieldLength) { |
| 207 // Length field of the current frame is within one memory block. |
| 208 memcpy(start_of_current_frame_, reinterpret_cast<char*>(&value) + 1, |
| 209 kLengthFieldLength); |
| 210 return true; |
| 211 } else if (start_of_current_frame_ != nullptr && |
| 212 start_of_current_frame_in_next_block_ != nullptr && |
| 213 bytes_of_length_written_in_first_block_ < kLengthFieldLength) { |
| 214 // Length field of the current frame crosses two memory blocks. |
| 215 memcpy(start_of_current_frame_, reinterpret_cast<char*>(&value) + 1, |
| 216 bytes_of_length_written_in_first_block_); |
| 217 memcpy(start_of_current_frame_in_next_block_, |
| 218 reinterpret_cast<char*>(&value) + 1 + |
| 219 bytes_of_length_written_in_first_block_, |
| 220 kLengthFieldLength - bytes_of_length_written_in_first_block_); |
| 221 return true; |
| 222 } else { |
| 223 return false; |
| 224 } |
| 225 } |
| 226 |
172 DCHECK_GE(framer.GetFrameMaximumSize(), length); | 227 DCHECK_GE(framer.GetFrameMaximumSize(), length); |
173 bool success = false; | 228 bool success = false; |
174 const size_t old_length = length_; | 229 const size_t old_length = length_; |
175 | 230 |
176 length_ = 0; | 231 length_ = 0; |
177 success = WriteUInt24(length); | 232 success = WriteUInt24(length); |
178 | 233 |
179 length_ = old_length; | 234 length_ = old_length; |
180 return success; | 235 return success; |
181 } | 236 } |
(...skipping 13 matching lines...) Expand all Loading... |
195 } else { | 250 } else { |
196 if (length > output_->BytesFree()) { | 251 if (length > output_->BytesFree()) { |
197 return false; | 252 return false; |
198 } | 253 } |
199 } | 254 } |
200 | 255 |
201 return true; | 256 return true; |
202 } | 257 } |
203 | 258 |
204 } // namespace net | 259 } // namespace net |
OLD | NEW |