rev |
line source |
nuclear@0
|
1 /*
|
nuclear@0
|
2 Open Asset Import Library (assimp)
|
nuclear@0
|
3 ----------------------------------------------------------------------
|
nuclear@0
|
4
|
nuclear@0
|
5 Copyright (c) 2006-2012, assimp team
|
nuclear@0
|
6 All rights reserved.
|
nuclear@0
|
7
|
nuclear@0
|
8 Redistribution and use of this software in source and binary forms,
|
nuclear@0
|
9 with or without modification, are permitted provided that the
|
nuclear@0
|
10 following conditions are met:
|
nuclear@0
|
11
|
nuclear@0
|
12 * Redistributions of source code must retain the above
|
nuclear@0
|
13 copyright notice, this list of conditions and the
|
nuclear@0
|
14 following disclaimer.
|
nuclear@0
|
15
|
nuclear@0
|
16 * Redistributions in binary form must reproduce the above
|
nuclear@0
|
17 copyright notice, this list of conditions and the
|
nuclear@0
|
18 following disclaimer in the documentation and/or other
|
nuclear@0
|
19 materials provided with the distribution.
|
nuclear@0
|
20
|
nuclear@0
|
21 * Neither the name of the assimp team, nor the names of its
|
nuclear@0
|
22 contributors may be used to endorse or promote products
|
nuclear@0
|
23 derived from this software without specific prior
|
nuclear@0
|
24 written permission of the assimp team.
|
nuclear@0
|
25
|
nuclear@0
|
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
nuclear@0
|
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
nuclear@0
|
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
nuclear@0
|
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
nuclear@0
|
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
nuclear@0
|
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
nuclear@0
|
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
nuclear@0
|
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
nuclear@0
|
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
nuclear@0
|
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
nuclear@0
|
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
nuclear@0
|
37
|
nuclear@0
|
38 ----------------------------------------------------------------------
|
nuclear@0
|
39 */
|
nuclear@0
|
40
|
nuclear@0
|
41 /** @file Helper class tp perform various byte oder swappings
|
nuclear@0
|
42 (e.g. little to big endian) */
|
nuclear@0
|
43 #ifndef AI_BYTESWAP_H_INC
|
nuclear@0
|
44 #define AI_BYTESWAP_H_INC
|
nuclear@0
|
45
|
nuclear@0
|
46 #include "assimp/ai_assert.h"
|
nuclear@0
|
47 #include "assimp/types.h"
|
nuclear@0
|
48
|
nuclear@0
|
49 #if _MSC_VER >= 1400
|
nuclear@0
|
50 #include <stdlib.h>
|
nuclear@0
|
51 #endif
|
nuclear@0
|
52
|
nuclear@0
|
53 namespace Assimp {
|
nuclear@0
|
54 // --------------------------------------------------------------------------------------
|
nuclear@0
|
55 /** Defines some useful byte order swap routines.
|
nuclear@0
|
56 *
|
nuclear@0
|
57 * This is required to read big-endian model formats on little-endian machines,
|
nuclear@0
|
58 * and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
|
nuclear@0
|
59 // --------------------------------------------------------------------------------------
|
nuclear@0
|
60 class ByteSwap
|
nuclear@0
|
61 {
|
nuclear@0
|
62 ByteSwap() {}
|
nuclear@0
|
63
|
nuclear@0
|
64 public:
|
nuclear@0
|
65
|
nuclear@0
|
66 // ----------------------------------------------------------------------
|
nuclear@0
|
67 /** Swap two bytes of data
|
nuclear@0
|
68 * @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
nuclear@0
|
69 static inline void Swap2(void* _szOut)
|
nuclear@0
|
70 {
|
nuclear@0
|
71 ai_assert(_szOut);
|
nuclear@0
|
72
|
nuclear@0
|
73 #if _MSC_VER >= 1400
|
nuclear@0
|
74 uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
|
nuclear@0
|
75 *szOut = _byteswap_ushort(*szOut);
|
nuclear@0
|
76 #else
|
nuclear@0
|
77 uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
nuclear@0
|
78 std::swap(szOut[0],szOut[1]);
|
nuclear@0
|
79 #endif
|
nuclear@0
|
80 }
|
nuclear@0
|
81
|
nuclear@0
|
82 // ----------------------------------------------------------------------
|
nuclear@0
|
83 /** Swap four bytes of data
|
nuclear@0
|
84 * @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
nuclear@0
|
85 static inline void Swap4(void* _szOut)
|
nuclear@0
|
86 {
|
nuclear@0
|
87 ai_assert(_szOut);
|
nuclear@0
|
88
|
nuclear@0
|
89 #if _MSC_VER >= 1400
|
nuclear@0
|
90 uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
|
nuclear@0
|
91 *szOut = _byteswap_ulong(*szOut);
|
nuclear@0
|
92 #else
|
nuclear@0
|
93 uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
nuclear@0
|
94 std::swap(szOut[0],szOut[3]);
|
nuclear@0
|
95 std::swap(szOut[1],szOut[2]);
|
nuclear@0
|
96 #endif
|
nuclear@0
|
97 }
|
nuclear@0
|
98
|
nuclear@0
|
99 // ----------------------------------------------------------------------
|
nuclear@0
|
100 /** Swap eight bytes of data
|
nuclear@0
|
101 * @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
nuclear@0
|
102 static inline void Swap8(void* _szOut)
|
nuclear@0
|
103 {
|
nuclear@0
|
104 ai_assert(_szOut);
|
nuclear@0
|
105
|
nuclear@0
|
106 #if _MSC_VER >= 1400
|
nuclear@0
|
107 uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
|
nuclear@0
|
108 *szOut = _byteswap_uint64(*szOut);
|
nuclear@0
|
109 #else
|
nuclear@0
|
110 uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
nuclear@0
|
111 std::swap(szOut[0],szOut[7]);
|
nuclear@0
|
112 std::swap(szOut[1],szOut[6]);
|
nuclear@0
|
113 std::swap(szOut[2],szOut[5]);
|
nuclear@0
|
114 std::swap(szOut[3],szOut[4]);
|
nuclear@0
|
115 #endif
|
nuclear@0
|
116 }
|
nuclear@0
|
117
|
nuclear@0
|
118 // ----------------------------------------------------------------------
|
nuclear@0
|
119 /** ByteSwap a float. Not a joke.
|
nuclear@0
|
120 * @param[inout] fOut ehm. .. */
|
nuclear@0
|
121 static inline void Swap(float* fOut) {
|
nuclear@0
|
122 Swap4(fOut);
|
nuclear@0
|
123 }
|
nuclear@0
|
124
|
nuclear@0
|
125 // ----------------------------------------------------------------------
|
nuclear@0
|
126 /** ByteSwap a double. Not a joke.
|
nuclear@0
|
127 * @param[inout] fOut ehm. .. */
|
nuclear@0
|
128 static inline void Swap(double* fOut) {
|
nuclear@0
|
129 Swap8(fOut);
|
nuclear@0
|
130 }
|
nuclear@0
|
131
|
nuclear@0
|
132
|
nuclear@0
|
133 // ----------------------------------------------------------------------
|
nuclear@0
|
134 /** ByteSwap an int16t. Not a joke.
|
nuclear@0
|
135 * @param[inout] fOut ehm. .. */
|
nuclear@0
|
136 static inline void Swap(int16_t* fOut) {
|
nuclear@0
|
137 Swap2(fOut);
|
nuclear@0
|
138 }
|
nuclear@0
|
139
|
nuclear@0
|
140 static inline void Swap(uint16_t* fOut) {
|
nuclear@0
|
141 Swap2(fOut);
|
nuclear@0
|
142 }
|
nuclear@0
|
143
|
nuclear@0
|
144 // ----------------------------------------------------------------------
|
nuclear@0
|
145 /** ByteSwap an int32t. Not a joke.
|
nuclear@0
|
146 * @param[inout] fOut ehm. .. */
|
nuclear@0
|
147 static inline void Swap(int32_t* fOut){
|
nuclear@0
|
148 Swap4(fOut);
|
nuclear@0
|
149 }
|
nuclear@0
|
150
|
nuclear@0
|
151 static inline void Swap(uint32_t* fOut){
|
nuclear@0
|
152 Swap4(fOut);
|
nuclear@0
|
153 }
|
nuclear@0
|
154
|
nuclear@0
|
155 // ----------------------------------------------------------------------
|
nuclear@0
|
156 /** ByteSwap an int64t. Not a joke.
|
nuclear@0
|
157 * @param[inout] fOut ehm. .. */
|
nuclear@0
|
158 static inline void Swap(int64_t* fOut) {
|
nuclear@0
|
159 Swap8(fOut);
|
nuclear@0
|
160 }
|
nuclear@0
|
161
|
nuclear@0
|
162 static inline void Swap(uint64_t* fOut) {
|
nuclear@0
|
163 Swap8(fOut);
|
nuclear@0
|
164 }
|
nuclear@0
|
165
|
nuclear@0
|
166 // ----------------------------------------------------------------------
|
nuclear@0
|
167 //! Templatized ByteSwap
|
nuclear@0
|
168 //! \returns param tOut as swapped
|
nuclear@0
|
169 template<typename Type>
|
nuclear@0
|
170 static inline Type Swapped(Type tOut)
|
nuclear@0
|
171 {
|
nuclear@0
|
172 return _swapper<Type,sizeof(Type)>()(tOut);
|
nuclear@0
|
173 }
|
nuclear@0
|
174
|
nuclear@0
|
175 private:
|
nuclear@0
|
176
|
nuclear@0
|
177 template <typename T, size_t size> struct _swapper;
|
nuclear@0
|
178 };
|
nuclear@0
|
179
|
nuclear@0
|
180 template <typename T> struct ByteSwap::_swapper<T,2> {
|
nuclear@0
|
181 T operator() (T tOut) {
|
nuclear@0
|
182 Swap2(&tOut);
|
nuclear@0
|
183 return tOut;
|
nuclear@0
|
184 }
|
nuclear@0
|
185 };
|
nuclear@0
|
186
|
nuclear@0
|
187 template <typename T> struct ByteSwap::_swapper<T,4> {
|
nuclear@0
|
188 T operator() (T tOut) {
|
nuclear@0
|
189 Swap4(&tOut);
|
nuclear@0
|
190 return tOut;
|
nuclear@0
|
191 }
|
nuclear@0
|
192 };
|
nuclear@0
|
193
|
nuclear@0
|
194 template <typename T> struct ByteSwap::_swapper<T,8> {
|
nuclear@0
|
195 T operator() (T tOut) {
|
nuclear@0
|
196 Swap8(&tOut);
|
nuclear@0
|
197 return tOut;
|
nuclear@0
|
198 }
|
nuclear@0
|
199 };
|
nuclear@0
|
200
|
nuclear@0
|
201
|
nuclear@0
|
202 // --------------------------------------------------------------------------------------
|
nuclear@0
|
203 // ByteSwap macros for BigEndian/LittleEndian support
|
nuclear@0
|
204 // --------------------------------------------------------------------------------------
|
nuclear@0
|
205 #if (defined AI_BUILD_BIG_ENDIAN)
|
nuclear@0
|
206 # define AI_LE(t) (t)
|
nuclear@0
|
207 # define AI_BE(t) ByteSwap::Swapped(t)
|
nuclear@0
|
208 # define AI_LSWAP2(p)
|
nuclear@0
|
209 # define AI_LSWAP4(p)
|
nuclear@0
|
210 # define AI_LSWAP8(p)
|
nuclear@0
|
211 # define AI_LSWAP2P(p)
|
nuclear@0
|
212 # define AI_LSWAP4P(p)
|
nuclear@0
|
213 # define AI_LSWAP8P(p)
|
nuclear@0
|
214 # define LE_NCONST const
|
nuclear@0
|
215 # define AI_SWAP2(p) ByteSwap::Swap2(&(p))
|
nuclear@0
|
216 # define AI_SWAP4(p) ByteSwap::Swap4(&(p))
|
nuclear@0
|
217 # define AI_SWAP8(p) ByteSwap::Swap8(&(p))
|
nuclear@0
|
218 # define AI_SWAP2P(p) ByteSwap::Swap2((p))
|
nuclear@0
|
219 # define AI_SWAP4P(p) ByteSwap::Swap4((p))
|
nuclear@0
|
220 # define AI_SWAP8P(p) ByteSwap::Swap8((p))
|
nuclear@0
|
221 # define BE_NCONST
|
nuclear@0
|
222 #else
|
nuclear@0
|
223 # define AI_BE(t) (t)
|
nuclear@0
|
224 # define AI_LE(t) ByteSwap::Swapped(t)
|
nuclear@0
|
225 # define AI_SWAP2(p)
|
nuclear@0
|
226 # define AI_SWAP4(p)
|
nuclear@0
|
227 # define AI_SWAP8(p)
|
nuclear@0
|
228 # define AI_SWAP2P(p)
|
nuclear@0
|
229 # define AI_SWAP4P(p)
|
nuclear@0
|
230 # define AI_SWAP8P(p)
|
nuclear@0
|
231 # define BE_NCONST const
|
nuclear@0
|
232 # define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
|
nuclear@0
|
233 # define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
|
nuclear@0
|
234 # define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
|
nuclear@0
|
235 # define AI_LSWAP2P(p) ByteSwap::Swap2((p))
|
nuclear@0
|
236 # define AI_LSWAP4P(p) ByteSwap::Swap4((p))
|
nuclear@0
|
237 # define AI_LSWAP8P(p) ByteSwap::Swap8((p))
|
nuclear@0
|
238 # define LE_NCONST
|
nuclear@0
|
239 #endif
|
nuclear@0
|
240
|
nuclear@0
|
241
|
nuclear@0
|
242 namespace Intern {
|
nuclear@0
|
243
|
nuclear@0
|
244 // --------------------------------------------------------------------------------------------
|
nuclear@0
|
245 template <typename T, bool doit>
|
nuclear@0
|
246 struct ByteSwapper {
|
nuclear@0
|
247 void operator() (T* inout) {
|
nuclear@0
|
248 ByteSwap::Swap(inout);
|
nuclear@0
|
249 }
|
nuclear@0
|
250 };
|
nuclear@0
|
251
|
nuclear@0
|
252 template <typename T>
|
nuclear@0
|
253 struct ByteSwapper<T,false> {
|
nuclear@0
|
254 void operator() (T*) {
|
nuclear@0
|
255 }
|
nuclear@0
|
256 };
|
nuclear@0
|
257
|
nuclear@0
|
258 // --------------------------------------------------------------------------------------------
|
nuclear@0
|
259 template <bool SwapEndianess, typename T, bool RuntimeSwitch>
|
nuclear@0
|
260 struct Getter {
|
nuclear@0
|
261 void operator() (T* inout, bool le) {
|
nuclear@0
|
262 #ifdef AI_BUILD_BIG_ENDIAN
|
nuclear@0
|
263 le = le;
|
nuclear@0
|
264 #else
|
nuclear@0
|
265 le = !le;
|
nuclear@0
|
266 #endif
|
nuclear@0
|
267 if (le) {
|
nuclear@0
|
268 ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
|
nuclear@0
|
269 }
|
nuclear@0
|
270 else ByteSwapper<T,false> () (inout);
|
nuclear@0
|
271 }
|
nuclear@0
|
272 };
|
nuclear@0
|
273
|
nuclear@0
|
274 template <bool SwapEndianess, typename T>
|
nuclear@0
|
275 struct Getter<SwapEndianess,T,false> {
|
nuclear@0
|
276
|
nuclear@0
|
277 void operator() (T* inout, bool /*le*/) {
|
nuclear@0
|
278 // static branch
|
nuclear@0
|
279 ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
|
nuclear@0
|
280 }
|
nuclear@0
|
281 };
|
nuclear@0
|
282 } // end Intern
|
nuclear@0
|
283 } // end Assimp
|
nuclear@0
|
284
|
nuclear@0
|
285 #endif //!! AI_BYTESWAP_H_INC
|