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>
TestSingleSwap(T aValue,T aSwappedValue)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>
TestSingleNoSwap(T aValue,T aUnswappedValue)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>
TestBulkSwapToSub(enum SwapExpectation aExpectSwap,const T (& aValues)[Count],void (* aSwapperFunc)(void *,const T *,size_t),T (* aReaderFunc)(const void *))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>
TestBulkSwapFromSub(enum SwapExpectation aExpectSwap,const T (& aValues)[Count],void (* aSwapperFunc)(T *,const void *,size_t),T (* aReaderFunc)(const void *))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>
TestBulkInPlaceSub(enum SwapExpectation aExpectSwap,const T (& aValues)[Count],void (* aSwapperFunc)(T *,size_t),T (* aReaderFunc)(const void *))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
SPECIALIZE_READER(uint16_t,readUint16)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>
TestBulkNoSwap(const T (& aBytes)[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>
TestBulkInPlaceSwap(const T (& aBytes)[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>
TestBulkInPlaceNoSwap(const T (& aBytes)[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
main()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 }
502