tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }