1 // Copyright (c) 2013 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/spdy/spdy_buffer.h"
9 #include "base/callback.h"
10 #include "base/logging.h"
11 #include "base/profiler/scoped_tracker.h"
12 #include "net/base/io_buffer.h"
13 #include "net/spdy/spdy_protocol.h"
19 // Bound on largest frame any SPDY version has allowed.
20 const size_t kMaxSpdyFrameSize
= 0x00ffffff;
22 // Makes a SpdyFrame with |size| bytes of data copied from
23 // |data|. |data| must be non-NULL and |size| must be positive.
24 scoped_ptr
<SpdyFrame
> MakeSpdyFrame(const char* data
, size_t size
) {
27 CHECK_LE(size
, kMaxSpdyFrameSize
);
28 scoped_ptr
<char[]> frame_data(new char[size
]);
29 std::memcpy(frame_data
.get(), data
, size
);
30 scoped_ptr
<SpdyFrame
> frame(
31 new SpdyFrame(frame_data
.release(), size
, true /* owns_buffer */));
37 // This class is an IOBuffer implementation that simply holds a
38 // reference to a SharedFrame object and a fixed offset. Used by
39 // SpdyBuffer::GetIOBufferForRemainingData().
40 class SpdyBuffer::SharedFrameIOBuffer
: public IOBuffer
{
42 SharedFrameIOBuffer(const scoped_refptr
<SharedFrame
>& shared_frame
,
44 : IOBuffer(shared_frame
->data
->data() + offset
),
45 shared_frame_(shared_frame
) {}
48 ~SharedFrameIOBuffer() override
{
49 // Prevent ~IOBuffer() from trying to delete |data_|.
53 const scoped_refptr
<SharedFrame
> shared_frame_
;
55 DISALLOW_COPY_AND_ASSIGN(SharedFrameIOBuffer
);
58 SpdyBuffer::SpdyBuffer(scoped_ptr
<SpdyFrame
> frame
)
59 : shared_frame_(new SharedFrame()),
61 shared_frame_
->data
= frame
.Pass();
64 // The given data may not be strictly a SPDY frame; we (ab)use
65 // |frame_| just as a container.
66 SpdyBuffer::SpdyBuffer(const char* data
, size_t size
) :
67 shared_frame_(new SharedFrame()),
70 CHECK_LE(size
, kMaxSpdyFrameSize
);
71 shared_frame_
->data
= MakeSpdyFrame(data
, size
);
74 SpdyBuffer::~SpdyBuffer() {
75 if (GetRemainingSize() > 0)
76 ConsumeHelper(GetRemainingSize(), DISCARD
);
79 const char* SpdyBuffer::GetRemainingData() const {
80 return shared_frame_
->data
->data() + offset_
;
83 size_t SpdyBuffer::GetRemainingSize() const {
84 return shared_frame_
->data
->size() - offset_
;
87 void SpdyBuffer::AddConsumeCallback(const ConsumeCallback
& consume_callback
) {
88 consume_callbacks_
.push_back(consume_callback
);
91 void SpdyBuffer::Consume(size_t consume_size
) {
92 // TODO(pkasting): Remove ScopedTracker below once crbug.com/457517 is fixed.
93 tracked_objects::ScopedTracker
tracking_profile(
94 FROM_HERE_WITH_EXPLICIT_FUNCTION("457517 SpdyBuffer::Consume"));
95 ConsumeHelper(consume_size
, CONSUME
);
98 IOBuffer
* SpdyBuffer::GetIOBufferForRemainingData() {
99 return new SharedFrameIOBuffer(shared_frame_
, offset_
);
102 void SpdyBuffer::ConsumeHelper(size_t consume_size
,
103 ConsumeSource consume_source
) {
104 DCHECK_GE(consume_size
, 1u);
105 DCHECK_LE(consume_size
, GetRemainingSize());
106 offset_
+= consume_size
;
107 for (std::vector
<ConsumeCallback
>::const_iterator it
=
108 consume_callbacks_
.begin(); it
!= consume_callbacks_
.end(); ++it
) {
109 it
->Run(consume_size
, consume_source
);