1 //+--------------------------------------------------------------
2 //
3 //  For conditions of distribution and use, see copyright notice
4 //  in Flashpix.h
5 //
6 //  Copyright (c) 1999 Digital Imaging Group, Inc.
7 //
8 //  Contents:   Byte swapping functions.
9 //              These functions can swap all of the base types,
10 //              and some special cases.  There is always an
11 //              overloaded version which accepts a pointer to the
12 //              data, and performs a swap in place.  Where possible,
13 //              there is also an overload which returns the swapped
14 //              value without modifying the input.
15 //
16 //---------------------------------------------------------------
17 
18 #ifndef __BYTEORDER_HXX_
19 #define __BYTEORDER_HXX_
20 
21 #include <limits.h>
22 #include <assert.h>
23 //
24 // BYTE Byte-Swap
25 //
26 
27 // These exist so that you can call ByteSwap(OLECHAR) without
28 // knowning if OLECHAR is a CHAR or a WCHAR.
29 
ByteSwap(char b)30 inline BYTE ByteSwap( char b )
31 {
32     return(b);
33 }
34 
ByteSwap(char * pb)35 inline VOID ByteSwap( char *pb )
36 {
37     *pb = ByteSwap(*pb);
38 }
39 
40 //
41 // WORD Byte-Swap
42 //
43 
44 #ifndef LOBYTE
45 
46 #   define LOBYTE(a)  (unsigned char)((a) & ((unsigned)~0 >> sizeof(BYTE)*8 ))
47 #   define HIBYTE(a)  (unsigned char)((unsigned)(a) >> sizeof(BYTE)*8 )
48 
49 #   define LOWORD(a)  (WORD)( (a) & ( (WORD)~0 >> sizeof(WORD)*8 ))
50 #   define HIWORD(a)  (WORD)( (WORD)(a) >> sizeof(WORD)*8 )
51 
52 #   define LODWORD(a) (DWORD)( (a) & ( (DWORD)~0 >> sizeof(DWORD)*8 ))
53 #   define HIDWORD(a) (DWORD)( (DWORD)(a) >> sizeof(DWORD)*8 )
54 
55 #endif // #ifndef LOBYTE
56 
ByteSwap(WORD w)57 inline WORD ByteSwap( WORD w )
58 {
59     return( (USHORT) ( (LOBYTE(w) << 8 )
60                      |
61                      HIBYTE(w)) );
62 }
63 
ByteSwap(WORD * pw)64 inline VOID ByteSwap( WORD *pw )
65 {
66     *pw = ByteSwap(*pw);
67 }
68 
69 //
70 // DWORD Byte-Swap
71 //
72 
73 #define BYTE_MASK_A_C_  0xff00ff00
74 #define BYTE_MASK__B_D  0x00ff00ff
75 #define BYTE_MASK_AB__  0xffff0000
76 #define BYTE_MASK___CD  0x0000ffff
77 
ByteSwap(DWORD dwOriginal)78 inline DWORD ByteSwap( DWORD dwOriginal )
79 {
80     ULONG dwSwapped;
81 
82     // ABCD => BADC
83 
84     dwSwapped = (( (dwOriginal) & BYTE_MASK_A_C_ ) >> 8 )
85                 |
86                 (( (dwOriginal) & BYTE_MASK__B_D ) << 8 );
87 
88     // BADC => DCBA
89 
90     dwSwapped = (( dwSwapped & BYTE_MASK_AB__ ) >> 16 )
91                 |
92                 (( dwSwapped & BYTE_MASK___CD ) << 16 );
93 
94     return( dwSwapped );
95 }
96 
ByteSwap(DWORD * pdw)97 inline VOID ByteSwap( DWORD *pdw )
98 {
99     *pdw = ByteSwap(*pdw);
100 }
101 
102 
103 //
104 // LONGLONG Byte-Swap
105 //
106 
107 #ifndef _UNIX
108 // FIXME: portability
109 #define BYTE_MASK_A_C_E_G_  0xff00ff00ff00ff00
110 #define BYTE_MASK__B_D_F_H  0x00ff00ff00ff00ff
111 #define BYTE_MASK_AB__EF__  0xffff0000ffff0000
112 #define BYTE_MASK___CD__GH  0x0000ffff0000ffff
113 #define BYTE_MASK_ABCD____  0xffffffff00000000
114 #define BYTE_MASK_____EFGH  0x00000000ffffffff
115 #else                           //#ifndef GNUC
116 #define BYTE_MASK_A_C_E_G_  0xff00ff00ff00ff00LL
117 #define BYTE_MASK__B_D_F_H  0x00ff00ff00ff00ffLL
118 #define BYTE_MASK_AB__EF__  0xffff0000ffff0000LL
119 #define BYTE_MASK___CD__GH  0x0000ffff0000ffffLL
120 #define BYTE_MASK_ABCD____  0xffffffff00000000LL
121 #define BYTE_MASK_____EFGH  0x00000000ffffffffLL
122 #endif                          //#ifndef GNUC, else
123 
ByteSwap(LONGLONG llOriginal)124 inline LONGLONG ByteSwap( LONGLONG llOriginal )
125 {
126     LONGLONG llSwapped;
127 
128     // ABCDEFGH => BADCFEHG
129 
130     llSwapped = (( (llOriginal) & BYTE_MASK_A_C_E_G_ ) >> 8 )
131                 |
132                 (( (llOriginal) & BYTE_MASK__B_D_F_H ) << 8 );
133 
134     // BADCFEHG => DCBAHGFE
135 
136     llSwapped = (( llSwapped & BYTE_MASK_AB__EF__ ) >> 16 )
137                 |
138                 (( llSwapped & BYTE_MASK___CD__GH ) << 16 );
139 
140     // DCBAHGFE => HGFEDCBA
141 
142     llSwapped = (( llSwapped & BYTE_MASK_ABCD____ ) >> 32 )
143                 |
144                 (( llSwapped & BYTE_MASK_____EFGH ) << 32 );
145 
146     return( llSwapped );
147 }
148 
ByteSwap(LONGLONG * pll)149 inline VOID ByteSwap( LONGLONG *pll )
150 {
151     // we have to deal with two DWORDs instead of one LONG LONG
152     // because the pointer might not be 8 word aligned.
153     // (it should be DWORD (4 bytes) aligned though)
154 
155     assert( sizeof(LONGLONG) == 2 * sizeof (DWORD));
156 
157     DWORD *pdw = (DWORD*)pll;
158     DWORD dwTemp = ByteSwap( *pdw ); // temp = swapped(dw1)
159     ByteSwap( pdw+1 );               // swap dw2
160     *pdw = *(pdw+1);                 // dw1 = dw2(swapped)
161     *(pdw+1) = dwTemp;               // dw2 = temp
162     return;
163 }
164 
165 //
166 // GUID Byte-swap
167 //
168 
ByteSwap(GUID * pguid)169 inline VOID ByteSwap( GUID *pguid)
170 {
171     ByteSwap(&pguid->Data1);
172     ByteSwap(&pguid->Data2);
173     ByteSwap(&pguid->Data3);
174 }
175 
176 //
177 // FILETIME Byte-Swap
178 //
179 
180 // Note that we treat FILETIME as two DWORD's instead of
181 // a single 8 byte integer, in memory or in disk
182 // FILETIME should not be casted into a LONGLONG, or else
183 // it will fail on a Big Endian machine.
184 //
ByteSwap(FILETIME * pfileTime)185 inline VOID ByteSwap(FILETIME *pfileTime)
186 {
187     ByteSwap(&pfileTime->dwLowDateTime);
188     ByteSwap(&pfileTime->dwHighDateTime);
189 }
190 
191 
192 #endif  // !__BYTEORDER_HXX_
193 
194