1 //------------------------------------------------------------------------
2 //  EDGE Endian handling
3 //------------------------------------------------------------------------
4 //
5 //  Copyright (c) 2003-2008  The EDGE Team.
6 //
7 //  This program is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU Lesser General Public License
9 //  (LGPL) as published by the Free Software Foundation.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //------------------------------------------------------------------------
17 //
18 //  Based on SDL_byteorder.h and SDL_endian.h.
19 //
20 //------------------------------------------------------------------------
21 
22 #ifndef __EPI_ENDIAN_H__
23 #define __EPI_ENDIAN_H__
24 
25 // the two types of endianness
26 #define EPI_LIL_ENDIAN  1234
27 #define EPI_BIG_ENDIAN  4321
28 
29 #if defined(__LITTLE_ENDIAN__) ||  \
30     defined(__i386__)  || defined(__ia64__) || defined(WIN32)   ||  \
31 	defined(__alpha__) || defined(__alpha)  || defined(__arm__) ||  \
32 	(defined(__mips__) && defined(__MIPSEL__)) ||  \
33 	defined(__SYMBIAN32__) || defined(__x86_64__)
34 #define EPI_BYTEORDER   EPI_LIL_ENDIAN
35 #else
36 #define EPI_BYTEORDER   EPI_BIG_ENDIAN
37 #endif
38 
39 // The macros used to swap values.  Try to use superfast macros on systems
40 // that support them, otherwise use C++ inline functions.
41 #ifdef LINUX
42 #ifdef __FreeBSD__
43 #include <sys/endian.h>
44 #else
45 #include <endian.h>
46 #endif
47 #ifdef __arch__swab16
48 #define EPI_Swap16  __arch__swab16
49 #endif
50 #ifdef __arch__swab32
51 #define EPI_Swap32  __arch__swab32
52 #endif
53 #endif /* LINUX */
54 
55 #ifndef EPI_Swap16
56 #define EPI_Swap16  epi::endian_swapper_c::Swap16
57 #endif
58 
59 #ifndef EPI_Swap32
60 #define EPI_Swap32  epi::endian_swapper_c::Swap32
61 #endif
62 
63 
64 // Byteswap item between the specified endianness to the native endianness
65 #if EPI_BYTEORDER == EPI_LIL_ENDIAN
66 #define EPI_LE_U16(X)  ((u16_t)(X))
67 #define EPI_LE_U32(X)  ((u32_t)(X))
68 #define EPI_BE_U16(X)  EPI_Swap16(X)
69 #define EPI_BE_U32(X)  EPI_Swap32(X)
70 #else
71 #define EPI_LE_U16(X)  EPI_Swap16(X)
72 #define EPI_LE_U32(X)  EPI_Swap32(X)
73 #define EPI_BE_U16(X)  ((u16_t)(X))
74 #define EPI_BE_U32(X)  ((u32_t)(X))
75 #endif
76 
77 #define EPI_LE_S16(X)  ((s16_t) EPI_LE_U16((u16_t) (X)))
78 #define EPI_LE_S32(X)  ((s32_t) EPI_LE_U32((u32_t) (X)))
79 #define EPI_BE_S16(X)  ((s16_t) EPI_BE_U16((u16_t) (X)))
80 #define EPI_BE_S32(X)  ((s32_t) EPI_BE_U32((u32_t) (X)))
81 
82 namespace epi
83 {
84 	class endian_swapper_c
85 	{
86 	public:
87 		static u16_t Swap16(u16_t x);
88 		static u32_t Swap32(u32_t x);
89 	};
90 
91 	// Swap 16bit, that is, MSB and LSB byte.
Swap16(u16_t x)92 	inline u16_t endian_swapper_c::Swap16(u16_t x)
93 	{
94 		// No masking with 0xFF should be necessary.
95 		return (x >> 8) | (x << 8);
96 	}
97 
98 	// Swapping 32bit.
Swap32(u32_t x)99 	inline u32_t endian_swapper_c::Swap32(u32_t x)
100 	{
101 		return
102 			(x >> 24)
103 			| ((x >> 8) & 0xff00)
104 			| ((x << 8) & 0xff0000)
105 			| (x << 24);
106 	}
107 
108 } // namespace epi
109 
110 #endif  /* __EPI_ENDIAN_H__ */
111 
112 //--- editor settings ---
113 // vi:ts=4:sw=4:noexpandtab
114