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