1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */ 2 3 /** 4 * @brief byte order handling 5 * 6 * Mac PPC: BIG Endian 7 * Mac X86: little Endian 8 * 9 * Win X86: little Endian 10 * 11 * BSD X86: BIG Endian 12 * Linux X86: BIG Endian 13 * 14 * Um... all x86 machines are little endian. 15 * - cfh 16 */ 17 18 #ifndef BYTE_ORDER_H 19 #define BYTE_ORDER_H 20 21 /* 22 * The swabbing stuff looks backwards, but the files 23 * are _originally_ little endian (win32 x86). 24 * So in this case little endian is the standard while 25 * big endian is the exception. 26 */ 27 28 #if defined(__linux__) 29 30 #include <string.h> // for memcpy 31 #include <byteswap.h> 32 33 #if __BYTE_ORDER == __BIG_ENDIAN 34 #define swabWord(w) (bswap_16(w)) 35 #define swabDWord(w) (bswap_32(w)) 36 #define swab64(w) (bswap_64(w)) 37 /* 38 * My brother tells me that a C compiler must store floats in memory 39 * by a particular standard, except for the endianness; hence, this 40 * will work on all C compilers. 41 */ swabFloat(float w)42 static inline float swabFloat(float w) { 43 char octets[4]; 44 char ret_octets[4]; 45 float ret; 46 47 memcpy(octets, &w, 4); 48 49 ret_octets[0] = octets[3]; 50 ret_octets[1] = octets[2]; 51 ret_octets[2] = octets[1]; 52 ret_octets[3] = octets[0]; 53 54 memcpy(&ret, ret_octets, 4); 55 56 return ret; 57 } 58 #else 59 // do not swab 60 #endif 61 62 #elif defined(__FreeBSD__) 63 64 #include <sys/endian.h> 65 66 #define swabWord(w) (htole16(w)) 67 #define swabDWord(w) (htole32(w)) 68 #define swab64(w) (htole64(w)) swabFloat(float w)69 static inline float swabFloat(float w) { 70 // compile time assertion to validate sizeof(int) == sizeof(float) 71 typedef int sizeof_long_equals_sizeof_float[sizeof(int) == sizeof(float) ? 1 : -1]; 72 int l = swabDWord(*(int*)&w); 73 return *(float*)&l; 74 } 75 76 #elif defined(__APPLE__) && defined(_BIG_ENDIAN) 77 78 #include <CoreFoundation/CFByteOrder.h> 79 80 #define swabWord(w) (CFSwapInt16(w)) 81 #define swabDWord(w) (CFSwapInt32(w)) 82 #define swab64(w) (CFSwapInt64(w)) 83 // swabFloat(w) do not swab 84 85 #else 86 // WIN32 87 88 // do not swab 89 90 #endif 91 92 93 94 #if defined(swabWord) 95 #define swabWordInPlace(w) (w = swabWord(w)) 96 #else // defined(swabWord) 97 // do nothing 98 #define swabWord(w) (w) 99 #define swabWordInPlace(w) 100 #endif // defined(swabWord) 101 102 #if defined(swabDWord) 103 #define swabDWordInPlace(w) (w = swabDWord(w)) 104 #else // defined(swabDWord) 105 // do nothing 106 #define swabDWord(w) (w) 107 #define swabDWordInPlace(w) 108 #endif // defined(swabDWord) 109 110 #if defined(swab64) 111 #define swab64InPlace(w) (w = swab64(w)) 112 #else // defined(swab64) 113 // do nothing 114 #define swab64(w) (w) 115 #define swab64InPlace(w) 116 #endif // defined(swab64) 117 118 #if defined(swabFloat) 119 #define swabFloatInPlace(w) (w = swabFloat(w)) 120 #else // defined(swabFloat) 121 // do nothing 122 #define swabFloat(w) (w) 123 #define swabFloatInPlace(w) 124 #endif // defined(swabFloat) 125 126 // backwards compatibility (used until 19. July 2011) 127 #define swabword(w) swabWord(w) 128 #define swabdword(w) swabDWord(w) 129 #define swabfloat(w) swabFloat(w) 130 131 #endif // BYTE_ORDER_H 132