| 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 |