| Index: net/spdy/spdy_frame_builder.cc
|
| diff --git a/net/spdy/spdy_frame_builder.cc b/net/spdy/spdy_frame_builder.cc
|
| index ee9d36c9f73d5c56cf59dbec073824b659d4e397..1f82dd9d97f2500586d5cdc861e8544644fb936c 100644
|
| --- a/net/spdy/spdy_frame_builder.cc
|
| +++ b/net/spdy/spdy_frame_builder.cc
|
| @@ -80,11 +80,42 @@ bool SpdyFrameBuilder::BeginNewFrame(const SpdyFramer& framer,
|
| offset_ += length_;
|
| length_ = 0;
|
|
|
| + // TODO(yasong): remove after OverwriteLength() is deleted.
|
| + bool length_written = false;
|
| + // Remember where the length field is written. Used for OverwriteLength().
|
| + if (output_ != nullptr && CanWrite(kLengthFieldLength)) {
|
| + // Can write the length field.
|
| + char* dest = nullptr;
|
| + // |size| is the available bytes in the current memory block.
|
| + int size = 0;
|
| + output_->Next(&dest, &size);
|
| + start_of_current_frame_ = dest;
|
| + bytes_of_length_written_in_first_block_ =
|
| + size > (int)kLengthFieldLength ? kLengthFieldLength : size;
|
| + // If the current block is not enough for the length field, write the
|
| + // length field here, and remember the pointer to the next block.
|
| + if (size < (int)kLengthFieldLength) {
|
| + // Write the first portion of the length field.
|
| + int value = base::HostToNet32(capacity_ - offset_ - kFrameHeaderSize);
|
| + memcpy(dest, reinterpret_cast<char*>(&value) + 1, size);
|
| + Seek(size);
|
| + output_->Next(&dest, &size);
|
| + start_of_current_frame_in_next_block_ = dest;
|
| + int size_left =
|
| + kLengthFieldLength - bytes_of_length_written_in_first_block_;
|
| + memcpy(dest, reinterpret_cast<char*>(&value) + 1 + size, size_left);
|
| + Seek(size_left);
|
| + length_written = true;
|
| + }
|
| + }
|
| +
|
| // Assume all remaining capacity will be used for this frame. If not,
|
| // the length will get overwritten when we begin the next frame.
|
| // Don't check for length limits here because this may be larger than the
|
| // actual frame length.
|
| - success &= WriteUInt24(capacity_ - offset_ - kFrameHeaderSize);
|
| + if (!length_written) {
|
| + success &= WriteUInt24(capacity_ - offset_ - kFrameHeaderSize);
|
| + }
|
| success &= WriteUInt8(type);
|
| success &= WriteUInt8(flags);
|
| success &= WriteUInt32(stream_id);
|
| @@ -169,6 +200,30 @@ bool SpdyFrameBuilder::WriteBytes(const void* data, uint32_t data_len) {
|
|
|
| bool SpdyFrameBuilder::OverwriteLength(const SpdyFramer& framer,
|
| size_t length) {
|
| + if (output_ != nullptr) {
|
| + size_t value = base::HostToNet32(length);
|
| + if (start_of_current_frame_ != nullptr &&
|
| + bytes_of_length_written_in_first_block_ == kLengthFieldLength) {
|
| + // Length field of the current frame is within one memory block.
|
| + memcpy(start_of_current_frame_, reinterpret_cast<char*>(&value) + 1,
|
| + kLengthFieldLength);
|
| + return true;
|
| + } else if (start_of_current_frame_ != nullptr &&
|
| + start_of_current_frame_in_next_block_ != nullptr &&
|
| + bytes_of_length_written_in_first_block_ < kLengthFieldLength) {
|
| + // Length field of the current frame crosses two memory blocks.
|
| + memcpy(start_of_current_frame_, reinterpret_cast<char*>(&value) + 1,
|
| + bytes_of_length_written_in_first_block_);
|
| + memcpy(start_of_current_frame_in_next_block_,
|
| + reinterpret_cast<char*>(&value) + 1 +
|
| + bytes_of_length_written_in_first_block_,
|
| + kLengthFieldLength - bytes_of_length_written_in_first_block_);
|
| + return true;
|
| + } else {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| DCHECK_GE(framer.GetFrameMaximumSize(), length);
|
| bool success = false;
|
| const size_t old_length = length_;
|
|
|