globally remove all trailing whitespace from ardour code base.
[ardour.git] / libs / backends / wavesaudio / wavesapi / BasicTypes / WTByteOrder.h
1 /*
2     Copyright (C) 2014 Waves Audio Ltd.
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #if !defined(__WTByteOrder_h__)
21 #define __WTByteOrder_h__
22
23 /* Copy to include
24 #include "BasicTypes/WTByteOrder.h"
25 */
26
27 #include "WavesPublicAPI/wstdint.h"
28 #include "BasicTypes/WUDefines.h"
29
30 // Stuff concerning little/big endian and the conversion between them.
31 // most of the code here was copied from NetShell with some modifications
32 // Written by Udi on Nov-2005
33 // Adjusted to Cross platform by Shai Mar-2006
34
35 // Macros to determine endian.  __BIG_ENDIAN__ & __LITTLE_ENDIAN__ should come from the compiler.
36 // We try to set the macro _BYTEORDER_BIG_ENDIAN to 1 if big-endian or to 0 if little-endian.
37
38 // if the compiler properly has set either __BIG_ENDIAN__ or __LITTLE_ENDIAN__
39 #if defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)
40 #if defined(__BIG_ENDIAN__) && defined(__LITTLE_ENDIAN__) //if both defined, check them as booleans
41 #if __BIG_ENDIAN__ && !__LITTLE_ENDIAN__
42 #define _BYTEORDER_BIG_ENDIAN 1
43 #elif !__BIG_ENDIAN__ && __LITTLE_ENDIAN__
44 #define _BYTEORDER_BIG_ENDIAN 0
45 #else
46 #error I am confused. Is this big-endian or little-endian?
47 #endif  // stupid compiler defines both __LITTLE_ENDIAN__ and __BIG_ENDIAN__
48 #elif defined(__BIG_ENDIAN__)
49 #define _BYTEORDER_BIG_ENDIAN 1
50 #else
51 #define _BYTEORDER_BIG_ENDIAN 0
52 #endif // big/little switch
53 #else // if the compiler proparly has NOT set either __BIG_ENDIAN__ or __LITTLE_ENDIAN__
54 // http://msdn.microsoft.com/en-us/library/b0084kay.aspx for all preprocessor defs. _M_X64: 64 bit. _M_IA64: Itanium 64bit
55 #if defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(__INTEL__) || defined(__x86_64__) || defined(_M_X64) || defined(_M_IA64)
56 #define _BYTEORDER_BIG_ENDIAN 0
57 #elif defined(_M_PPC) || defined(__POWERPC__ ) || defined(__ppc__)
58 #define _BYTEORDER_BIG_ENDIAN 1
59 #else
60 #error Cannot detect compiler byte-order. Please add a test for your compiler appropriate symbol to this header file.
61 #endif // symbol search
62 #endif // standard preprocessor symbol found
63
64 // code to determine which assembly code we can use
65 #if defined(_MSC_VER) && defined(_M_IX86)
66 #define _BYTEORDER_ASM_MSVC_I386  1  // Windows
67 #elif defined(__GNUC__) && defined(__i386__)
68 #define _BYTEORDER_ASM_GNUC_I386  1  // Linux, or MacOS with MacIntel on Xcode
69 #define _BYTEORDER_ASM_NONE               1      // Currently we have no assebley for GNU i386, so use the C version
70 #elif defined(__GNUC__) && defined(__POWERPC__)
71 #define _BYTEORDER_ASM_GNUC_PPC   1  // MacOS with PPC on Xcode
72 #define _BYTEORDER_ASM_NONE               1      // Currently we have no assebley for GNU PPC, so use the C version
73 #else
74 #define _BYTEORDER_ASM_NONE       1  // don't know the compiler and processor, use C implementation
75 #endif
76
77 namespace wvNS {
78         
79 namespace wvBO // namespace Waves::ByteOrder
80 {
81     typedef int         byte_order_type;   // we use int rather than enum because some compilers cannot resolve enum constants at compile-time. There are only two options anyway :-)
82     static const        byte_order_type byte_order_little_endian = 0;
83     static const        byte_order_type byte_order_big_endian    = 1;
84
85
86     // We try to use this static const rather than preprocessor symbols in our code wherever possible.
87 #if _BYTEORDER_BIG_ENDIAN == 1
88     static const        byte_order_type compiler_byte_order = byte_order_big_endian;
89 #else
90     static const        byte_order_type compiler_byte_order = byte_order_little_endian;
91 #endif
92
93
94     //---------------------------------------------------------------------------------
95     // swap functions - best if implemented in inline assembly code
96     // The following are very slow swappers when compiled, do not use in loops
97 #if _BYTEORDER_ASM_MSVC_I386
98
99     // assembly implementation for Intel386 on Visual Studio
100     inline uint16_t swap16(uint16_t x)
101     {
102         __asm MOV AX,x;
103         __asm XCHG AL,AH;
104         __asm MOV x,AX;
105         return x;
106     }
107
108     inline uint32_t swap32(uint32_t x)
109     {
110         __asm MOV EAX,x;
111         __asm BSWAP EAX;
112         __asm MOV x,EAX;
113         return x;
114     }
115     inline uint64_t swap64(uint64_t x)  // TODO: To be replaced
116     {
117         return
118             ((x>>7*8)&0xFF)<<0*8 | ((x>>6*8)&0xFF)<<1*8 | ((x>>5*8)&0xFF)<<2*8 | ((x>>4*8)&0xFF)<<3*8 |
119             ((x>>3*8)&0xFF)<<4*8 | ((x>>2*8)&0xFF)<<5*8 | ((x>>1*8)&0xFF)<<6*8 | ((x>>0*8)&0xFF)<<7*8 ;
120     }
121
122     /* the ASM code for swap64 does not compile
123     inline uint64_t swap64(uint64_t x)
124     {
125     __asm MOV EBX, OFFSET x;
126     __asm MOV EAX, [EBX];
127     __asm MOV EDX, [EBX+4];
128     __asm BSWAP EAX;
129     __asm BSWAP EDX;
130     __asm MOV [EBX],EDX;
131     __asm MOV [EBX+4],EAX;
132     return x;
133     }
134     */
135 #endif // _BYTEORDER_ASM_MSVC_I386
136
137 #if _BYTEORDER_ASM_GNUC_I386
138     // assembly implementation for Intel386 on GCC (Linux)
139     // TODO
140 #endif // _BYTEORDER_ASM_GNUC_I386
141
142 #if _BYTEORDER_ASM_GNUC_PPC
143     // assembly implementation for PowerPC on GCC (XCode)
144     // TODO
145 #endif // _BYTEORDER_ASM_GNUC_PPC
146
147 #if _BYTEORDER_ASM_NONE
148     inline uint16_t swap16(uint16_t x) { return (x>>8) | ((x&0xFF)<<8); }
149     inline uint32_t swap32(uint32_t x) { return (x&0xFF)<<24 | (x&0xFF00)<<8 | (x&0xFF0000)>>8 | (x&0xFF000000)>>24; }
150     inline uint64_t swap64(uint64_t x)
151     {
152         return
153             ((x>>7*8)&0xFF)<<0*8 | ((x>>6*8)&0xFF)<<1*8 | ((x>>5*8)&0xFF)<<2*8 | ((x>>4*8)&0xFF)<<3*8 |
154             ((x>>3*8)&0xFF)<<4*8 | ((x>>2*8)&0xFF)<<5*8 | ((x>>1*8)&0xFF)<<6*8 | ((x>>0*8)&0xFF)<<7*8 ;
155     }
156 #endif // _BYTEORDER_ASM_NONE
157
158
159
160
161     //---------------------------------------------------------------------------------
162
163     // order conversion functions
164     //    may want to overload for float and double as well.
165     //    overload for signed ints is ambiguous and should be done only if no other choice exists.
166     // - - - - - - - - - - - - - - - - - - - -
167     inline uint16_t compiler_to_big_16(uint16_t x)
168     {
169         return compiler_byte_order==byte_order_big_endian ? x : swap16(x);
170     }
171     inline uint16_t big_to_compiler_16(uint16_t x)
172     {
173         return compiler_byte_order==byte_order_big_endian ? x : swap16(x);
174     }
175     inline uint16_t compiler_to_little_16(uint16_t x)
176     {
177         return compiler_byte_order==byte_order_little_endian ? x : swap16(x);
178     }
179     inline uint16_t little_to_compiler_16(uint16_t x)
180     {
181         return compiler_byte_order==byte_order_little_endian ? x : swap16(x);
182     }
183     // - - - - - - - - - - - - - - - - - - - -
184     inline uint32_t compiler_to_big_32(uint32_t x)
185     {
186         return compiler_byte_order==byte_order_big_endian ? x : swap32(x);
187     }
188     inline uint32_t big_to_compiler_32(uint32_t x)
189     {
190         return compiler_byte_order==byte_order_big_endian ? x : swap32(x);
191     }
192     inline uint32_t compiler_to_little_32(uint32_t x)
193     {
194         return compiler_byte_order==byte_order_little_endian ? x : swap32(x);
195     }
196     inline uint32_t little_to_compiler_32(uint32_t x)
197     {
198         return compiler_byte_order==byte_order_little_endian ? x : swap32(x);
199     }
200     // - - - - - - - - - - - - - - - - - - - -
201     inline uint64_t compiler_to_big_64(uint64_t x)
202     {
203         return compiler_byte_order==byte_order_big_endian ? x : swap64(x);
204     }
205     inline uint64_t big_to_compiler_64(uint64_t x)
206     {
207         return compiler_byte_order==byte_order_big_endian ? x : swap64(x);
208     }
209     inline uint64_t compiler_to_little_64(uint64_t x)
210     {
211         return compiler_byte_order==byte_order_little_endian ? x : swap64(x);
212     }
213     inline uint64_t little_to_compiler_64(uint64_t x)
214     {
215         return compiler_byte_order==byte_order_little_endian ? x : swap64(x);
216     }
217
218 } // namespace wvBO
219
220 } // namespace wvNS {
221
222 #endif // #if !defined(__WTByteOrder_h__)
223