TestEndian.cpp (20636B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/Assertions.h" 8 #include "mozilla/EndianUtils.h" 9 10 #include <stddef.h> 11 12 using mozilla::BigEndian; 13 using mozilla::LittleEndian; 14 using mozilla::NativeEndian; 15 16 template <typename T> 17 void TestSingleSwap(T aValue, T aSwappedValue) { 18 #if MOZ_LITTLE_ENDIAN() 19 MOZ_RELEASE_ASSERT(NativeEndian::swapToBigEndian(aValue) == aSwappedValue); 20 MOZ_RELEASE_ASSERT(NativeEndian::swapFromBigEndian(aValue) == aSwappedValue); 21 MOZ_RELEASE_ASSERT(NativeEndian::swapToNetworkOrder(aValue) == aSwappedValue); 22 MOZ_RELEASE_ASSERT(NativeEndian::swapFromNetworkOrder(aValue) == 23 aSwappedValue); 24 #else 25 MOZ_RELEASE_ASSERT(NativeEndian::swapToLittleEndian(aValue) == aSwappedValue); 26 MOZ_RELEASE_ASSERT(NativeEndian::swapFromLittleEndian(aValue) == 27 aSwappedValue); 28 #endif 29 } 30 31 template <typename T> 32 void TestSingleNoSwap(T aValue, T aUnswappedValue) { 33 #if MOZ_LITTLE_ENDIAN() 34 MOZ_RELEASE_ASSERT(NativeEndian::swapToLittleEndian(aValue) == 35 aUnswappedValue); 36 MOZ_RELEASE_ASSERT(NativeEndian::swapFromLittleEndian(aValue) == 37 aUnswappedValue); 38 #else 39 MOZ_RELEASE_ASSERT(NativeEndian::swapToBigEndian(aValue) == aUnswappedValue); 40 MOZ_RELEASE_ASSERT(NativeEndian::swapFromBigEndian(aValue) == 41 aUnswappedValue); 42 MOZ_RELEASE_ASSERT(NativeEndian::swapToNetworkOrder(aValue) == 43 aUnswappedValue); 44 MOZ_RELEASE_ASSERT(NativeEndian::swapFromNetworkOrder(aValue) == 45 aUnswappedValue); 46 #endif 47 } 48 49 // EndianUtils.h functions are declared as protected in a base class and 50 // then re-exported as public in public derived classes. The 51 // standardese around explicit instantiation of templates is not clear 52 // in such cases. Provide these wrappers to make things more explicit. 53 // For your own enlightenment, you may wish to peruse: 54 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56152 and subsequently 55 // http://j.mp/XosS6S . 56 #define WRAP_COPYTO(NAME) \ 57 template <typename T> \ 58 void NAME(void* aDst, const T* aSrc, size_t aCount) { \ 59 NativeEndian::NAME<T>(aDst, aSrc, aCount); \ 60 } 61 62 WRAP_COPYTO(copyAndSwapToLittleEndian) 63 WRAP_COPYTO(copyAndSwapToBigEndian) 64 WRAP_COPYTO(copyAndSwapToNetworkOrder) 65 66 #define WRAP_COPYFROM(NAME) \ 67 template <typename T> \ 68 void NAME(T* aDst, const void* aSrc, size_t aCount) { \ 69 NativeEndian::NAME<T>(aDst, aSrc, aCount); \ 70 } 71 72 WRAP_COPYFROM(copyAndSwapFromLittleEndian) 73 WRAP_COPYFROM(copyAndSwapFromBigEndian) 74 WRAP_COPYFROM(copyAndSwapFromNetworkOrder) 75 76 #define WRAP_IN_PLACE(NAME) \ 77 template <typename T> \ 78 void NAME(T* aP, size_t aCount) { \ 79 NativeEndian::NAME<T>(aP, aCount); \ 80 } 81 WRAP_IN_PLACE(swapToLittleEndianInPlace) 82 WRAP_IN_PLACE(swapFromLittleEndianInPlace) 83 WRAP_IN_PLACE(swapToBigEndianInPlace) 84 WRAP_IN_PLACE(swapFromBigEndianInPlace) 85 WRAP_IN_PLACE(swapToNetworkOrderInPlace) 86 WRAP_IN_PLACE(swapFromNetworkOrderInPlace) 87 88 enum SwapExpectation { Swap, NoSwap }; 89 90 template <typename T, size_t Count> 91 void TestBulkSwapToSub(enum SwapExpectation aExpectSwap, 92 const T (&aValues)[Count], 93 void (*aSwapperFunc)(void*, const T*, size_t), 94 T (*aReaderFunc)(const void*)) { 95 const size_t arraySize = 2 * Count; 96 const size_t bufferSize = arraySize * sizeof(T); 97 static uint8_t buffer[bufferSize]; 98 const uint8_t fillValue = 0xa5; 99 static uint8_t checkBuffer[bufferSize]; 100 101 MOZ_RELEASE_ASSERT(bufferSize > 2 * sizeof(T)); 102 103 memset(checkBuffer, fillValue, bufferSize); 104 105 for (size_t startPosition = 0; startPosition < sizeof(T); ++startPosition) { 106 for (size_t nValues = 0; nValues < Count; ++nValues) { 107 memset(buffer, fillValue, bufferSize); 108 aSwapperFunc(buffer + startPosition, aValues, nValues); 109 110 MOZ_RELEASE_ASSERT(memcmp(buffer, checkBuffer, startPosition) == 0); 111 size_t valuesEndPosition = startPosition + sizeof(T) * nValues; 112 MOZ_RELEASE_ASSERT(memcmp(buffer + valuesEndPosition, 113 checkBuffer + valuesEndPosition, 114 bufferSize - valuesEndPosition) == 0); 115 if (aExpectSwap == NoSwap) { 116 MOZ_RELEASE_ASSERT( 117 memcmp(buffer + startPosition, aValues, nValues * sizeof(T)) == 0); 118 } 119 for (size_t i = 0; i < nValues; ++i) { 120 MOZ_RELEASE_ASSERT( 121 aReaderFunc(buffer + startPosition + sizeof(T) * i) == aValues[i]); 122 } 123 } 124 } 125 } 126 127 template <typename T, size_t Count> 128 void TestBulkSwapFromSub(enum SwapExpectation aExpectSwap, 129 const T (&aValues)[Count], 130 void (*aSwapperFunc)(T*, const void*, size_t), 131 T (*aReaderFunc)(const void*)) { 132 const size_t arraySize = 2 * Count; 133 const size_t bufferSize = arraySize * sizeof(T); 134 static T buffer[arraySize]; 135 const uint8_t fillValue = 0xa5; 136 static T checkBuffer[arraySize]; 137 138 memset(checkBuffer, fillValue, bufferSize); 139 140 for (size_t startPosition = 0; startPosition < Count; ++startPosition) { 141 for (size_t nValues = 0; nValues < (Count - startPosition); ++nValues) { 142 memset(buffer, fillValue, bufferSize); 143 aSwapperFunc(buffer + startPosition, aValues, nValues); 144 145 MOZ_RELEASE_ASSERT( 146 memcmp(buffer, checkBuffer, startPosition * sizeof(T)) == 0); 147 size_t valuesEndPosition = startPosition + nValues; 148 MOZ_RELEASE_ASSERT( 149 memcmp(buffer + valuesEndPosition, checkBuffer + valuesEndPosition, 150 (arraySize - valuesEndPosition) * sizeof(T)) == 0); 151 if (aExpectSwap == NoSwap) { 152 MOZ_RELEASE_ASSERT( 153 memcmp(buffer + startPosition, aValues, nValues * sizeof(T)) == 0); 154 } 155 for (size_t i = 0; i < nValues; ++i) { 156 MOZ_RELEASE_ASSERT(aReaderFunc(buffer + startPosition + i) == 157 aValues[i]); 158 } 159 } 160 } 161 } 162 163 template <typename T, size_t Count> 164 void TestBulkInPlaceSub(enum SwapExpectation aExpectSwap, 165 const T (&aValues)[Count], 166 void (*aSwapperFunc)(T*, size_t), 167 T (*aReaderFunc)(const void*)) { 168 const size_t bufferCount = 4 * Count; 169 const size_t bufferSize = bufferCount * sizeof(T); 170 static T buffer[bufferCount]; 171 const T fillValue = 0xa5; 172 static T checkBuffer[bufferCount]; 173 174 MOZ_RELEASE_ASSERT(bufferSize > 2 * sizeof(T)); 175 176 memset(checkBuffer, fillValue, bufferSize); 177 178 for (size_t startPosition = 0; startPosition < Count; ++startPosition) { 179 for (size_t nValues = 0; nValues < Count; ++nValues) { 180 memset(buffer, fillValue, bufferSize); 181 memcpy(buffer + startPosition, aValues, nValues * sizeof(T)); 182 aSwapperFunc(buffer + startPosition, nValues); 183 184 MOZ_RELEASE_ASSERT( 185 memcmp(buffer, checkBuffer, startPosition * sizeof(T)) == 0); 186 size_t valuesEndPosition = startPosition + nValues; 187 MOZ_RELEASE_ASSERT( 188 memcmp(buffer + valuesEndPosition, checkBuffer + valuesEndPosition, 189 bufferSize - valuesEndPosition * sizeof(T)) == 0); 190 if (aExpectSwap == NoSwap) { 191 MOZ_RELEASE_ASSERT( 192 memcmp(buffer + startPosition, aValues, nValues * sizeof(T)) == 0); 193 } 194 for (size_t i = 0; i < nValues; ++i) { 195 MOZ_RELEASE_ASSERT(aReaderFunc(buffer + startPosition + i) == 196 aValues[i]); 197 } 198 } 199 } 200 } 201 202 template <typename T> 203 struct Reader {}; 204 205 #define SPECIALIZE_READER(TYPE, READ_FUNC) \ 206 template <> \ 207 struct Reader<TYPE> { \ 208 static TYPE readLE(const void* aP) { return LittleEndian::READ_FUNC(aP); } \ 209 static TYPE readBE(const void* aP) { return BigEndian::READ_FUNC(aP); } \ 210 }; 211 212 SPECIALIZE_READER(uint16_t, readUint16) 213 SPECIALIZE_READER(uint32_t, readUint32) 214 SPECIALIZE_READER(uint64_t, readUint64) 215 SPECIALIZE_READER(int16_t, readInt16) 216 SPECIALIZE_READER(int32_t, readInt32) 217 SPECIALIZE_READER(int64_t, readInt64) 218 219 template <typename T, size_t Count> 220 void TestBulkSwap(const T (&aBytes)[Count]) { 221 #if MOZ_LITTLE_ENDIAN() 222 TestBulkSwapToSub(Swap, aBytes, copyAndSwapToBigEndian<T>, Reader<T>::readBE); 223 TestBulkSwapFromSub(Swap, aBytes, copyAndSwapFromBigEndian<T>, 224 Reader<T>::readBE); 225 TestBulkSwapToSub(Swap, aBytes, copyAndSwapToNetworkOrder<T>, 226 Reader<T>::readBE); 227 TestBulkSwapFromSub(Swap, aBytes, copyAndSwapFromNetworkOrder<T>, 228 Reader<T>::readBE); 229 #else 230 TestBulkSwapToSub(Swap, aBytes, copyAndSwapToLittleEndian<T>, 231 Reader<T>::readLE); 232 TestBulkSwapFromSub(Swap, aBytes, copyAndSwapFromLittleEndian<T>, 233 Reader<T>::readLE); 234 #endif 235 } 236 237 template <typename T, size_t Count> 238 void TestBulkNoSwap(const T (&aBytes)[Count]) { 239 #if MOZ_LITTLE_ENDIAN() 240 TestBulkSwapToSub(NoSwap, aBytes, copyAndSwapToLittleEndian<T>, 241 Reader<T>::readLE); 242 TestBulkSwapFromSub(NoSwap, aBytes, copyAndSwapFromLittleEndian<T>, 243 Reader<T>::readLE); 244 #else 245 TestBulkSwapToSub(NoSwap, aBytes, copyAndSwapToBigEndian<T>, 246 Reader<T>::readBE); 247 TestBulkSwapFromSub(NoSwap, aBytes, copyAndSwapFromBigEndian<T>, 248 Reader<T>::readBE); 249 TestBulkSwapToSub(NoSwap, aBytes, copyAndSwapToNetworkOrder<T>, 250 Reader<T>::readBE); 251 TestBulkSwapFromSub(NoSwap, aBytes, copyAndSwapFromNetworkOrder<T>, 252 Reader<T>::readBE); 253 #endif 254 } 255 256 template <typename T, size_t Count> 257 void TestBulkInPlaceSwap(const T (&aBytes)[Count]) { 258 #if MOZ_LITTLE_ENDIAN() 259 TestBulkInPlaceSub(Swap, aBytes, swapToBigEndianInPlace<T>, 260 Reader<T>::readBE); 261 TestBulkInPlaceSub(Swap, aBytes, swapFromBigEndianInPlace<T>, 262 Reader<T>::readBE); 263 TestBulkInPlaceSub(Swap, aBytes, swapToNetworkOrderInPlace<T>, 264 Reader<T>::readBE); 265 TestBulkInPlaceSub(Swap, aBytes, swapFromNetworkOrderInPlace<T>, 266 Reader<T>::readBE); 267 #else 268 TestBulkInPlaceSub(Swap, aBytes, swapToLittleEndianInPlace<T>, 269 Reader<T>::readLE); 270 TestBulkInPlaceSub(Swap, aBytes, swapFromLittleEndianInPlace<T>, 271 Reader<T>::readLE); 272 #endif 273 } 274 275 template <typename T, size_t Count> 276 void TestBulkInPlaceNoSwap(const T (&aBytes)[Count]) { 277 #if MOZ_LITTLE_ENDIAN() 278 TestBulkInPlaceSub(NoSwap, aBytes, swapToLittleEndianInPlace<T>, 279 Reader<T>::readLE); 280 TestBulkInPlaceSub(NoSwap, aBytes, swapFromLittleEndianInPlace<T>, 281 Reader<T>::readLE); 282 #else 283 TestBulkInPlaceSub(NoSwap, aBytes, swapToBigEndianInPlace<T>, 284 Reader<T>::readBE); 285 TestBulkInPlaceSub(NoSwap, aBytes, swapFromBigEndianInPlace<T>, 286 Reader<T>::readBE); 287 TestBulkInPlaceSub(NoSwap, aBytes, swapToNetworkOrderInPlace<T>, 288 Reader<T>::readBE); 289 TestBulkInPlaceSub(NoSwap, aBytes, swapFromNetworkOrderInPlace<T>, 290 Reader<T>::readBE); 291 #endif 292 } 293 294 int main() { 295 static const uint8_t unsigned_bytes[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 296 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 297 0x05, 0x06, 0x07, 0x08}; 298 static const int8_t signed_bytes[16] = { 299 -0x0f, -0x0e, -0x0d, -0x0c, -0x0b, -0x0a, -0x09, -0x08, 300 -0x0f, -0x0e, -0x0d, -0x0c, -0x0b, -0x0a, -0x09, -0x08}; 301 static const uint16_t uint16_values[8] = {0x0102, 0x0304, 0x0506, 0x0708, 302 0x0102, 0x0304, 0x0506, 0x0708}; 303 static const int16_t int16_values[8] = { 304 int16_t(0xf1f2), int16_t(0xf3f4), int16_t(0xf5f6), int16_t(0xf7f8), 305 int16_t(0xf1f2), int16_t(0xf3f4), int16_t(0xf5f6), int16_t(0xf7f8)}; 306 static const uint32_t uint32_values[4] = {0x01020304, 0x05060708, 0x01020304, 307 0x05060708}; 308 static const int32_t int32_values[4] = { 309 int32_t(0xf1f2f3f4), int32_t(0xf5f6f7f8), int32_t(0xf1f2f3f4), 310 int32_t(0xf5f6f7f8)}; 311 static const uint64_t uint64_values[2] = {0x0102030405060708, 312 0x0102030405060708}; 313 static const int64_t int64_values[2] = {int64_t(0xf1f2f3f4f5f6f7f8), 314 int64_t(0xf1f2f3f4f5f6f7f8)}; 315 uint8_t buffer[8]; 316 317 MOZ_RELEASE_ASSERT(LittleEndian::readUint16(&unsigned_bytes[0]) == 0x0201); 318 MOZ_RELEASE_ASSERT(BigEndian::readUint16(&unsigned_bytes[0]) == 0x0102); 319 320 MOZ_RELEASE_ASSERT(LittleEndian::readUint32(&unsigned_bytes[0]) == 321 0x04030201U); 322 MOZ_RELEASE_ASSERT(BigEndian::readUint32(&unsigned_bytes[0]) == 0x01020304U); 323 324 MOZ_RELEASE_ASSERT(LittleEndian::readUint64(&unsigned_bytes[0]) == 325 0x0807060504030201ULL); 326 MOZ_RELEASE_ASSERT(BigEndian::readUint64(&unsigned_bytes[0]) == 327 0x0102030405060708ULL); 328 329 if (sizeof(uintptr_t) == 8) { 330 // MSVC warning C4309 is "'static_cast': truncation of constant value" and 331 // will hit for the literal casts below in 32-bit builds -- in dead code, 332 // because only the other arm of this |if| runs. Turn off the warning for 333 // these two uses in dead code. 334 #ifdef _MSC_VER 335 # pragma warning(push) 336 # pragma warning(disable : 4309) 337 #endif 338 MOZ_RELEASE_ASSERT(LittleEndian::readUintptr(&unsigned_bytes[0]) == 339 static_cast<uintptr_t>(0x0807060504030201ULL)); 340 MOZ_RELEASE_ASSERT(BigEndian::readUintptr(&unsigned_bytes[0]) == 341 static_cast<uintptr_t>(0x0102030405060708ULL)); 342 #ifdef _MSC_VER 343 # pragma warning(pop) 344 #endif 345 } else { 346 MOZ_RELEASE_ASSERT(LittleEndian::readUintptr(&unsigned_bytes[0]) == 347 0x04030201U); 348 MOZ_RELEASE_ASSERT(BigEndian::readUintptr(&unsigned_bytes[0]) == 349 0x01020304U); 350 } 351 352 LittleEndian::writeUint16(&buffer[0], 0x0201); 353 MOZ_RELEASE_ASSERT(memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint16_t)) == 354 0); 355 BigEndian::writeUint16(&buffer[0], 0x0102); 356 MOZ_RELEASE_ASSERT(memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint16_t)) == 357 0); 358 359 LittleEndian::writeUint32(&buffer[0], 0x04030201U); 360 MOZ_RELEASE_ASSERT(memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint32_t)) == 361 0); 362 BigEndian::writeUint32(&buffer[0], 0x01020304U); 363 MOZ_RELEASE_ASSERT(memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint32_t)) == 364 0); 365 366 LittleEndian::writeUint64(&buffer[0], 0x0807060504030201ULL); 367 MOZ_RELEASE_ASSERT(memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint64_t)) == 368 0); 369 BigEndian::writeUint64(&buffer[0], 0x0102030405060708ULL); 370 MOZ_RELEASE_ASSERT(memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint64_t)) == 371 0); 372 373 memset(&buffer[0], 0xff, sizeof(buffer)); 374 LittleEndian::writeUintptr(&buffer[0], uintptr_t(0x0807060504030201ULL)); 375 MOZ_RELEASE_ASSERT( 376 memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uintptr_t)) == 0); 377 if (sizeof(uintptr_t) == 4) { 378 MOZ_RELEASE_ASSERT(LittleEndian::readUint32(&buffer[4]) == 0xffffffffU); 379 } 380 381 memset(&buffer[0], 0xff, sizeof(buffer)); 382 if (sizeof(uintptr_t) == 8) { 383 BigEndian::writeUintptr(&buffer[0], uintptr_t(0x0102030405060708ULL)); 384 } else { 385 BigEndian::writeUintptr(&buffer[0], uintptr_t(0x01020304U)); 386 MOZ_RELEASE_ASSERT(LittleEndian::readUint32(&buffer[4]) == 0xffffffffU); 387 } 388 MOZ_RELEASE_ASSERT( 389 memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uintptr_t)) == 0); 390 391 MOZ_RELEASE_ASSERT(LittleEndian::readInt16(&signed_bytes[0]) == 392 int16_t(0xf2f1)); 393 MOZ_RELEASE_ASSERT(BigEndian::readInt16(&signed_bytes[0]) == int16_t(0xf1f2)); 394 395 MOZ_RELEASE_ASSERT(LittleEndian::readInt32(&signed_bytes[0]) == 396 int32_t(0xf4f3f2f1)); 397 MOZ_RELEASE_ASSERT(BigEndian::readInt32(&signed_bytes[0]) == 398 int32_t(0xf1f2f3f4)); 399 400 MOZ_RELEASE_ASSERT(LittleEndian::readInt64(&signed_bytes[0]) == 401 int64_t(0xf8f7f6f5f4f3f2f1LL)); 402 MOZ_RELEASE_ASSERT(BigEndian::readInt64(&signed_bytes[0]) == 403 int64_t(0xf1f2f3f4f5f6f7f8LL)); 404 405 if (sizeof(uintptr_t) == 8) { 406 MOZ_RELEASE_ASSERT(LittleEndian::readIntptr(&signed_bytes[0]) == 407 intptr_t(0xf8f7f6f5f4f3f2f1LL)); 408 MOZ_RELEASE_ASSERT(BigEndian::readIntptr(&signed_bytes[0]) == 409 intptr_t(0xf1f2f3f4f5f6f7f8LL)); 410 } else { 411 MOZ_RELEASE_ASSERT(LittleEndian::readIntptr(&signed_bytes[0]) == 412 intptr_t(0xf4f3f2f1)); 413 MOZ_RELEASE_ASSERT(BigEndian::readIntptr(&signed_bytes[0]) == 414 intptr_t(0xf1f2f3f4)); 415 } 416 417 LittleEndian::writeInt16(&buffer[0], int16_t(0xf2f1)); 418 MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(int16_t)) == 419 0); 420 BigEndian::writeInt16(&buffer[0], int16_t(0xf1f2)); 421 MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(int16_t)) == 422 0); 423 424 LittleEndian::writeInt32(&buffer[0], 0xf4f3f2f1); 425 MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(int32_t)) == 426 0); 427 BigEndian::writeInt32(&buffer[0], 0xf1f2f3f4); 428 MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(int32_t)) == 429 0); 430 431 LittleEndian::writeInt64(&buffer[0], 0xf8f7f6f5f4f3f2f1LL); 432 MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(int64_t)) == 433 0); 434 BigEndian::writeInt64(&buffer[0], 0xf1f2f3f4f5f6f7f8LL); 435 MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(int64_t)) == 436 0); 437 438 memset(&buffer[0], 0xff, sizeof(buffer)); 439 LittleEndian::writeIntptr(&buffer[0], intptr_t(0xf8f7f6f5f4f3f2f1LL)); 440 MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(intptr_t)) == 441 0); 442 if (sizeof(intptr_t) == 4) { 443 MOZ_RELEASE_ASSERT(LittleEndian::readUint32(&buffer[4]) == 0xffffffffU); 444 } 445 446 memset(&buffer[0], 0xff, sizeof(buffer)); 447 if (sizeof(intptr_t) == 8) { 448 BigEndian::writeIntptr(&buffer[0], intptr_t(0xf1f2f3f4f5f6f7f8LL)); 449 } else { 450 BigEndian::writeIntptr(&buffer[0], intptr_t(0xf1f2f3f4)); 451 MOZ_RELEASE_ASSERT(LittleEndian::readUint32(&buffer[4]) == 0xffffffffU); 452 } 453 MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(intptr_t)) == 454 0); 455 456 TestSingleSwap(uint16_t(0xf2f1), uint16_t(0xf1f2)); 457 TestSingleSwap(uint32_t(0xf4f3f2f1), uint32_t(0xf1f2f3f4)); 458 TestSingleSwap(uint64_t(0xf8f7f6f5f4f3f2f1), uint64_t(0xf1f2f3f4f5f6f7f8)); 459 460 TestSingleSwap(int16_t(0xf2f1), int16_t(0xf1f2)); 461 TestSingleSwap(int32_t(0xf4f3f2f1), int32_t(0xf1f2f3f4)); 462 TestSingleSwap(int64_t(0xf8f7f6f5f4f3f2f1), int64_t(0xf1f2f3f4f5f6f7f8)); 463 464 TestSingleNoSwap(uint16_t(0xf2f1), uint16_t(0xf2f1)); 465 TestSingleNoSwap(uint32_t(0xf4f3f2f1), uint32_t(0xf4f3f2f1)); 466 TestSingleNoSwap(uint64_t(0xf8f7f6f5f4f3f2f1), uint64_t(0xf8f7f6f5f4f3f2f1)); 467 468 TestSingleNoSwap(int16_t(0xf2f1), int16_t(0xf2f1)); 469 TestSingleNoSwap(int32_t(0xf4f3f2f1), int32_t(0xf4f3f2f1)); 470 TestSingleNoSwap(int64_t(0xf8f7f6f5f4f3f2f1), int64_t(0xf8f7f6f5f4f3f2f1)); 471 472 TestBulkSwap(uint16_values); 473 TestBulkSwap(int16_values); 474 TestBulkSwap(uint32_values); 475 TestBulkSwap(int32_values); 476 TestBulkSwap(uint64_values); 477 TestBulkSwap(int64_values); 478 479 TestBulkNoSwap(uint16_values); 480 TestBulkNoSwap(int16_values); 481 TestBulkNoSwap(uint32_values); 482 TestBulkNoSwap(int32_values); 483 TestBulkNoSwap(uint64_values); 484 TestBulkNoSwap(int64_values); 485 486 TestBulkInPlaceSwap(uint16_values); 487 TestBulkInPlaceSwap(int16_values); 488 TestBulkInPlaceSwap(uint32_values); 489 TestBulkInPlaceSwap(int32_values); 490 TestBulkInPlaceSwap(uint64_values); 491 TestBulkInPlaceSwap(int64_values); 492 493 TestBulkInPlaceNoSwap(uint16_values); 494 TestBulkInPlaceNoSwap(int16_values); 495 TestBulkInPlaceNoSwap(uint32_values); 496 TestBulkInPlaceNoSwap(int32_values); 497 TestBulkInPlaceNoSwap(uint64_values); 498 TestBulkInPlaceNoSwap(int64_values); 499 500 return 0; 501 }