OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/quic/quic_data_writer.h" | |
6 | |
7 #include <stdint.h> | |
8 | |
9 #include <memory> | |
10 | |
11 #include "net/quic/quic_data_reader.h" | |
12 #include "net/test/gtest_util.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 | |
15 namespace net { | |
16 namespace test { | |
17 namespace { | |
18 | |
19 TEST(QuicDataWriterTest, SanityCheckUFloat16Consts) { | |
20 // Check the arithmetic on the constants - otherwise the values below make | |
21 // no sense. | |
22 EXPECT_EQ(30, kUFloat16MaxExponent); | |
23 EXPECT_EQ(11, kUFloat16MantissaBits); | |
24 EXPECT_EQ(12, kUFloat16MantissaEffectiveBits); | |
25 EXPECT_EQ(UINT64_C(0x3FFC0000000), kUFloat16MaxValue); | |
26 } | |
27 | |
28 TEST(QuicDataWriterTest, WriteUFloat16) { | |
29 struct TestCase { | |
30 uint64_t decoded; | |
31 uint16_t encoded; | |
32 }; | |
33 TestCase test_cases[] = { | |
34 // Small numbers represent themselves. | |
35 {0, 0}, | |
36 {1, 1}, | |
37 {2, 2}, | |
38 {3, 3}, | |
39 {4, 4}, | |
40 {5, 5}, | |
41 {6, 6}, | |
42 {7, 7}, | |
43 {15, 15}, | |
44 {31, 31}, | |
45 {42, 42}, | |
46 {123, 123}, | |
47 {1234, 1234}, | |
48 // Check transition through 2^11. | |
49 {2046, 2046}, | |
50 {2047, 2047}, | |
51 {2048, 2048}, | |
52 {2049, 2049}, | |
53 // Running out of mantissa at 2^12. | |
54 {4094, 4094}, | |
55 {4095, 4095}, | |
56 {4096, 4096}, | |
57 {4097, 4096}, | |
58 {4098, 4097}, | |
59 {4099, 4097}, | |
60 {4100, 4098}, | |
61 {4101, 4098}, | |
62 // Check transition through 2^13. | |
63 {8190, 6143}, | |
64 {8191, 6143}, | |
65 {8192, 6144}, | |
66 {8193, 6144}, | |
67 {8194, 6144}, | |
68 {8195, 6144}, | |
69 {8196, 6145}, | |
70 {8197, 6145}, | |
71 // Half-way through the exponents. | |
72 {0x7FF8000, 0x87FF}, | |
73 {0x7FFFFFF, 0x87FF}, | |
74 {0x8000000, 0x8800}, | |
75 {0xFFF0000, 0x8FFF}, | |
76 {0xFFFFFFF, 0x8FFF}, | |
77 {0x10000000, 0x9000}, | |
78 // Transition into the largest exponent. | |
79 {0x1FFFFFFFFFE, 0xF7FF}, | |
80 {0x1FFFFFFFFFF, 0xF7FF}, | |
81 {0x20000000000, 0xF800}, | |
82 {0x20000000001, 0xF800}, | |
83 {0x2003FFFFFFE, 0xF800}, | |
84 {0x2003FFFFFFF, 0xF800}, | |
85 {0x20040000000, 0xF801}, | |
86 {0x20040000001, 0xF801}, | |
87 // Transition into the max value and clamping. | |
88 {0x3FF80000000, 0xFFFE}, | |
89 {0x3FFBFFFFFFF, 0xFFFE}, | |
90 {0x3FFC0000000, 0xFFFF}, | |
91 {0x3FFC0000001, 0xFFFF}, | |
92 {0x3FFFFFFFFFF, 0xFFFF}, | |
93 {0x40000000000, 0xFFFF}, | |
94 {0xFFFFFFFFFFFFFFFF, 0xFFFF}, | |
95 }; | |
96 int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]); | |
97 | |
98 for (int i = 0; i < num_test_cases; ++i) { | |
99 char buffer[2]; | |
100 QuicDataWriter writer(2, buffer); | |
101 EXPECT_TRUE(writer.WriteUFloat16(test_cases[i].decoded)); | |
102 EXPECT_EQ(test_cases[i].encoded, | |
103 *reinterpret_cast<uint16_t*>(writer.data())); | |
104 } | |
105 } | |
106 | |
107 TEST(QuicDataWriterTest, ReadUFloat16) { | |
108 struct TestCase { | |
109 uint64_t decoded; | |
110 uint16_t encoded; | |
111 }; | |
112 TestCase test_cases[] = { | |
113 // There are fewer decoding test cases because encoding truncates, and | |
114 // decoding returns the smallest expansion. | |
115 // Small numbers represent themselves. | |
116 {0, 0}, | |
117 {1, 1}, | |
118 {2, 2}, | |
119 {3, 3}, | |
120 {4, 4}, | |
121 {5, 5}, | |
122 {6, 6}, | |
123 {7, 7}, | |
124 {15, 15}, | |
125 {31, 31}, | |
126 {42, 42}, | |
127 {123, 123}, | |
128 {1234, 1234}, | |
129 // Check transition through 2^11. | |
130 {2046, 2046}, | |
131 {2047, 2047}, | |
132 {2048, 2048}, | |
133 {2049, 2049}, | |
134 // Running out of mantissa at 2^12. | |
135 {4094, 4094}, | |
136 {4095, 4095}, | |
137 {4096, 4096}, | |
138 {4098, 4097}, | |
139 {4100, 4098}, | |
140 // Check transition through 2^13. | |
141 {8190, 6143}, | |
142 {8192, 6144}, | |
143 {8196, 6145}, | |
144 // Half-way through the exponents. | |
145 {0x7FF8000, 0x87FF}, | |
146 {0x8000000, 0x8800}, | |
147 {0xFFF0000, 0x8FFF}, | |
148 {0x10000000, 0x9000}, | |
149 // Transition into the largest exponent. | |
150 {0x1FFE0000000, 0xF7FF}, | |
151 {0x20000000000, 0xF800}, | |
152 {0x20040000000, 0xF801}, | |
153 // Transition into the max value. | |
154 {0x3FF80000000, 0xFFFE}, | |
155 {0x3FFC0000000, 0xFFFF}, | |
156 }; | |
157 int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]); | |
158 | |
159 for (int i = 0; i < num_test_cases; ++i) { | |
160 QuicDataReader reader(reinterpret_cast<char*>(&test_cases[i].encoded), 2); | |
161 uint64_t value; | |
162 EXPECT_TRUE(reader.ReadUFloat16(&value)); | |
163 EXPECT_EQ(test_cases[i].decoded, value); | |
164 } | |
165 } | |
166 | |
167 TEST(QuicDataWriterTest, RoundTripUFloat16) { | |
168 // Just test all 16-bit encoded values. 0 and max already tested above. | |
169 uint64_t previous_value = 0; | |
170 for (uint16_t i = 1; i < 0xFFFF; ++i) { | |
171 // Read the two bytes. | |
172 QuicDataReader reader(reinterpret_cast<char*>(&i), 2); | |
173 uint64_t value; | |
174 // All values must be decodable. | |
175 EXPECT_TRUE(reader.ReadUFloat16(&value)); | |
176 // Check that small numbers represent themselves | |
177 if (i < 4097) | |
178 EXPECT_EQ(i, value); | |
179 // Check there's monotonic growth. | |
180 EXPECT_LT(previous_value, value); | |
181 // Check that precision is within 0.5% away from the denormals. | |
182 if (i > 2000) | |
183 EXPECT_GT(previous_value * 1005, value * 1000); | |
184 // Check we're always within the promised range. | |
185 EXPECT_LT(value, UINT64_C(0x3FFC0000000)); | |
186 previous_value = value; | |
187 char buffer[6]; | |
188 QuicDataWriter writer(6, buffer); | |
189 EXPECT_TRUE(writer.WriteUFloat16(value - 1)); | |
190 EXPECT_TRUE(writer.WriteUFloat16(value)); | |
191 EXPECT_TRUE(writer.WriteUFloat16(value + 1)); | |
192 // Check minimal decoding (previous decoding has previous encoding). | |
193 EXPECT_EQ(i - 1, *reinterpret_cast<uint16_t*>(writer.data())); | |
194 // Check roundtrip. | |
195 EXPECT_EQ(i, *reinterpret_cast<uint16_t*>(writer.data() + 2)); | |
196 // Check next decoding. | |
197 EXPECT_EQ(i < 4096 ? i + 1 : i, | |
198 *reinterpret_cast<uint16_t*>(writer.data() + 4)); | |
199 } | |
200 } | |
201 | |
202 } // namespace | |
203 } // namespace test | |
204 } // namespace net | |
OLD | NEW |