blob: c5467e98af1c4866dc8b18442b4bc99283dabb01 [file] [log] [blame]
[email protected]39c48fc2012-03-12 18:42:121// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]aea80602009-09-18 00:55:082// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]1407b6e2010-08-27 21:39:485#ifndef NET_SPDY_SPDY_FRAME_BUILDER_H_
6#define NET_SPDY_SPDY_FRAME_BUILDER_H_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
[email protected]aea80602009-09-18 00:55:088
[email protected]aea80602009-09-18 00:55:089#include <string>
10
[email protected]1407b6e2010-08-27 21:39:4811#include "base/basictypes.h"
[email protected]39c48fc2012-03-12 18:42:1212#include "base/string_piece.h"
[email protected]0e6f6192011-12-28 23:18:2113#include "base/sys_byteorder.h"
[email protected]172da1b2011-08-12 15:52:2614#include "net/base/net_export.h"
[email protected]dab9c7d2010-02-06 21:44:3215#include "net/spdy/spdy_protocol.h"
[email protected]aea80602009-09-18 00:55:0816
[email protected]ff98d7f02012-03-22 21:44:1917namespace net {
[email protected]aea80602009-09-18 00:55:0818
19// This class provides facilities for basic binary value packing and unpacking
[email protected]955fc2e72010-02-08 20:37:3020// into Spdy frames.
[email protected]aea80602009-09-18 00:55:0821//
[email protected]955fc2e72010-02-08 20:37:3022// The SpdyFrameBuilder supports appending primitive values (int, string, etc)
23// to a frame instance. The SpdyFrameBuilder grows its internal memory buffer
[email protected]aea80602009-09-18 00:55:0824// dynamically to hold the sequence of primitive values. The internal memory
[email protected]955fc2e72010-02-08 20:37:3025// buffer is exposed as the "data" of the SpdyFrameBuilder.
[email protected]172da1b2011-08-12 15:52:2626class NET_EXPORT_PRIVATE SpdyFrameBuilder {
[email protected]aea80602009-09-18 00:55:0827 public:
[email protected]fb2323d72011-11-29 03:13:0328 ~SpdyFrameBuilder();
29
[email protected]690993242012-04-16 18:06:1130 // Initializes a SpdyFrameBuilder with a buffer of given size,
[email protected]a053b442012-04-18 00:28:4131 // populate with a SPDY control frame header based on
32 // |type|, |flags|, and |spdy_version|.
[email protected]690993242012-04-16 18:06:1133 SpdyFrameBuilder(SpdyControlType type, SpdyControlFlags flags,
34 int spdy_version, size_t size);
[email protected]aea80602009-09-18 00:55:0835
[email protected]690993242012-04-16 18:06:1136 // Initiailizes a SpdyFrameBuilder with a buffer of given size,
37 // populated with a SPDY data frame header based on
38 // |stream_id| and |flags|.
39 SpdyFrameBuilder(SpdyStreamId stream_id, SpdyDataFlags flags, size_t size);
[email protected]8ac2a022011-11-04 00:01:5740
[email protected]955fc2e72010-02-08 20:37:3041 // Returns the size of the SpdyFrameBuilder's data.
[email protected]bbfc65e2012-04-21 01:32:4042 size_t length() const { return length_; }
[email protected]aea80602009-09-18 00:55:0843
[email protected]955fc2e72010-02-08 20:37:3044 // Takes the buffer from the SpdyFrameBuilder.
45 SpdyFrame* take() {
46 SpdyFrame* rv = new SpdyFrame(buffer_, true);
[email protected]aea80602009-09-18 00:55:0847 buffer_ = NULL;
48 capacity_ = 0;
49 length_ = 0;
50 return rv;
51 }
52
[email protected]aea80602009-09-18 00:55:0853 // Methods for adding to the payload. These values are appended to the end
[email protected]39c48fc2012-03-12 18:42:1254 // of the SpdyFrameBuilder payload. Note - binary integers are converted from
[email protected]aea80602009-09-18 00:55:0855 // host to network form.
[email protected]ca33c882012-03-23 01:39:3056 bool WriteUInt8(uint8 value) {
57 return WriteBytes(&value, sizeof(value));
58 }
[email protected]aea80602009-09-18 00:55:0859 bool WriteUInt16(uint16 value) {
60 value = htons(value);
61 return WriteBytes(&value, sizeof(value));
62 }
63 bool WriteUInt32(uint32 value) {
64 value = htonl(value);
65 return WriteBytes(&value, sizeof(value));
66 }
[email protected]39c48fc2012-03-12 18:42:1267 // TODO(hkhalil) Rename to WriteStringPiece16().
[email protected]aea80602009-09-18 00:55:0868 bool WriteString(const std::string& value);
[email protected]39c48fc2012-03-12 18:42:1269 bool WriteStringPiece32(const base::StringPiece& value);
[email protected]fb2323d72011-11-29 03:13:0370 bool WriteBytes(const void* data, uint32 data_len);
[email protected]aea80602009-09-18 00:55:0871
72 // Write an integer to a particular offset in the data buffer.
73 bool WriteUInt32ToOffset(int offset, uint32 value) {
[email protected]aea80602009-09-18 00:55:0874 value = htonl(value);
[email protected]289b93d72009-10-20 15:32:3275 return WriteBytesToOffset(offset, &value, sizeof(value));
76 }
77
78 // Write to a particular offset in the data buffer.
79 bool WriteBytesToOffset(int offset, const void* data, uint32 data_len) {
80 if (offset + data_len > length_)
81 return false;
[email protected]aea80602009-09-18 00:55:0882 char *ptr = buffer_ + offset;
[email protected]289b93d72009-10-20 15:32:3283 memcpy(ptr, data, data_len);
[email protected]aea80602009-09-18 00:55:0884 return true;
85 }
86
[email protected]aea80602009-09-18 00:55:0887 // Returns true if the given iterator could point to data with the given
88 // length. If there is no room for the given data before the end of the
89 // payload, returns false.
90 bool IteratorHasRoomFor(const void* iter, int len) const {
91 const char* end_of_region = reinterpret_cast<const char*>(iter) + len;
[email protected]d8c21a52009-10-07 01:55:2192 if (len < 0 ||
93 iter < buffer_ ||
94 iter > end_of_payload() ||
95 iter > end_of_region ||
96 end_of_region > end_of_payload())
[email protected]aea80602009-09-18 00:55:0897 return false;
[email protected]aea80602009-09-18 00:55:0898
99 // Watch out for overflow in pointer calculation, which wraps.
100 return (iter <= end_of_region) && (end_of_region <= end_of_payload());
101 }
102
103 protected:
104 size_t capacity() const {
105 return capacity_;
106 }
107
108 const char* end_of_payload() const { return buffer_ + length_; }
109
[email protected]aea80602009-09-18 00:55:08110 // Completes the write operation by padding the data with NULL bytes until it
111 // is padded. Should be paired with BeginWrite, but it does not necessarily
112 // have to be called after the data is written.
113 void EndWrite(char* dest, int length);
114
[email protected]aea80602009-09-18 00:55:08115 // Moves the iterator by the given number of bytes.
116 static void UpdateIter(void** iter, int bytes) {
117 *iter = static_cast<char*>(*iter) + bytes;
118 }
119
[email protected]aea80602009-09-18 00:55:08120 private:
[email protected]5e8bf9c2012-04-13 00:47:53121 // Returns the location that the data should be written at, or NULL if there
122 // is not enough room. Call EndWrite with the returned offset and the given
123 // length to pad out for the next write.
124 char* BeginWrite(size_t length);
125
[email protected]aea80602009-09-18 00:55:08126 char* buffer_;
127 size_t capacity_; // Allocation size of payload (or -1 if buffer is const).
128 size_t length_; // current length of the buffer
[email protected]aea80602009-09-18 00:55:08129};
130
[email protected]ff98d7f02012-03-22 21:44:19131} // namespace net
[email protected]aea80602009-09-18 00:55:08132
[email protected]1407b6e2010-08-27 21:39:48133#endif // NET_SPDY_SPDY_FRAME_BUILDER_H_