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. 4 5 #ifndef NET_SPDY_SPDY_FRAME_BUILDER_H_ 6 #define NET_SPDY_SPDY_FRAME_BUILDER_H_ 7 8 #include <string> 9 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" 16 17 namespace net { 18 19 class SpdyFramer; 20 21 // This class provides facilities for basic binary value packing 22 // into Spdy frames. 23 // 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 { 29 public: 30 // Initializes a SpdyFrameBuilder with a buffer of given size 31 explicit SpdyFrameBuilder(size_t size); 32 33 ~SpdyFrameBuilder(); 34 35 // Returns the size of the SpdyFrameBuilder's data. 36 size_t length() const { return length_; } 37 38 // Returns a writeable buffer of given size in bytes, to be appended to the 39 // currently written frame. Does bounds checking on length but does not 40 // increment the underlying iterator. To do so, consumers should subsequently 41 // call Seek(). 42 // In general, consumers should use Write*() calls instead of this. 43 // Returns NULL on failure. 44 char* GetWritableBuffer(size_t length); 45 46 // Seeks forward by the given number of bytes. Useful in conjunction with 47 // GetWriteableBuffer() above. 48 bool Seek(size_t length); 49 50 // Populates this frame with a SPDY control frame header using 51 // version-specific information from the |framer| and length information from 52 // capacity_. The given type must be a control frame type. 53 // Used only for SPDY versions <4. 54 bool WriteControlFrameHeader(const SpdyFramer& framer, 55 SpdyFrameType type, 56 uint8 flags); 57 58 // Populates this frame with a SPDY data frame header using version-specific 59 // information from the |framer| and length information from capacity_. 60 bool WriteDataFrameHeader(const SpdyFramer& framer, 61 SpdyStreamId stream_id, 62 SpdyDataFlags flags); 63 64 // Populates this frame with a SPDY4/HTTP2 frame prefix using 65 // version-specific information from the |framer| and length information from 66 // capacity_. The given type must be a control frame type. 67 // Used only for SPDY versions >=4. 68 bool WriteFramePrefix(const SpdyFramer& framer, 69 SpdyFrameType type, 70 uint8 flags, 71 SpdyStreamId stream_id); 72 73 // Takes the buffer from the SpdyFrameBuilder. 74 SpdyFrame* take() { 75 SpdyFrame* rv = new SpdyFrame(buffer_.release(), length_, true); 76 capacity_ = 0; 77 length_ = 0; 78 return rv; 79 } 80 81 // Methods for adding to the payload. These values are appended to the end 82 // of the SpdyFrameBuilder payload. Note - binary integers are converted from 83 // host to network form. 84 bool WriteUInt8(uint8 value) { 85 return WriteBytes(&value, sizeof(value)); 86 } 87 bool WriteUInt16(uint16 value) { 88 value = htons(value); 89 return WriteBytes(&value, sizeof(value)); 90 } 91 bool WriteUInt32(uint32 value) { 92 value = htonl(value); 93 return WriteBytes(&value, sizeof(value)); 94 } 95 // TODO(hkhalil) Rename to WriteStringPiece16(). 96 bool WriteString(const std::string& value); 97 bool WriteStringPiece32(const base::StringPiece& value); 98 bool WriteBytes(const void* data, uint32 data_len); 99 100 // Update (in-place) the length field in the frame being built to reflect the 101 // current actual length of bytes written to said frame through this builder. 102 // The framer parameter is used to determine version-specific location and 103 // size information of the length field to be written, and must be initialized 104 // with the correct version for the frame being written. 105 bool RewriteLength(const SpdyFramer& framer); 106 107 // Update (in-place) the length field in the frame being built to reflect the 108 // given length. 109 // The framer parameter is used to determine version-specific location and 110 // size information of the length field to be written, and must be initialized 111 // with the correct version for the frame being written. 112 bool OverwriteLength(const SpdyFramer& framer, size_t length); 113 114 private: 115 // Checks to make sure that there is an appropriate amount of space for a 116 // write of given size, in bytes. 117 bool CanWrite(size_t length) const; 118 119 scoped_ptr<char[]> buffer_; 120 size_t capacity_; // Allocation size of payload, set by constructor. 121 size_t length_; // Current length of the buffer. 122 }; 123 124 } // namespace net 125 126 #endif // NET_SPDY_SPDY_FRAME_BUILDER_H_ 127