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
3 // found in the LICENSE file.
7 #include "net/spdy/spdy_frame_builder.h"
8 #include "net/spdy/spdy_protocol.h"
14 // Creates a FlagsAndLength.
15 FlagsAndLength
CreateFlagsAndLength(SpdyControlFlags flags
, size_t length
) {
16 DCHECK_EQ(0u, length
& ~static_cast<size_t>(kLengthMask
));
17 FlagsAndLength flags_length
;
18 flags_length
.length_
= htonl(static_cast<uint32
>(length
));
19 DCHECK_EQ(0, flags
& ~kControlFlagsMask
);
20 flags_length
.flags_
[0] = flags
;
26 SpdyFrameBuilder::SpdyFrameBuilder(SpdyControlType type
,
27 SpdyControlFlags flags
,
30 : buffer_(new char[size
]),
33 FlagsAndLength flags_length
= CreateFlagsAndLength(
34 flags
, size
- SpdyFrame::kHeaderSize
);
35 WriteUInt16(kControlFlagMask
| spdy_version
);
37 WriteBytes(&flags_length
, sizeof(flags_length
));
40 SpdyFrameBuilder::SpdyFrameBuilder(SpdyStreamId stream_id
,
43 : buffer_(new char[size
]),
46 DCHECK_EQ(0u, stream_id
& ~kStreamIdMask
);
47 WriteUInt32(stream_id
);
48 size_t length
= size
- SpdyFrame::kHeaderSize
;
49 DCHECK_EQ(0u, length
& ~static_cast<size_t>(kLengthMask
));
50 FlagsAndLength flags_length
;
51 flags_length
.length_
= htonl(length
);
52 DCHECK_EQ(0, flags
& ~kDataFlagsMask
);
53 flags_length
.flags_
[0] = flags
;
54 WriteBytes(&flags_length
, sizeof(flags_length
));
57 SpdyFrameBuilder::~SpdyFrameBuilder() {
61 char* SpdyFrameBuilder::BeginWrite(size_t length
) {
62 size_t offset
= length_
;
63 size_t needed_size
= length_
+ length
;
64 if (needed_size
> capacity_
)
67 #ifdef ARCH_CPU_64_BITS
68 DCHECK_LE(length
, std::numeric_limits
<uint32
>::max());
71 return buffer_
+ offset
;
74 void SpdyFrameBuilder::EndWrite(char* dest
, int length
) {
77 bool SpdyFrameBuilder::WriteBytes(const void* data
, uint32 data_len
) {
78 if (data_len
> kLengthMask
) {
82 char* dest
= BeginWrite(data_len
);
86 memcpy(dest
, data
, data_len
);
88 EndWrite(dest
, data_len
);
93 bool SpdyFrameBuilder::WriteString(const std::string
& value
) {
94 if (value
.size() > 0xffff)
97 if (!WriteUInt16(static_cast<int>(value
.size())))
100 return WriteBytes(value
.data(), static_cast<uint16
>(value
.size()));
103 bool SpdyFrameBuilder::WriteStringPiece32(const base::StringPiece
& value
) {
104 if (!WriteUInt32(value
.size())) {
108 return WriteBytes(value
.data(), value
.size());