OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef NET_SPDY_SPDY_FRAME_BUILDER_H_ | 5 #ifndef NET_SPDY_SPDY_FRAME_BUILDER_H_ |
6 #define NET_SPDY_SPDY_FRAME_BUILDER_H_ | 6 #define NET_SPDY_SPDY_FRAME_BUILDER_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/memory/scoped_ptr.h" |
11 #include "base/string_piece.h" | 12 #include "base/string_piece.h" |
12 #include "base/sys_byteorder.h" | 13 #include "base/sys_byteorder.h" |
13 #include "net/base/net_export.h" | 14 #include "net/base/net_export.h" |
14 #include "net/spdy/spdy_protocol.h" | 15 #include "net/spdy/spdy_protocol.h" |
15 | 16 |
16 namespace net { | 17 namespace net { |
17 | 18 |
18 // This class provides facilities for basic binary value packing and unpacking | 19 // This class provides facilities for basic binary value packing |
19 // into Spdy frames. | 20 // into Spdy frames. |
20 // | 21 // |
21 // The SpdyFrameBuilder supports appending primitive values (int, string, etc) | 22 // The SpdyFrameBuilder supports appending primitive values (int, string, etc) |
22 // to a frame instance. The SpdyFrameBuilder grows its internal memory buffer | 23 // to a frame instance. The SpdyFrameBuilder grows its internal memory buffer |
23 // dynamically to hold the sequence of primitive values. The internal memory | 24 // dynamically to hold the sequence of primitive values. The internal memory |
24 // buffer is exposed as the "data" of the SpdyFrameBuilder. | 25 // buffer is exposed as the "data" of the SpdyFrameBuilder. |
25 class NET_EXPORT_PRIVATE SpdyFrameBuilder { | 26 class NET_EXPORT_PRIVATE SpdyFrameBuilder { |
26 public: | 27 public: |
27 ~SpdyFrameBuilder(); | |
28 | |
29 // Initializes a SpdyFrameBuilder with a buffer of given size | 28 // Initializes a SpdyFrameBuilder with a buffer of given size |
30 explicit SpdyFrameBuilder(size_t size); | 29 explicit SpdyFrameBuilder(size_t size); |
31 | 30 |
32 // Initializes a SpdyFrameBuilder with a buffer of given size, | 31 // Initializes a SpdyFrameBuilder with a buffer of given size, |
33 // populate with a SPDY control frame header based on | 32 // populate with a SPDY control frame header based on |
34 // |type|, |flags|, and |spdy_version|. | 33 // |type|, |flags|, and |spdy_version|. |
35 SpdyFrameBuilder(SpdyControlType type, SpdyControlFlags flags, | 34 SpdyFrameBuilder(SpdyControlType type, SpdyControlFlags flags, |
36 int spdy_version, size_t size); | 35 int spdy_version, size_t size); |
37 | 36 |
38 // Initiailizes a SpdyFrameBuilder with a buffer of given size, | 37 // Initiailizes a SpdyFrameBuilder with a buffer of given size, |
39 // populated with a SPDY data frame header based on | 38 // populated with a SPDY data frame header based on |
40 // |stream_id| and |flags|. | 39 // |stream_id| and |flags|. |
41 SpdyFrameBuilder(SpdyStreamId stream_id, SpdyDataFlags flags, size_t size); | 40 SpdyFrameBuilder(SpdyStreamId stream_id, SpdyDataFlags flags, size_t size); |
42 | 41 |
| 42 ~SpdyFrameBuilder(); |
| 43 |
43 // Returns the size of the SpdyFrameBuilder's data. | 44 // Returns the size of the SpdyFrameBuilder's data. |
44 size_t length() const { return length_; } | 45 size_t length() const { return length_; } |
45 | 46 |
46 // Takes the buffer from the SpdyFrameBuilder. | 47 // Takes the buffer from the SpdyFrameBuilder. |
47 SpdyFrame* take() { | 48 SpdyFrame* take() { |
48 SpdyFrame* rv = new SpdyFrame(buffer_, true); | 49 SpdyFrame* rv = new SpdyFrame(buffer_.release(), true); |
49 buffer_ = NULL; | |
50 capacity_ = 0; | 50 capacity_ = 0; |
51 length_ = 0; | 51 length_ = 0; |
52 return rv; | 52 return rv; |
53 } | 53 } |
54 | 54 |
55 // Methods for adding to the payload. These values are appended to the end | 55 // Methods for adding to the payload. These values are appended to the end |
56 // of the SpdyFrameBuilder payload. Note - binary integers are converted from | 56 // of the SpdyFrameBuilder payload. Note - binary integers are converted from |
57 // host to network form. | 57 // host to network form. |
58 bool WriteUInt8(uint8 value) { | 58 bool WriteUInt8(uint8 value) { |
59 return WriteBytes(&value, sizeof(value)); | 59 return WriteBytes(&value, sizeof(value)); |
(...skipping 14 matching lines...) Expand all Loading... |
74 // Write an integer to a particular offset in the data buffer. | 74 // Write an integer to a particular offset in the data buffer. |
75 bool WriteUInt32ToOffset(int offset, uint32 value) { | 75 bool WriteUInt32ToOffset(int offset, uint32 value) { |
76 value = htonl(value); | 76 value = htonl(value); |
77 return WriteBytesToOffset(offset, &value, sizeof(value)); | 77 return WriteBytesToOffset(offset, &value, sizeof(value)); |
78 } | 78 } |
79 | 79 |
80 // Write to a particular offset in the data buffer. | 80 // Write to a particular offset in the data buffer. |
81 bool WriteBytesToOffset(int offset, const void* data, uint32 data_len) { | 81 bool WriteBytesToOffset(int offset, const void* data, uint32 data_len) { |
82 if (offset + data_len > length_) | 82 if (offset + data_len > length_) |
83 return false; | 83 return false; |
84 char *ptr = buffer_ + offset; | 84 char *ptr = buffer_.get() + offset; |
85 memcpy(ptr, data, data_len); | 85 memcpy(ptr, data, data_len); |
86 return true; | 86 return true; |
87 } | 87 } |
88 | 88 |
89 // Returns true if the given iterator could point to data with the given | |
90 // length. If there is no room for the given data before the end of the | |
91 // payload, returns false. | |
92 bool IteratorHasRoomFor(const void* iter, int len) const { | |
93 const char* end_of_region = reinterpret_cast<const char*>(iter) + len; | |
94 if (len < 0 || | |
95 iter < buffer_ || | |
96 iter > end_of_payload() || | |
97 iter > end_of_region || | |
98 end_of_region > end_of_payload()) | |
99 return false; | |
100 | |
101 // Watch out for overflow in pointer calculation, which wraps. | |
102 return (iter <= end_of_region) && (end_of_region <= end_of_payload()); | |
103 } | |
104 | |
105 protected: | 89 protected: |
106 size_t capacity() const { | 90 const char* end_of_payload() const { return buffer_.get() + length_; } |
107 return capacity_; | |
108 } | |
109 | |
110 const char* end_of_payload() const { return buffer_ + length_; } | |
111 | 91 |
112 // Completes the write operation by padding the data with NULL bytes until it | 92 // Completes the write operation by padding the data with NULL bytes until it |
113 // is padded. Should be paired with BeginWrite, but it does not necessarily | 93 // is padded. Should be paired with BeginWrite, but it does not necessarily |
114 // have to be called after the data is written. | 94 // have to be called after the data is written. |
115 void EndWrite(char* dest, int length); | 95 void EndWrite(char* dest, int length); |
116 | 96 |
117 // Moves the iterator by the given number of bytes. | |
118 static void UpdateIter(void** iter, int bytes) { | |
119 *iter = static_cast<char*>(*iter) + bytes; | |
120 } | |
121 | |
122 private: | 97 private: |
123 // Returns the location that the data should be written at, or NULL if there | 98 // Returns the location that the data should be written at, or NULL if there |
124 // is not enough room. Call EndWrite with the returned offset and the given | 99 // is not enough room. Call EndWrite with the returned offset and the given |
125 // length to pad out for the next write. | 100 // length to pad out for the next write. |
126 char* BeginWrite(size_t length); | 101 char* BeginWrite(size_t length); |
127 | 102 |
128 char* buffer_; | 103 scoped_ptr<char[]> buffer_; |
129 size_t capacity_; // Allocation size of payload (or -1 if buffer is const). | 104 size_t capacity_; // Allocation size of payload (or -1 if buffer is const). |
130 size_t length_; // current length of the buffer | 105 size_t length_; // current length of the buffer |
131 }; | 106 }; |
132 | 107 |
133 } // namespace net | 108 } // namespace net |
134 | 109 |
135 #endif // NET_SPDY_SPDY_FRAME_BUILDER_H_ | 110 #endif // NET_SPDY_SPDY_FRAME_BUILDER_H_ |
OLD | NEW |