Index: trunk/src/net/spdy/spdy_http_stream.cc |
=================================================================== |
--- trunk/src/net/spdy/spdy_http_stream.cc (revision 194561) |
+++ trunk/src/net/spdy/spdy_http_stream.cc (working copy) |
@@ -135,11 +135,28 @@ |
CHECK(!callback.is_null()); |
// If we have data buffered, complete the IO immediately. |
- if (!response_body_queue_.IsEmpty()) { |
- size_t bytes_consumed = response_body_queue_.Dequeue(buf->data(), buf_len); |
+ if (!response_body_.empty()) { |
+ int bytes_read = 0; |
+ while (!response_body_.empty() && buf_len > 0) { |
+ scoped_refptr<IOBufferWithSize> data = response_body_.front(); |
+ const int bytes_to_copy = std::min(buf_len, data->size()); |
+ memcpy(&(buf->data()[bytes_read]), data->data(), bytes_to_copy); |
+ buf_len -= bytes_to_copy; |
+ if (bytes_to_copy == data->size()) { |
+ response_body_.pop_front(); |
+ } else { |
+ const int bytes_remaining = data->size() - bytes_to_copy; |
+ IOBufferWithSize* new_buffer = new IOBufferWithSize(bytes_remaining); |
+ memcpy(new_buffer->data(), &(data->data()[bytes_to_copy]), |
+ bytes_remaining); |
+ response_body_.pop_front(); |
+ response_body_.push_front(make_scoped_refptr(new_buffer)); |
+ } |
+ bytes_read += bytes_to_copy; |
+ } |
if (stream_) |
- stream_->IncreaseRecvWindowSize(bytes_consumed); |
- return bytes_consumed; |
+ stream_->IncreaseRecvWindowSize(bytes_read); |
+ return bytes_read; |
} else if (stream_closed_) { |
return closed_stream_status_; |
} |
@@ -417,7 +434,7 @@ |
NOTREACHED(); |
} |
-int SpdyHttpStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { |
+int SpdyHttpStream::OnDataReceived(const char* data, int length) { |
// SpdyStream won't call us with data if the header block didn't contain a |
// valid set of headers. So we don't expect to not have headers received |
// here. |
@@ -429,8 +446,11 @@ |
// happen for server initiated streams. |
DCHECK(stream_.get()); |
DCHECK(!stream_->closed() || stream_->pushed()); |
- if (buffer) { |
- response_body_queue_.Enqueue(buffer.Pass()); |
+ if (length > 0) { |
+ // Save the received data. |
+ IOBufferWithSize* io_buffer = new IOBufferWithSize(length); |
+ memcpy(io_buffer->data(), data, length); |
+ response_body_.push_back(make_scoped_refptr(io_buffer)); |
if (user_buffer_) { |
// Handing small chunks of data to the caller creates measurable overhead. |
@@ -489,9 +509,14 @@ |
if (stream_closed_) |
return false; |
- DCHECK_GT(user_buffer_len_, 0); |
- return response_body_queue_.GetTotalSize() < |
- static_cast<size_t>(user_buffer_len_); |
+ int bytes_buffered = 0; |
+ std::list<scoped_refptr<IOBufferWithSize> >::const_iterator it; |
+ for (it = response_body_.begin(); |
+ it != response_body_.end() && bytes_buffered < user_buffer_len_; |
+ ++it) |
+ bytes_buffered += (*it)->size(); |
+ |
+ return bytes_buffered < user_buffer_len_; |
} |
bool SpdyHttpStream::DoBufferedReadCallback() { |