1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/spdy/hpack_output_stream.h"
6
7#include <cstddef>
8
9#include "base/basictypes.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12namespace net {
13
14namespace {
15
16using std::string;
17
18// Make sure that AppendBits() appends bits starting from the most
19// significant bit, and that it can handle crossing a byte boundary.
20TEST(HpackOutputStreamTest, AppendBits) {
21  HpackOutputStream output_stream;
22  string expected_str;
23
24  output_stream.AppendBits(0x1, 1);
25  expected_str.append(1, 0x00);
26  *expected_str.rbegin() |= (0x1 << 7);
27
28  output_stream.AppendBits(0x0, 1);
29
30  output_stream.AppendBits(0x3, 2);
31  *expected_str.rbegin() |= (0x3 << 4);
32
33  output_stream.AppendBits(0x0, 2);
34
35  // Byte-crossing append.
36  output_stream.AppendBits(0x7, 3);
37  *expected_str.rbegin() |= (0x7 >> 1);
38  expected_str.append(1, 0x00);
39  *expected_str.rbegin() |= (0x7 << 7);
40
41  output_stream.AppendBits(0x0, 7);
42
43  string str;
44  output_stream.TakeString(&str);
45  EXPECT_EQ(expected_str, str);
46}
47
48// Utility function to return I as a string encoded with an N-bit
49// prefix.
50string EncodeUint32(uint8 N, uint32 I) {
51  HpackOutputStream output_stream;
52  if (N < 8) {
53    output_stream.AppendBits(0x00, 8 - N);
54  }
55  output_stream.AppendUint32(I);
56  string str;
57  output_stream.TakeString(&str);
58  return str;
59}
60
61// The {Number}ByteIntegersEightBitPrefix tests below test that
62// certain integers are encoded correctly with an 8-bit prefix in
63// exactly {Number} bytes.
64
65TEST(HpackOutputStreamTest, OneByteIntegersEightBitPrefix) {
66  // Minimum.
67  EXPECT_EQ(string("\x00", 1), EncodeUint32(8, 0x00));
68  EXPECT_EQ("\x7f", EncodeUint32(8, 0x7f));
69  // Maximum.
70  EXPECT_EQ("\xfe", EncodeUint32(8, 0xfe));
71}
72
73TEST(HpackOutputStreamTest, TwoByteIntegersEightBitPrefix) {
74  // Minimum.
75  EXPECT_EQ(string("\xff\x00", 2), EncodeUint32(8, 0xff));
76  EXPECT_EQ("\xff\x01", EncodeUint32(8, 0x0100));
77  // Maximum.
78  EXPECT_EQ("\xff\x7f", EncodeUint32(8, 0x017e));
79}
80
81TEST(HpackOutputStreamTest, ThreeByteIntegersEightBitPrefix) {
82  // Minimum.
83  EXPECT_EQ("\xff\x80\x01", EncodeUint32(8, 0x017f));
84  EXPECT_EQ("\xff\x80\x1e", EncodeUint32(8, 0x0fff));
85  // Maximum.
86  EXPECT_EQ("\xff\xff\x7f", EncodeUint32(8, 0x40fe));
87}
88
89TEST(HpackOutputStreamTest, FourByteIntegersEightBitPrefix) {
90  // Minimum.
91  EXPECT_EQ("\xff\x80\x80\x01", EncodeUint32(8, 0x40ff));
92  EXPECT_EQ("\xff\x80\xfe\x03", EncodeUint32(8, 0xffff));
93  // Maximum.
94  EXPECT_EQ("\xff\xff\xff\x7f", EncodeUint32(8, 0x002000fe));
95}
96
97TEST(HpackOutputStreamTest, FiveByteIntegersEightBitPrefix) {
98  // Minimum.
99  EXPECT_EQ("\xff\x80\x80\x80\x01", EncodeUint32(8, 0x002000ff));
100  EXPECT_EQ("\xff\x80\xfe\xff\x07", EncodeUint32(8, 0x00ffffff));
101  // Maximum.
102  EXPECT_EQ("\xff\xff\xff\xff\x7f", EncodeUint32(8, 0x100000fe));
103}
104
105TEST(HpackOutputStreamTest, SixByteIntegersEightBitPrefix) {
106  // Minimum.
107  EXPECT_EQ("\xff\x80\x80\x80\x80\x01", EncodeUint32(8, 0x100000ff));
108  // Maximum.
109  EXPECT_EQ("\xff\x80\xfe\xff\xff\x0f", EncodeUint32(8, 0xffffffff));
110}
111
112// The {Number}ByteIntegersOneToSevenBitPrefix tests below test that
113// certain integers are encoded correctly with an N-bit prefix in
114// exactly {Number} bytes for N in {1, 2, ..., 7}.
115
116TEST(HpackOutputStreamTest, OneByteIntegersOneToSevenBitPrefixes) {
117  // Minimums.
118  EXPECT_EQ(string("\x00", 1), EncodeUint32(7, 0x00));
119  EXPECT_EQ(string("\x00", 1), EncodeUint32(6, 0x00));
120  EXPECT_EQ(string("\x00", 1), EncodeUint32(5, 0x00));
121  EXPECT_EQ(string("\x00", 1), EncodeUint32(4, 0x00));
122  EXPECT_EQ(string("\x00", 1), EncodeUint32(3, 0x00));
123  EXPECT_EQ(string("\x00", 1), EncodeUint32(2, 0x00));
124  EXPECT_EQ(string("\x00", 1), EncodeUint32(1, 0x00));
125
126  // Maximums.
127  EXPECT_EQ("\x7e", EncodeUint32(7, 0x7e));
128  EXPECT_EQ("\x3e", EncodeUint32(6, 0x3e));
129  EXPECT_EQ("\x1e", EncodeUint32(5, 0x1e));
130  EXPECT_EQ("\x0e", EncodeUint32(4, 0x0e));
131  EXPECT_EQ("\x06", EncodeUint32(3, 0x06));
132  EXPECT_EQ("\x02", EncodeUint32(2, 0x02));
133  EXPECT_EQ(string("\x00", 1), EncodeUint32(1, 0x00));
134}
135
136TEST(HpackOutputStreamTest, TwoByteIntegersOneToSevenBitPrefixes) {
137  // Minimums.
138  EXPECT_EQ(string("\x7f\x00", 2), EncodeUint32(7, 0x7f));
139  EXPECT_EQ(string("\x3f\x00", 2), EncodeUint32(6, 0x3f));
140  EXPECT_EQ(string("\x1f\x00", 2), EncodeUint32(5, 0x1f));
141  EXPECT_EQ(string("\x0f\x00", 2), EncodeUint32(4, 0x0f));
142  EXPECT_EQ(string("\x07\x00", 2), EncodeUint32(3, 0x07));
143  EXPECT_EQ(string("\x03\x00", 2), EncodeUint32(2, 0x03));
144  EXPECT_EQ(string("\x01\x00", 2), EncodeUint32(1, 0x01));
145
146  // Maximums.
147  EXPECT_EQ("\x7f\x7f", EncodeUint32(7, 0xfe));
148  EXPECT_EQ("\x3f\x7f", EncodeUint32(6, 0xbe));
149  EXPECT_EQ("\x1f\x7f", EncodeUint32(5, 0x9e));
150  EXPECT_EQ("\x0f\x7f", EncodeUint32(4, 0x8e));
151  EXPECT_EQ("\x07\x7f", EncodeUint32(3, 0x86));
152  EXPECT_EQ("\x03\x7f", EncodeUint32(2, 0x82));
153  EXPECT_EQ("\x01\x7f", EncodeUint32(1, 0x80));
154}
155
156TEST(HpackOutputStreamTest, ThreeByteIntegersOneToSevenBitPrefixes) {
157  // Minimums.
158  EXPECT_EQ("\x7f\x80\x01", EncodeUint32(7, 0xff));
159  EXPECT_EQ("\x3f\x80\x01", EncodeUint32(6, 0xbf));
160  EXPECT_EQ("\x1f\x80\x01", EncodeUint32(5, 0x9f));
161  EXPECT_EQ("\x0f\x80\x01", EncodeUint32(4, 0x8f));
162  EXPECT_EQ("\x07\x80\x01", EncodeUint32(3, 0x87));
163  EXPECT_EQ("\x03\x80\x01", EncodeUint32(2, 0x83));
164  EXPECT_EQ("\x01\x80\x01", EncodeUint32(1, 0x81));
165
166  // Maximums.
167  EXPECT_EQ("\x7f\xff\x7f", EncodeUint32(7, 0x407e));
168  EXPECT_EQ("\x3f\xff\x7f", EncodeUint32(6, 0x403e));
169  EXPECT_EQ("\x1f\xff\x7f", EncodeUint32(5, 0x401e));
170  EXPECT_EQ("\x0f\xff\x7f", EncodeUint32(4, 0x400e));
171  EXPECT_EQ("\x07\xff\x7f", EncodeUint32(3, 0x4006));
172  EXPECT_EQ("\x03\xff\x7f", EncodeUint32(2, 0x4002));
173  EXPECT_EQ("\x01\xff\x7f", EncodeUint32(1, 0x4000));
174}
175
176TEST(HpackOutputStreamTest, FourByteIntegersOneToSevenBitPrefixes) {
177  // Minimums.
178  EXPECT_EQ("\x7f\x80\x80\x01", EncodeUint32(7, 0x407f));
179  EXPECT_EQ("\x3f\x80\x80\x01", EncodeUint32(6, 0x403f));
180  EXPECT_EQ("\x1f\x80\x80\x01", EncodeUint32(5, 0x401f));
181  EXPECT_EQ("\x0f\x80\x80\x01", EncodeUint32(4, 0x400f));
182  EXPECT_EQ("\x07\x80\x80\x01", EncodeUint32(3, 0x4007));
183  EXPECT_EQ("\x03\x80\x80\x01", EncodeUint32(2, 0x4003));
184  EXPECT_EQ("\x01\x80\x80\x01", EncodeUint32(1, 0x4001));
185
186  // Maximums.
187  EXPECT_EQ("\x7f\xff\xff\x7f", EncodeUint32(7, 0x20007e));
188  EXPECT_EQ("\x3f\xff\xff\x7f", EncodeUint32(6, 0x20003e));
189  EXPECT_EQ("\x1f\xff\xff\x7f", EncodeUint32(5, 0x20001e));
190  EXPECT_EQ("\x0f\xff\xff\x7f", EncodeUint32(4, 0x20000e));
191  EXPECT_EQ("\x07\xff\xff\x7f", EncodeUint32(3, 0x200006));
192  EXPECT_EQ("\x03\xff\xff\x7f", EncodeUint32(2, 0x200002));
193  EXPECT_EQ("\x01\xff\xff\x7f", EncodeUint32(1, 0x200000));
194}
195
196TEST(HpackOutputStreamTest, FiveByteIntegersOneToSevenBitPrefixes) {
197  // Minimums.
198  EXPECT_EQ("\x7f\x80\x80\x80\x01", EncodeUint32(7, 0x20007f));
199  EXPECT_EQ("\x3f\x80\x80\x80\x01", EncodeUint32(6, 0x20003f));
200  EXPECT_EQ("\x1f\x80\x80\x80\x01", EncodeUint32(5, 0x20001f));
201  EXPECT_EQ("\x0f\x80\x80\x80\x01", EncodeUint32(4, 0x20000f));
202  EXPECT_EQ("\x07\x80\x80\x80\x01", EncodeUint32(3, 0x200007));
203  EXPECT_EQ("\x03\x80\x80\x80\x01", EncodeUint32(2, 0x200003));
204  EXPECT_EQ("\x01\x80\x80\x80\x01", EncodeUint32(1, 0x200001));
205
206  // Maximums.
207  EXPECT_EQ("\x7f\xff\xff\xff\x7f", EncodeUint32(7, 0x1000007e));
208  EXPECT_EQ("\x3f\xff\xff\xff\x7f", EncodeUint32(6, 0x1000003e));
209  EXPECT_EQ("\x1f\xff\xff\xff\x7f", EncodeUint32(5, 0x1000001e));
210  EXPECT_EQ("\x0f\xff\xff\xff\x7f", EncodeUint32(4, 0x1000000e));
211  EXPECT_EQ("\x07\xff\xff\xff\x7f", EncodeUint32(3, 0x10000006));
212  EXPECT_EQ("\x03\xff\xff\xff\x7f", EncodeUint32(2, 0x10000002));
213  EXPECT_EQ("\x01\xff\xff\xff\x7f", EncodeUint32(1, 0x10000000));
214}
215
216TEST(HpackOutputStreamTest, SixByteIntegersOneToSevenBitPrefixes) {
217  // Minimums.
218  EXPECT_EQ("\x7f\x80\x80\x80\x80\x01", EncodeUint32(7, 0x1000007f));
219  EXPECT_EQ("\x3f\x80\x80\x80\x80\x01", EncodeUint32(6, 0x1000003f));
220  EXPECT_EQ("\x1f\x80\x80\x80\x80\x01", EncodeUint32(5, 0x1000001f));
221  EXPECT_EQ("\x0f\x80\x80\x80\x80\x01", EncodeUint32(4, 0x1000000f));
222  EXPECT_EQ("\x07\x80\x80\x80\x80\x01", EncodeUint32(3, 0x10000007));
223  EXPECT_EQ("\x03\x80\x80\x80\x80\x01", EncodeUint32(2, 0x10000003));
224  EXPECT_EQ("\x01\x80\x80\x80\x80\x01", EncodeUint32(1, 0x10000001));
225
226  // Maximums.
227  EXPECT_EQ("\x7f\x80\xff\xff\xff\x0f", EncodeUint32(7, 0xffffffff));
228  EXPECT_EQ("\x3f\xc0\xff\xff\xff\x0f", EncodeUint32(6, 0xffffffff));
229  EXPECT_EQ("\x1f\xe0\xff\xff\xff\x0f", EncodeUint32(5, 0xffffffff));
230  EXPECT_EQ("\x0f\xf0\xff\xff\xff\x0f", EncodeUint32(4, 0xffffffff));
231  EXPECT_EQ("\x07\xf8\xff\xff\xff\x0f", EncodeUint32(3, 0xffffffff));
232  EXPECT_EQ("\x03\xfc\xff\xff\xff\x0f", EncodeUint32(2, 0xffffffff));
233  EXPECT_EQ("\x01\xfe\xff\xff\xff\x0f", EncodeUint32(1, 0xffffffff));
234}
235
236// Test that encoding an integer with an N-bit prefix preserves the
237// upper (8-N) bits of the first byte.
238TEST(HpackOutputStreamTest, AppendUint32PreservesUpperBits) {
239  HpackOutputStream output_stream;
240  output_stream.AppendBits(0x7f, 7);
241  output_stream.AppendUint32(0x01);
242  string str;
243  output_stream.TakeString(&str);
244  EXPECT_EQ(string("\xff\x00", 2), str);
245}
246
247TEST(HpackOutputStreamTest, AppendBytes) {
248  HpackOutputStream output_stream;
249
250  output_stream.AppendBytes("buffer1");
251  output_stream.AppendBytes("buffer2");
252
253  string str;
254  output_stream.TakeString(&str);
255  EXPECT_EQ("buffer1buffer2", str);
256}
257
258}  // namespace
259
260}  // namespace net
261