| 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 |