1 // Copyright (c) 2011 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_
11 #include "base/basictypes.h"
12 #include "base/sys_byteorder.h"
13 #include "net/base/net_export.h"
14 #include "net/spdy/spdy_protocol.h"
18 // This class provides facilities for basic binary value packing and unpacking
21 // The SpdyFrameBuilder supports appending primitive values (int, string, etc)
22 // to a frame instance. The SpdyFrameBuilder grows its internal memory buffer
23 // dynamically to hold the sequence of primitive values. The internal memory
24 // buffer is exposed as the "data" of the SpdyFrameBuilder.
26 // When reading from a SpdyFrameBuilder the consumer must know what value types
27 // to read and in what order to read them as the SpdyFrameBuilder does not keep
28 // track of the type of data written to it.
29 class NET_EXPORT_PRIVATE SpdyFrameBuilder
{
35 // Initiailizes a SpdyFrameBuilder with a buffer of given size.
36 // The buffer will still be resized as necessary.
37 explicit SpdyFrameBuilder(size_t size
);
39 // Initializes a SpdyFrameBuilder from a const block of data. The data is
40 // not copied; instead the data is merely referenced by this
41 // SpdyFrameBuilder. Only const methods should be used when initialized
43 SpdyFrameBuilder(const char* data
, int data_len
);
45 // Returns the size of the SpdyFrameBuilder's data.
46 int length() const { return length_
; }
48 // Takes the buffer from the SpdyFrameBuilder.
50 SpdyFrame
* rv
= new SpdyFrame(buffer_
, true);
57 // Methods for reading the payload of the SpdyFrameBuilder. To read from the
58 // start of the SpdyFrameBuilder, initialize *iter to NULL. If successful,
59 // these methods return true. Otherwise, false is returned to indicate that
60 // the result could not be extracted.
61 bool ReadUInt16(void** iter
, uint16
* result
) const;
62 bool ReadUInt32(void** iter
, uint32
* result
) const;
63 bool ReadString(void** iter
, std::string
* result
) const;
64 bool ReadBytes(void** iter
, const char** data
, uint32 length
) const;
65 bool ReadData(void** iter
, const char** data
, uint16
* length
) const;
66 bool ReadReadLen32PrefixedData(void** iter
,
68 uint32
* length
) const;
70 // Methods for adding to the payload. These values are appended to the end
71 // of the SpdyFrameBuilder payload. When reading values, you must read them
72 // in the order they were added. Note - binary integers are converted from
73 // host to network form.
74 bool WriteUInt16(uint16 value
) {
76 return WriteBytes(&value
, sizeof(value
));
78 bool WriteUInt32(uint32 value
) {
80 return WriteBytes(&value
, sizeof(value
));
82 bool WriteString(const std::string
& value
);
83 bool WriteBytes(const void* data
, uint32 data_len
);
85 // Write an integer to a particular offset in the data buffer.
86 bool WriteUInt32ToOffset(int offset
, uint32 value
) {
88 return WriteBytesToOffset(offset
, &value
, sizeof(value
));
91 // Write to a particular offset in the data buffer.
92 bool WriteBytesToOffset(int offset
, const void* data
, uint32 data_len
) {
93 if (offset
+ data_len
> length_
)
95 char *ptr
= buffer_
+ offset
;
96 memcpy(ptr
, data
, data_len
);
100 // Allows the caller to write data directly into the SpdyFrameBuilder.
101 // This saves a copy when the data is not already available in a buffer.
102 // The caller must not write more than the length it declares it will.
103 // Use ReadData to get the data.
104 // Returns NULL on failure.
106 // The returned pointer will only be valid until the next write operation
107 // on this SpdyFrameBuilder.
108 char* BeginWriteData(uint16 length
);
110 // Returns true if the given iterator could point to data with the given
111 // length. If there is no room for the given data before the end of the
112 // payload, returns false.
113 bool IteratorHasRoomFor(const void* iter
, int len
) const {
114 const char* end_of_region
= reinterpret_cast<const char*>(iter
) + len
;
117 iter
> end_of_payload() ||
118 iter
> end_of_region
||
119 end_of_region
> end_of_payload())
122 // Watch out for overflow in pointer calculation, which wraps.
123 return (iter
<= end_of_region
) && (end_of_region
<= end_of_payload());
127 size_t capacity() const {
131 const char* end_of_payload() const { return buffer_
+ length_
; }
133 // Resizes the buffer for use when writing the specified amount of data. The
134 // location that the data should be written at is returned, or NULL if there
135 // was an error. Call EndWrite with the returned offset and the given length
136 // to pad out for the next write.
137 char* BeginWrite(size_t length
);
139 // Completes the write operation by padding the data with NULL bytes until it
140 // is padded. Should be paired with BeginWrite, but it does not necessarily
141 // have to be called after the data is written.
142 void EndWrite(char* dest
, int length
);
144 // Resize the capacity, note that the input value should include the size of
145 // the header: new_capacity = sizeof(Header) + desired_payload_capacity.
146 // A new failure will cause a Resize failure... and caller should check
147 // the return result for true (i.e., successful resizing).
148 bool Resize(size_t new_capacity
);
150 // Moves the iterator by the given number of bytes.
151 static void UpdateIter(void** iter
, int bytes
) {
152 *iter
= static_cast<char*>(*iter
) + bytes
;
155 // Initial size of the payload.
156 static const int kInitialPayload
= 1024;
160 size_t capacity_
; // Allocation size of payload (or -1 if buffer is const).
161 size_t length_
; // current length of the buffer
162 size_t variable_buffer_offset_
; // IF non-zero, then offset to a buffer.
167 #endif // NET_SPDY_SPDY_FRAME_BUILDER_H_