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.
5 #ifndef NET_SPDY_SPDY_FRAME_BUILDER_H_
6 #define NET_SPDY_SPDY_FRAME_BUILDER_H_
10 #include "base/basictypes.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/strings/string_piece.h"
13 #include "base/sys_byteorder.h"
14 #include "net/base/net_export.h"
15 #include "net/spdy/spdy_protocol.h"
21 // This class provides facilities for basic binary value packing
24 // The SpdyFrameBuilder supports appending primitive values (int, string, etc)
25 // to a frame instance. The SpdyFrameBuilder grows its internal memory buffer
26 // dynamically to hold the sequence of primitive values. The internal memory
27 // buffer is exposed as the "data" of the SpdyFrameBuilder.
28 class NET_EXPORT_PRIVATE SpdyFrameBuilder
{
30 // Initializes a SpdyFrameBuilder with a buffer of given size
31 SpdyFrameBuilder(size_t size
, SpdyMajorVersion version
);
35 // Returns the total size of the SpdyFrameBuilder's data, which may include
37 size_t length() const { return offset_
+ length_
; }
39 // Returns a writeable buffer of given size in bytes, to be appended to the
40 // currently written frame. Does bounds checking on length but does not
41 // increment the underlying iterator. To do so, consumers should subsequently
43 // In general, consumers should use Write*() calls instead of this.
44 // Returns NULL on failure.
45 char* GetWritableBuffer(size_t length
);
47 // Seeks forward by the given number of bytes. Useful in conjunction with
48 // GetWriteableBuffer() above.
49 bool Seek(size_t length
);
51 // Populates this frame with a SPDY control frame header using
52 // version-specific information from the |framer| and length information from
53 // capacity_. The given type must be a control frame type.
54 // Used only for SPDY versions <4.
55 bool WriteControlFrameHeader(const SpdyFramer
& framer
,
59 // Populates this frame with a SPDY data frame header using version-specific
60 // information from the |framer| and length information from capacity_.
61 bool WriteDataFrameHeader(const SpdyFramer
& framer
,
62 SpdyStreamId stream_id
,
65 // Populates this frame with a SPDY4/HTTP2 frame prefix using
66 // version-specific information from the |framer| and length information from
67 // capacity_. The given type must be a control frame type.
68 // Used only for SPDY versions >=4.
69 bool BeginNewFrame(const SpdyFramer
& framer
,
72 SpdyStreamId stream_id
);
74 // Takes the buffer from the SpdyFrameBuilder.
76 if (version_
> SPDY3
) {
77 DLOG_IF(DFATAL
, SpdyConstants::GetFrameMaximumSize(version_
) < length_
)
78 << "Frame length " << length_
79 << " is longer than the maximum allowed length.";
81 SpdyFrame
* rv
= new SpdyFrame(buffer_
.release(), length(), true);
88 // Methods for adding to the payload. These values are appended to the end
89 // of the SpdyFrameBuilder payload. Note - binary integers are converted from
90 // host to network form.
91 bool WriteUInt8(uint8 value
) {
92 return WriteBytes(&value
, sizeof(value
));
94 bool WriteUInt16(uint16 value
) {
96 return WriteBytes(&value
, sizeof(value
));
98 bool WriteUInt24(uint32 value
) {
100 return WriteBytes(reinterpret_cast<char*>(&value
) + 1,
103 bool WriteUInt32(uint32 value
) {
104 value
= htonl(value
);
105 return WriteBytes(&value
, sizeof(value
));
107 bool WriteUInt64(uint64 value
) {
108 uint32 upper
= htonl(value
>> 32);
109 uint32 lower
= htonl(static_cast<uint32
>(value
));
110 return (WriteBytes(&upper
, sizeof(upper
)) &&
111 WriteBytes(&lower
, sizeof(lower
)));
113 // TODO(hkhalil) Rename to WriteStringPiece16().
114 bool WriteString(const std::string
& value
);
115 bool WriteStringPiece32(const base::StringPiece
& value
);
116 bool WriteBytes(const void* data
, uint32 data_len
);
118 // Update (in-place) the length field in the frame being built to reflect the
119 // current actual length of bytes written to said frame through this builder.
120 // The framer parameter is used to determine version-specific location and
121 // size information of the length field to be written, and must be initialized
122 // with the correct version for the frame being written.
123 bool RewriteLength(const SpdyFramer
& framer
);
125 // Update (in-place) the length field in the frame being built to reflect the
127 // The framer parameter is used to determine version-specific location and
128 // size information of the length field to be written, and must be initialized
129 // with the correct version for the frame being written.
130 bool OverwriteLength(const SpdyFramer
& framer
, size_t length
);
132 // Update (in-place) the flags field in the frame being built to reflect the
133 // given flags value.
134 // Used only for SPDY versions >=4.
135 bool OverwriteFlags(const SpdyFramer
& framer
, uint8 flags
);
138 // Checks to make sure that there is an appropriate amount of space for a
139 // write of given size, in bytes.
140 bool CanWrite(size_t length
) const;
142 scoped_ptr
<char[]> buffer_
;
143 size_t capacity_
; // Allocation size of payload, set by constructor.
144 size_t length_
; // Length of the latest frame in the buffer.
145 size_t offset_
; // Position at which the latest frame begins.
147 const SpdyMajorVersion version_
;
152 #endif // NET_SPDY_SPDY_FRAME_BUILDER_H_