1/*
2 * Copyright (c) 2014 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24/*	CFByteOrder.h
25	Copyright (c) 1995-2013, Apple Inc. All rights reserved.
26*/
27
28#if !defined(__COREFOUNDATION_CFBYTEORDER__)
29#define __COREFOUNDATION_CFBYTEORDER__ 1
30
31#include <CoreFoundation/CFBase.h>
32#if ((TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) && !defined(CF_USE_OSBYTEORDER_H)
33#include <libkern/OSByteOrder.h>
34#define CF_USE_OSBYTEORDER_H 1
35#endif
36
37CF_EXTERN_C_BEGIN
38
39enum __CFByteOrder {
40    CFByteOrderUnknown,
41    CFByteOrderLittleEndian,
42    CFByteOrderBigEndian
43};
44typedef CFIndex CFByteOrder;
45
46CF_INLINE CFByteOrder CFByteOrderGetCurrent(void) {
47#if CF_USE_OSBYTEORDER_H
48    int32_t byteOrder = OSHostByteOrder();
49    switch (byteOrder) {
50    case OSLittleEndian: return CFByteOrderLittleEndian;
51    case OSBigEndian: return CFByteOrderBigEndian;
52    default: break;
53    }
54    return CFByteOrderUnknown;
55#else
56#if __LITTLE_ENDIAN__
57    return CFByteOrderLittleEndian;
58#elif __BIG_ENDIAN__
59    return CFByteOrderBigEndian;
60#else
61    return CFByteOrderUnknown;
62#endif
63#endif
64}
65
66CF_INLINE uint16_t CFSwapInt16(uint16_t arg) {
67#if CF_USE_OSBYTEORDER_H
68    return OSSwapInt16(arg);
69#else
70    uint16_t result;
71    result = (uint16_t)(((arg << 8) & 0xFF00) | ((arg >> 8) & 0xFF));
72    return result;
73#endif
74}
75
76CF_INLINE uint32_t CFSwapInt32(uint32_t arg) {
77#if CF_USE_OSBYTEORDER_H
78    return OSSwapInt32(arg);
79#else
80    uint32_t result;
81    result = ((arg & 0xFF) << 24) | ((arg & 0xFF00) << 8) | ((arg >> 8) & 0xFF00) | ((arg >> 24) & 0xFF);
82    return result;
83#endif
84}
85
86CF_INLINE uint64_t CFSwapInt64(uint64_t arg) {
87#if CF_USE_OSBYTEORDER_H
88    return OSSwapInt64(arg);
89#else
90    union CFSwap {
91        uint64_t sv;
92        uint32_t ul[2];
93    } tmp, result;
94    tmp.sv = arg;
95    result.ul[0] = CFSwapInt32(tmp.ul[1]);
96    result.ul[1] = CFSwapInt32(tmp.ul[0]);
97    return result.sv;
98#endif
99}
100
101CF_INLINE uint16_t CFSwapInt16BigToHost(uint16_t arg) {
102#if CF_USE_OSBYTEORDER_H
103    return OSSwapBigToHostInt16(arg);
104#elif __BIG_ENDIAN__
105    return arg;
106#else
107    return CFSwapInt16(arg);
108#endif
109}
110
111CF_INLINE uint32_t CFSwapInt32BigToHost(uint32_t arg) {
112#if CF_USE_OSBYTEORDER_H
113    return OSSwapBigToHostInt32(arg);
114#elif __BIG_ENDIAN__
115    return arg;
116#else
117    return CFSwapInt32(arg);
118#endif
119}
120
121CF_INLINE uint64_t CFSwapInt64BigToHost(uint64_t arg) {
122#if CF_USE_OSBYTEORDER_H
123    return OSSwapBigToHostInt64(arg);
124#elif __BIG_ENDIAN__
125    return arg;
126#else
127    return CFSwapInt64(arg);
128#endif
129}
130
131CF_INLINE uint16_t CFSwapInt16HostToBig(uint16_t arg) {
132#if CF_USE_OSBYTEORDER_H
133    return OSSwapHostToBigInt16(arg);
134#elif __BIG_ENDIAN__
135    return arg;
136#else
137    return CFSwapInt16(arg);
138#endif
139}
140
141CF_INLINE uint32_t CFSwapInt32HostToBig(uint32_t arg) {
142#if CF_USE_OSBYTEORDER_H
143    return OSSwapHostToBigInt32(arg);
144#elif __BIG_ENDIAN__
145    return arg;
146#else
147    return CFSwapInt32(arg);
148#endif
149}
150
151CF_INLINE uint64_t CFSwapInt64HostToBig(uint64_t arg) {
152#if CF_USE_OSBYTEORDER_H
153    return OSSwapHostToBigInt64(arg);
154#elif __BIG_ENDIAN__
155    return arg;
156#else
157    return CFSwapInt64(arg);
158#endif
159}
160
161CF_INLINE uint16_t CFSwapInt16LittleToHost(uint16_t arg) {
162#if CF_USE_OSBYTEORDER_H
163    return OSSwapLittleToHostInt16(arg);
164#elif __LITTLE_ENDIAN__
165    return arg;
166#else
167    return CFSwapInt16(arg);
168#endif
169}
170
171CF_INLINE uint32_t CFSwapInt32LittleToHost(uint32_t arg) {
172#if CF_USE_OSBYTEORDER_H
173    return OSSwapLittleToHostInt32(arg);
174#elif __LITTLE_ENDIAN__
175    return arg;
176#else
177    return CFSwapInt32(arg);
178#endif
179}
180
181CF_INLINE uint64_t CFSwapInt64LittleToHost(uint64_t arg) {
182#if CF_USE_OSBYTEORDER_H
183    return OSSwapLittleToHostInt64(arg);
184#elif __LITTLE_ENDIAN__
185    return arg;
186#else
187    return CFSwapInt64(arg);
188#endif
189}
190
191CF_INLINE uint16_t CFSwapInt16HostToLittle(uint16_t arg) {
192#if CF_USE_OSBYTEORDER_H
193    return OSSwapHostToLittleInt16(arg);
194#elif __LITTLE_ENDIAN__
195    return arg;
196#else
197    return CFSwapInt16(arg);
198#endif
199}
200
201CF_INLINE uint32_t CFSwapInt32HostToLittle(uint32_t arg) {
202#if CF_USE_OSBYTEORDER_H
203    return OSSwapHostToLittleInt32(arg);
204#elif __LITTLE_ENDIAN__
205    return arg;
206#else
207    return CFSwapInt32(arg);
208#endif
209}
210
211CF_INLINE uint64_t CFSwapInt64HostToLittle(uint64_t arg) {
212#if CF_USE_OSBYTEORDER_H
213    return OSSwapHostToLittleInt64(arg);
214#elif __LITTLE_ENDIAN__
215    return arg;
216#else
217    return CFSwapInt64(arg);
218#endif
219}
220
221typedef struct {uint32_t v;} CFSwappedFloat32;
222typedef struct {uint64_t v;} CFSwappedFloat64;
223
224CF_INLINE CFSwappedFloat32 CFConvertFloat32HostToSwapped(Float32 arg) {
225    union CFSwap {
226	Float32 v;
227	CFSwappedFloat32 sv;
228    } result;
229    result.v = arg;
230#if __LITTLE_ENDIAN__
231    result.sv.v = CFSwapInt32(result.sv.v);
232#endif
233    return result.sv;
234}
235
236CF_INLINE Float32 CFConvertFloat32SwappedToHost(CFSwappedFloat32 arg) {
237    union CFSwap {
238	Float32 v;
239	CFSwappedFloat32 sv;
240    } result;
241    result.sv = arg;
242#if __LITTLE_ENDIAN__
243    result.sv.v = CFSwapInt32(result.sv.v);
244#endif
245    return result.v;
246}
247
248CF_INLINE CFSwappedFloat64 CFConvertFloat64HostToSwapped(Float64 arg) {
249    union CFSwap {
250	Float64 v;
251	CFSwappedFloat64 sv;
252    } result;
253    result.v = arg;
254#if __LITTLE_ENDIAN__
255    result.sv.v = CFSwapInt64(result.sv.v);
256#endif
257    return result.sv;
258}
259
260CF_INLINE Float64 CFConvertFloat64SwappedToHost(CFSwappedFloat64 arg) {
261    union CFSwap {
262	Float64 v;
263	CFSwappedFloat64 sv;
264    } result;
265    result.sv = arg;
266#if __LITTLE_ENDIAN__
267    result.sv.v = CFSwapInt64(result.sv.v);
268#endif
269    return result.v;
270}
271
272CF_INLINE CFSwappedFloat32 CFConvertFloatHostToSwapped(float arg) {
273    union CFSwap {
274	float v;
275	CFSwappedFloat32 sv;
276    } result;
277    result.v = arg;
278#if __LITTLE_ENDIAN__
279    result.sv.v = CFSwapInt32(result.sv.v);
280#endif
281    return result.sv;
282}
283
284CF_INLINE float CFConvertFloatSwappedToHost(CFSwappedFloat32 arg) {
285    union CFSwap {
286	float v;
287	CFSwappedFloat32 sv;
288    } result;
289    result.sv = arg;
290#if __LITTLE_ENDIAN__
291    result.sv.v = CFSwapInt32(result.sv.v);
292#endif
293    return result.v;
294}
295
296CF_INLINE CFSwappedFloat64 CFConvertDoubleHostToSwapped(double arg) {
297    union CFSwap {
298	double v;
299	CFSwappedFloat64 sv;
300    } result;
301    result.v = arg;
302#if __LITTLE_ENDIAN__
303    result.sv.v = CFSwapInt64(result.sv.v);
304#endif
305    return result.sv;
306}
307
308CF_INLINE double CFConvertDoubleSwappedToHost(CFSwappedFloat64 arg) {
309    union CFSwap {
310	double v;
311	CFSwappedFloat64 sv;
312    } result;
313    result.sv = arg;
314#if __LITTLE_ENDIAN__
315    result.sv.v = CFSwapInt64(result.sv.v);
316#endif
317    return result.v;
318}
319
320CF_EXTERN_C_END
321
322#endif /* ! __COREFOUNDATION_CFBYTEORDER__ */
323
324