| OLD | NEW |
| (Empty) |
| 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 | |
| 12 namespace net { | |
| 13 | |
| 14 namespace { | |
| 15 | |
| 16 using 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. | |
| 20 TEST(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. | |
| 50 string 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 | |
| 65 TEST(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 | |
| 73 TEST(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 | |
| 81 TEST(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 | |
| 89 TEST(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 | |
| 97 TEST(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 | |
| 105 TEST(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 | |
| 116 TEST(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 | |
| 136 TEST(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 | |
| 156 TEST(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 | |
| 176 TEST(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 | |
| 196 TEST(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 | |
| 216 TEST(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. | |
| 238 TEST(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 | |
| 247 TEST(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 | |
| OLD | NEW |