blob: 31d0211d7ae4a510eba99582d7c9351df5c2dc58 [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]955fc2e72010-02-08 20:37:3030 SpdyFrameBuilder();
[email protected]aea80602009-09-18 00:55:0831
[email protected]8ac2a022011-11-04 00:01:5732 // Initiailizes a SpdyFrameBuilder with a buffer of given size.
[email protected]8ac2a022011-11-04 00:01:5733 explicit SpdyFrameBuilder(size_t size);
34
[email protected]955fc2e72010-02-08 20:37:3035 // Returns the size of the SpdyFrameBuilder's data.
[email protected]aea80602009-09-18 00:55:0836 int length() const { return length_; }
37
[email protected]955fc2e72010-02-08 20:37:3038 // Takes the buffer from the SpdyFrameBuilder.
39 SpdyFrame* take() {
40 SpdyFrame* rv = new SpdyFrame(buffer_, true);
[email protected]aea80602009-09-18 00:55:0841 buffer_ = NULL;
42 capacity_ = 0;
43 length_ = 0;
44 return rv;
45 }
46
[email protected]aea80602009-09-18 00:55:0847 // Methods for adding to the payload. These values are appended to the end
[email protected]39c48fc2012-03-12 18:42:1248 // of the SpdyFrameBuilder payload. Note - binary integers are converted from
[email protected]aea80602009-09-18 00:55:0849 // host to network form.
[email protected]ca33c882012-03-23 01:39:3050 bool WriteUInt8(uint8 value) {
51 return WriteBytes(&value, sizeof(value));
52 }
[email protected]aea80602009-09-18 00:55:0853 bool WriteUInt16(uint16 value) {
54 value = htons(value);
55 return WriteBytes(&value, sizeof(value));
56 }
57 bool WriteUInt32(uint32 value) {
58 value = htonl(value);
59 return WriteBytes(&value, sizeof(value));
60 }
[email protected]39c48fc2012-03-12 18:42:1261 // TODO(hkhalil) Rename to WriteStringPiece16().
[email protected]aea80602009-09-18 00:55:0862 bool WriteString(const std::string& value);
[email protected]39c48fc2012-03-12 18:42:1263 bool WriteStringPiece32(const base::StringPiece& value);
[email protected]fb2323d72011-11-29 03:13:0364 bool WriteBytes(const void* data, uint32 data_len);
[email protected]aea80602009-09-18 00:55:0865
66 // Write an integer to a particular offset in the data buffer.
67 bool WriteUInt32ToOffset(int offset, uint32 value) {
[email protected]aea80602009-09-18 00:55:0868 value = htonl(value);
[email protected]289b93d72009-10-20 15:32:3269 return WriteBytesToOffset(offset, &value, sizeof(value));
70 }
71
72 // Write to a particular offset in the data buffer.
73 bool WriteBytesToOffset(int offset, const void* data, uint32 data_len) {
74 if (offset + data_len > length_)
75 return false;
[email protected]aea80602009-09-18 00:55:0876 char *ptr = buffer_ + offset;
[email protected]289b93d72009-10-20 15:32:3277 memcpy(ptr, data, data_len);
[email protected]aea80602009-09-18 00:55:0878 return true;
79 }
80
[email protected]aea80602009-09-18 00:55:0881 // Returns true if the given iterator could point to data with the given
82 // length. If there is no room for the given data before the end of the
83 // payload, returns false.
84 bool IteratorHasRoomFor(const void* iter, int len) const {
85 const char* end_of_region = reinterpret_cast<const char*>(iter) + len;
[email protected]d8c21a52009-10-07 01:55:2186 if (len < 0 ||
87 iter < buffer_ ||
88 iter > end_of_payload() ||
89 iter > end_of_region ||
90 end_of_region > end_of_payload())
[email protected]aea80602009-09-18 00:55:0891 return false;
[email protected]aea80602009-09-18 00:55:0892
93 // Watch out for overflow in pointer calculation, which wraps.
94 return (iter <= end_of_region) && (end_of_region <= end_of_payload());
95 }
96
97 protected:
98 size_t capacity() const {
99 return capacity_;
100 }
101
102 const char* end_of_payload() const { return buffer_ + length_; }
103
[email protected]aea80602009-09-18 00:55:08104 // Completes the write operation by padding the data with NULL bytes until it
105 // is padded. Should be paired with BeginWrite, but it does not necessarily
106 // have to be called after the data is written.
107 void EndWrite(char* dest, int length);
108
[email protected]aea80602009-09-18 00:55:08109 // Moves the iterator by the given number of bytes.
110 static void UpdateIter(void** iter, int bytes) {
111 *iter = static_cast<char*>(*iter) + bytes;
112 }
113
[email protected]aea80602009-09-18 00:55:08114 private:
[email protected]5e8bf9c2012-04-13 00:47:53115 // Returns the location that the data should be written at, or NULL if there
116 // is not enough room. Call EndWrite with the returned offset and the given
117 // length to pad out for the next write.
118 char* BeginWrite(size_t length);
119
[email protected]aea80602009-09-18 00:55:08120 char* buffer_;
121 size_t capacity_; // Allocation size of payload (or -1 if buffer is const).
122 size_t length_; // current length of the buffer
[email protected]aea80602009-09-18 00:55:08123};
124
[email protected]ff98d7f02012-03-22 21:44:19125} // namespace net
[email protected]aea80602009-09-18 00:55:08126
[email protected]1407b6e2010-08-27 21:39:48127#endif // NET_SPDY_SPDY_FRAME_BUILDER_H_