OLD | NEW |
1 // Copyright (c) 2011 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 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.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 spdy { | 17 namespace spdy { |
17 | 18 |
18 // This class provides facilities for basic binary value packing and unpacking | 19 // This class provides facilities for basic binary value packing and unpacking |
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 // | |
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 { | 26 class NET_EXPORT_PRIVATE SpdyFrameBuilder { |
30 public: | 27 public: |
31 ~SpdyFrameBuilder(); | 28 ~SpdyFrameBuilder(); |
32 | 29 |
33 SpdyFrameBuilder(); | 30 SpdyFrameBuilder(); |
34 | 31 |
35 // Initiailizes a SpdyFrameBuilder with a buffer of given size. | 32 // Initiailizes a SpdyFrameBuilder with a buffer of given size. |
36 // The buffer will still be resized as necessary. | 33 // The buffer will still be resized as necessary. |
37 explicit SpdyFrameBuilder(size_t size); | 34 explicit SpdyFrameBuilder(size_t size); |
38 | 35 |
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 | |
42 // this way. | |
43 SpdyFrameBuilder(const char* data, int data_len); | |
44 | |
45 // Returns the size of the SpdyFrameBuilder's data. | 36 // Returns the size of the SpdyFrameBuilder's data. |
46 int length() const { return length_; } | 37 int length() const { return length_; } |
47 | 38 |
48 // Takes the buffer from the SpdyFrameBuilder. | 39 // Takes the buffer from the SpdyFrameBuilder. |
49 SpdyFrame* take() { | 40 SpdyFrame* take() { |
50 SpdyFrame* rv = new SpdyFrame(buffer_, true); | 41 SpdyFrame* rv = new SpdyFrame(buffer_, true); |
51 buffer_ = NULL; | 42 buffer_ = NULL; |
52 capacity_ = 0; | 43 capacity_ = 0; |
53 length_ = 0; | 44 length_ = 0; |
54 return rv; | 45 return rv; |
55 } | 46 } |
56 | 47 |
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, | |
67 const char** data, | |
68 uint32* length) const; | |
69 | |
70 // Methods for adding to the payload. These values are appended to the end | 48 // 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 | 49 // of the SpdyFrameBuilder payload. Note - binary integers are converted from |
72 // in the order they were added. Note - binary integers are converted from | |
73 // host to network form. | 50 // host to network form. |
74 bool WriteUInt16(uint16 value) { | 51 bool WriteUInt16(uint16 value) { |
75 value = htons(value); | 52 value = htons(value); |
76 return WriteBytes(&value, sizeof(value)); | 53 return WriteBytes(&value, sizeof(value)); |
77 } | 54 } |
78 bool WriteUInt32(uint32 value) { | 55 bool WriteUInt32(uint32 value) { |
79 value = htonl(value); | 56 value = htonl(value); |
80 return WriteBytes(&value, sizeof(value)); | 57 return WriteBytes(&value, sizeof(value)); |
81 } | 58 } |
| 59 // TODO(hkhalil) Rename to WriteStringPiece16(). |
82 bool WriteString(const std::string& value); | 60 bool WriteString(const std::string& value); |
| 61 bool WriteStringPiece32(const base::StringPiece& value); |
83 bool WriteBytes(const void* data, uint32 data_len); | 62 bool WriteBytes(const void* data, uint32 data_len); |
84 | 63 |
85 // Write an integer to a particular offset in the data buffer. | 64 // Write an integer to a particular offset in the data buffer. |
86 bool WriteUInt32ToOffset(int offset, uint32 value) { | 65 bool WriteUInt32ToOffset(int offset, uint32 value) { |
87 value = htonl(value); | 66 value = htonl(value); |
88 return WriteBytesToOffset(offset, &value, sizeof(value)); | 67 return WriteBytesToOffset(offset, &value, sizeof(value)); |
89 } | 68 } |
90 | 69 |
91 // Write to a particular offset in the data buffer. | 70 // Write to a particular offset in the data buffer. |
92 bool WriteBytesToOffset(int offset, const void* data, uint32 data_len) { | 71 bool WriteBytesToOffset(int offset, const void* data, uint32 data_len) { |
93 if (offset + data_len > length_) | 72 if (offset + data_len > length_) |
94 return false; | 73 return false; |
95 char *ptr = buffer_ + offset; | 74 char *ptr = buffer_ + offset; |
96 memcpy(ptr, data, data_len); | 75 memcpy(ptr, data, data_len); |
97 return true; | 76 return true; |
98 } | 77 } |
99 | 78 |
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. | |
105 // | |
106 // The returned pointer will only be valid until the next write operation | |
107 // on this SpdyFrameBuilder. | |
108 char* BeginWriteData(uint16 length); | |
109 | |
110 // Returns true if the given iterator could point to data with the given | 79 // 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 | 80 // length. If there is no room for the given data before the end of the |
112 // payload, returns false. | 81 // payload, returns false. |
113 bool IteratorHasRoomFor(const void* iter, int len) const { | 82 bool IteratorHasRoomFor(const void* iter, int len) const { |
114 const char* end_of_region = reinterpret_cast<const char*>(iter) + len; | 83 const char* end_of_region = reinterpret_cast<const char*>(iter) + len; |
115 if (len < 0 || | 84 if (len < 0 || |
116 iter < buffer_ || | 85 iter < buffer_ || |
117 iter > end_of_payload() || | 86 iter > end_of_payload() || |
118 iter > end_of_region || | 87 iter > end_of_region || |
119 end_of_region > end_of_payload()) | 88 end_of_region > end_of_payload()) |
(...skipping 25 matching lines...) Expand all Loading... |
145 // the header: new_capacity = sizeof(Header) + desired_payload_capacity. | 114 // the header: new_capacity = sizeof(Header) + desired_payload_capacity. |
146 // A new failure will cause a Resize failure... and caller should check | 115 // A new failure will cause a Resize failure... and caller should check |
147 // the return result for true (i.e., successful resizing). | 116 // the return result for true (i.e., successful resizing). |
148 bool Resize(size_t new_capacity); | 117 bool Resize(size_t new_capacity); |
149 | 118 |
150 // Moves the iterator by the given number of bytes. | 119 // Moves the iterator by the given number of bytes. |
151 static void UpdateIter(void** iter, int bytes) { | 120 static void UpdateIter(void** iter, int bytes) { |
152 *iter = static_cast<char*>(*iter) + bytes; | 121 *iter = static_cast<char*>(*iter) + bytes; |
153 } | 122 } |
154 | 123 |
155 // Initial size of the payload. | |
156 static const int kInitialPayload = 1024; | |
157 | |
158 private: | 124 private: |
159 char* buffer_; | 125 char* buffer_; |
160 size_t capacity_; // Allocation size of payload (or -1 if buffer is const). | 126 size_t capacity_; // Allocation size of payload (or -1 if buffer is const). |
161 size_t length_; // current length of the buffer | 127 size_t length_; // current length of the buffer |
162 size_t variable_buffer_offset_; // IF non-zero, then offset to a buffer. | 128 size_t variable_buffer_offset_; // IF non-zero, then offset to a buffer. |
163 }; | 129 }; |
164 | 130 |
165 } // namespace spdy | 131 } // namespace spdy |
166 | 132 |
167 #endif // NET_SPDY_SPDY_FRAME_BUILDER_H_ | 133 #endif // NET_SPDY_SPDY_FRAME_BUILDER_H_ |
OLD | NEW |