OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include <limits> | 11 #include <limits> |
12 | 12 |
13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
14 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 14 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
15 | 15 |
16 namespace webrtc { | 16 namespace webrtc { |
17 namespace { | 17 namespace { |
18 | 18 |
19 class ByteIoTest : public ::testing::Test { | 19 class ByteIoTest : public ::testing::Test { |
20 protected: | 20 protected: |
21 ByteIoTest() {} | 21 ByteIoTest() {} |
22 virtual ~ByteIoTest() {} | 22 virtual ~ByteIoTest() {} |
23 | 23 |
24 enum { kAlignments = sizeof(uint64_t) - 1 }; | 24 enum { kAlignments = sizeof(uint64_t) - 1 }; |
25 | 25 |
26 // Method to create a test value that is not the same when byte reversed. | 26 // Method to create a test value that is not the same when byte reversed. |
27 template <typename T> | 27 template <typename T> |
28 T CreateTestValue(bool negative, uint8_t num_bytes) { | 28 T CreateTestValue(bool negative, uint8_t num_bytes) { |
29 // Examples of output: | |
30 // T = int32_t, negative = false, num_bytes = 4: 0x00010203 | |
31 // T = int32_t, negative = true, num_bytes = 4: 0xFFFEFDFC | |
32 // T = int32_t, negative = false, num_bytes = 3: 0x000102 | |
33 // * T = int32_t, negative = true, num_bytes = 3: 0xFFFEFD | |
34 | |
29 T val = 0; | 35 T val = 0; |
30 for (uint8_t i = 0; i != num_bytes; ++i) { | 36 for (uint8_t i = 0; i != num_bytes; ++i) { |
31 val = (val << 8) + (negative ? (0xFF - i) : (i + 1)); | 37 val = (val << 8) + (negative ? (0xFF - i) : (i + 1)); |
32 } | 38 } |
33 if (negative && std::numeric_limits<T>::is_signed) { | 39 |
34 val |= static_cast<T>(-1) << (8 * num_bytes); | 40 // This loop will create a sign extend mask if num_bytes if necessary. |
41 // For the last example (marked * above), we the number needs to be sign | |
stefan-webrtc
2016/02/26 10:11:19
"the number needs to..."
sprang_webrtc
2016/02/26 10:22:28
Done.
| |
42 // extended to be a valid int32_t. The sign extend mask is 0xFF000000. | |
43 // Comments for each step with this example below. | |
44 if (std::numeric_limits<T>::is_signed && negative && | |
45 num_bytes < sizeof(T)) { | |
46 // Start with mask = 0xFFFFFFFF. | |
47 T mask = static_cast<T>(-1); | |
48 // Create a temporary for the lowest byte (0x000000FF). | |
49 const T neg_byte = static_cast<T>(0xFF); | |
50 for (int i = 0; i < num_bytes; ++i) { | |
51 // And the inverse of the temporary and the mask: | |
52 // 0xFFFFFFFF & 0xFFFFFF00 = 0xFFFFFF00. | |
53 // 0xFFFFFF00 & 0xFFFF00FF = 0xFFFF0000. | |
54 // 0xFFFF0000 & 0xFF00FFFF = 0xFF000000. | |
55 mask &= ~(neg_byte << (i * 8)); | |
56 } | |
57 // Add the sign extension mask to the actual value. | |
58 val |= mask; | |
35 } | 59 } |
36 return val; | 60 return val; |
37 } | 61 } |
38 | 62 |
39 // Populate byte buffer with value, in big endian format. | 63 // Populate byte buffer with value, in big endian format. |
40 template <typename T> | 64 template <typename T> |
41 void PopulateTestData(uint8_t* data, T value, int num_bytes, bool bigendian) { | 65 void PopulateTestData(uint8_t* data, T value, int num_bytes, bool bigendian) { |
42 if (bigendian) { | 66 if (bigendian) { |
43 for (int i = 0; i < num_bytes; ++i) { | 67 for (int i = 0; i < num_bytes; ++i) { |
44 data[i] = (value >> ((num_bytes - i - 1) * 8)) & 0xFF; | 68 data[i] = (value >> ((num_bytes - i - 1) * 8)) & 0xFF; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 sizeof(int16_t)>(true); | 157 sizeof(int16_t)>(true); |
134 TestWrite<int16_t, ByteWriter<int16_t>::WriteBigEndian, | 158 TestWrite<int16_t, ByteWriter<int16_t>::WriteBigEndian, |
135 sizeof(int16_t)>(true); | 159 sizeof(int16_t)>(true); |
136 } | 160 } |
137 | 161 |
138 TEST_F(ByteIoTest, Test24SBitBigEndian) { | 162 TEST_F(ByteIoTest, Test24SBitBigEndian) { |
139 TestRead<int32_t, ByteReader<int32_t, 3>::ReadBigEndian, 3>(true); | 163 TestRead<int32_t, ByteReader<int32_t, 3>::ReadBigEndian, 3>(true); |
140 TestWrite<int32_t, ByteWriter<int32_t, 3>::WriteBigEndian, 3>(true); | 164 TestWrite<int32_t, ByteWriter<int32_t, 3>::WriteBigEndian, 3>(true); |
141 } | 165 } |
142 | 166 |
143 // Disabled for UBSan: https://bugs.chromium.org/p/webrtc/issues/detail?id=5490 | 167 TEST_F(ByteIoTest, Test32SBitBigEndian) { |
144 #ifdef UNDEFINED_SANITIZER | |
145 #define MAYBE_Test32SBitBigEndian DISABLED_Test32SBitBigEndian | |
146 #else | |
147 #define MAYBE_Test32SBitBigEndian Test32SBitBigEndian | |
148 #endif | |
149 TEST_F(ByteIoTest, MAYBE_Test32SBitBigEndian) { | |
150 TestRead<int32_t, ByteReader<int32_t>::ReadBigEndian, | 168 TestRead<int32_t, ByteReader<int32_t>::ReadBigEndian, |
151 sizeof(int32_t)>(true); | 169 sizeof(int32_t)>(true); |
152 TestWrite<int32_t, ByteWriter<int32_t>::WriteBigEndian, | 170 TestWrite<int32_t, ByteWriter<int32_t>::WriteBigEndian, |
153 sizeof(int32_t)>(true); | 171 sizeof(int32_t)>(true); |
154 } | 172 } |
155 | 173 |
156 // Disabled for UBSan: https://bugs.chromium.org/p/webrtc/issues/detail?id=5490 | 174 TEST_F(ByteIoTest, Test64SBitBigEndian) { |
157 #ifdef UNDEFINED_SANITIZER | |
158 #define MAYBE_Test64SBitBigEndian DISABLED_Test64SBitBigEndian | |
159 #else | |
160 #define MAYBE_Test64SBitBigEndian Test64SBitBigEndian | |
161 #endif | |
162 TEST_F(ByteIoTest, MAYBE_Test64SBitBigEndian) { | |
163 TestRead<int64_t, ByteReader<int64_t>::ReadBigEndian, | 175 TestRead<int64_t, ByteReader<int64_t>::ReadBigEndian, |
164 sizeof(int64_t)>(true); | 176 sizeof(int64_t)>(true); |
165 TestWrite<int64_t, ByteWriter<int64_t>::WriteBigEndian, | 177 TestWrite<int64_t, ByteWriter<int64_t>::WriteBigEndian, |
166 sizeof(int64_t)>(true); | 178 sizeof(int64_t)>(true); |
167 } | 179 } |
168 | 180 |
169 TEST_F(ByteIoTest, Test16UBitLittleEndian) { | 181 TEST_F(ByteIoTest, Test16UBitLittleEndian) { |
170 TestRead<uint16_t, ByteReader<uint16_t>::ReadLittleEndian, | 182 TestRead<uint16_t, ByteReader<uint16_t>::ReadLittleEndian, |
171 sizeof(uint16_t)>(false); | 183 sizeof(uint16_t)>(false); |
172 TestWrite<uint16_t, ByteWriter<uint16_t>::WriteLittleEndian, | 184 TestWrite<uint16_t, ByteWriter<uint16_t>::WriteLittleEndian, |
(...skipping 24 matching lines...) Expand all Loading... | |
197 sizeof(int16_t)>(false); | 209 sizeof(int16_t)>(false); |
198 TestWrite<int16_t, ByteWriter<int16_t>::WriteLittleEndian, | 210 TestWrite<int16_t, ByteWriter<int16_t>::WriteLittleEndian, |
199 sizeof(int16_t)>(false); | 211 sizeof(int16_t)>(false); |
200 } | 212 } |
201 | 213 |
202 TEST_F(ByteIoTest, Test24SBitLittleEndian) { | 214 TEST_F(ByteIoTest, Test24SBitLittleEndian) { |
203 TestRead<int32_t, ByteReader<int32_t, 3>::ReadLittleEndian, 3>(false); | 215 TestRead<int32_t, ByteReader<int32_t, 3>::ReadLittleEndian, 3>(false); |
204 TestWrite<int32_t, ByteWriter<int32_t, 3>::WriteLittleEndian, 3>(false); | 216 TestWrite<int32_t, ByteWriter<int32_t, 3>::WriteLittleEndian, 3>(false); |
205 } | 217 } |
206 | 218 |
207 // Disabled for UBSan: https://bugs.chromium.org/p/webrtc/issues/detail?id=5490 | 219 TEST_F(ByteIoTest, Test32SBitLittleEndian) { |
208 #ifdef UNDEFINED_SANITIZER | |
209 #define MAYBE_Test32SBitLittleEndian DISABLED_Test32SBitLittleEndian | |
210 #else | |
211 #define MAYBE_Test32SBitLittleEndian Test32SBitLittleEndian | |
212 #endif | |
213 TEST_F(ByteIoTest, MAYBE_Test32SBitLittleEndian) { | |
214 TestRead<int32_t, ByteReader<int32_t>::ReadLittleEndian, | 220 TestRead<int32_t, ByteReader<int32_t>::ReadLittleEndian, |
215 sizeof(int32_t)>(false); | 221 sizeof(int32_t)>(false); |
216 TestWrite<int32_t, ByteWriter<int32_t>::WriteLittleEndian, | 222 TestWrite<int32_t, ByteWriter<int32_t>::WriteLittleEndian, |
217 sizeof(int32_t)>(false); | 223 sizeof(int32_t)>(false); |
218 } | 224 } |
219 | 225 |
220 // Disabled for UBSan: https://bugs.chromium.org/p/webrtc/issues/detail?id=5490 | 226 TEST_F(ByteIoTest, Test64SBitLittleEndian) { |
221 #ifdef UNDEFINED_SANITIZER | |
222 #define MAYBE_Test64SBitLittleEndian DISABLED_Test64SBitLittleEndian | |
223 #else | |
224 #define MAYBE_Test64SBitLittleEndian Test64SBitLittleEndian | |
225 #endif | |
226 TEST_F(ByteIoTest, MAYBE_Test64SBitLittleEndian) { | |
227 TestRead<int64_t, ByteReader<int64_t>::ReadLittleEndian, | 227 TestRead<int64_t, ByteReader<int64_t>::ReadLittleEndian, |
228 sizeof(int64_t)>(false); | 228 sizeof(int64_t)>(false); |
229 TestWrite<int64_t, ByteWriter<int64_t>::WriteLittleEndian, | 229 TestWrite<int64_t, ByteWriter<int64_t>::WriteLittleEndian, |
230 sizeof(int64_t)>(false); | 230 sizeof(int64_t)>(false); |
231 } | 231 } |
232 | 232 |
233 // Sets up a fixed byte array and converts N bytes from the array into a | 233 // Sets up a fixed byte array and converts N bytes from the array into a |
234 // uint64_t. Verifies the value with hard-coded reference. | 234 // uint64_t. Verifies the value with hard-coded reference. |
235 TEST(ByteIo, SanityCheckFixedByteArrayUnsignedReadBigEndian) { | 235 TEST(ByteIo, SanityCheckFixedByteArrayUnsignedReadBigEndian) { |
236 uint8_t data[8] = {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}; | 236 uint8_t data[8] = {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}; |
(...skipping 26 matching lines...) Expand all Loading... | |
263 EXPECT_EQ(static_cast<uint64_t>(0xBBCCDDEEFF), value); | 263 EXPECT_EQ(static_cast<uint64_t>(0xBBCCDDEEFF), value); |
264 value = ByteReader<uint64_t, 6>::ReadLittleEndian(data); | 264 value = ByteReader<uint64_t, 6>::ReadLittleEndian(data); |
265 EXPECT_EQ(static_cast<uint64_t>(0xAABBCCDDEEFF), value); | 265 EXPECT_EQ(static_cast<uint64_t>(0xAABBCCDDEEFF), value); |
266 value = ByteReader<uint64_t, 7>::ReadLittleEndian(data); | 266 value = ByteReader<uint64_t, 7>::ReadLittleEndian(data); |
267 EXPECT_EQ(static_cast<uint64_t>(0x99AABBCCDDEEFF), value); | 267 EXPECT_EQ(static_cast<uint64_t>(0x99AABBCCDDEEFF), value); |
268 value = ByteReader<uint64_t, 8>::ReadLittleEndian(data); | 268 value = ByteReader<uint64_t, 8>::ReadLittleEndian(data); |
269 EXPECT_EQ(static_cast<uint64_t>(0x8899AABBCCDDEEFF), value); | 269 EXPECT_EQ(static_cast<uint64_t>(0x8899AABBCCDDEEFF), value); |
270 } | 270 } |
271 } // namespace | 271 } // namespace |
272 } // namespace webrtc | 272 } // namespace webrtc |
OLD | NEW |