Chromium Code Reviews| 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 |