1 /* EINA - EFL data type library
2  * Copyright (C) 2013 Cedric Bail
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library 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 GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library;
16  * if not, see <http://www.gnu.org/licenses/>.
17  */
18 /*
19  * This code has been partially inspired by :
20  *  - http://create.stephan-brumme.com/crc32/
21  */
22 
23 #ifndef EINA_INLINE_CPU_X_
24 #define EINA_INLINE_CPU_X_
25 
26 #ifdef __has_builtin
27 # define EINA_HAS_BUILTIN(x) __has_builtin(x)
28 #elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
29 # define EINA_HAS_BUILTIN(x) 1
30 #else
31 # define EINA_HAS_BUILTIN(x) 0  // Compatibility for the rest of the world
32 #endif
33 
34 #ifdef EINA_HAVE_BYTESWAP_H
35 # include <byteswap.h>
36 #endif
37 
38 static inline unsigned short
eina_swap16(unsigned short x)39 eina_swap16(unsigned short x)
40 {
41 #if EINA_HAS_BUILTIN(__builtin_bswap16)
42   return __builtin_bswap16(x);
43 #elif defined _MSC_VER          /* Windows. Apparently in <stdlib.h>. */
44   return _byteswap_ushort(x);
45 #elif defined EINA_HAVE_BYTESWAP_H
46   return bswap_16(x);
47 #else
48   return (((x & 0xff00) >> 8) |
49           ((x & 0x00ff) << 8));
50 #endif
51 }
52 
53 static inline unsigned int
eina_swap32(unsigned int x)54 eina_swap32(unsigned int x)
55 {
56 #if EINA_HAS_BUILTIN(__builtin_bswap32)
57   return __builtin_bswap32(x);
58 #elif defined _MSC_VER          /* Windows. Apparently in <stdlib.h>. */
59   return _byteswap_ulong(x);
60 #elif defined EINA_HAVE_BYTESWAP_H
61   return bswap_32(x);
62 #else
63   return (x >> 24) |
64         ((x >>  8) & 0x0000FF00) |
65         ((x <<  8) & 0x00FF0000) |
66          (x << 24);
67 #endif
68 }
69 
70 static inline unsigned long long
eina_swap64(unsigned long long x)71 eina_swap64(unsigned long long x)
72 {
73 #if EINA_HAS_BUILTIN(__builtin_bswap64)
74   return __builtin_bswap64(x);
75 #elif defined _MSC_VER          /* Windows. Apparently in <stdlib.h>. */
76   return _byteswap_uint64(x);
77 #elif defined EINA_HAVE_BYTESWAP_H
78   return bswap_64(x);
79 #else
80   return (((x & 0xff00000000000000ull) >> 56) |
81           ((x & 0x00ff000000000000ull) >> 40) |
82           ((x & 0x0000ff0000000000ull) >> 24) |
83           ((x & 0x000000ff00000000ull) >> 8)  |
84           ((x & 0x00000000ff000000ull) << 8)  |
85           ((x & 0x0000000000ff0000ull) << 24) |
86           ((x & 0x000000000000ff00ull) << 40) |
87           ((x & 0x00000000000000ffull) << 56));
88 #endif
89 }
90 
91 static inline unsigned short
eina_htons(unsigned short host)92 eina_htons(unsigned short host)
93 {
94 #ifdef EINA_HAVE_WORDS_BIGENDIAN
95    return host;
96 #else
97    return eina_swap16(host);
98 #endif
99 }
100 
101 static inline unsigned int
eina_htonl(unsigned int host)102 eina_htonl(unsigned int host)
103 {
104 #ifdef EINA_HAVE_WORDS_BIGENDIAN
105    return host;
106 #else
107    return eina_swap32(host);
108 #endif
109 }
110 
111 static inline unsigned long long
eina_htonll(unsigned long long host)112 eina_htonll(unsigned long long host)
113 {
114 #ifdef EINA_HAVE_WORDS_BIGENDIAN
115    return host;
116 #else
117    return eina_swap64(host);
118 #endif
119 }
120 
121 static inline unsigned short
eina_ntohs(unsigned short net)122 eina_ntohs(unsigned short net)
123 {
124 #ifdef EINA_HAVE_WORDS_BIGENDIAN
125    return net;
126 #else
127    return eina_swap16(net);
128 #endif
129 }
130 
131 static inline unsigned int
eina_ntohl(unsigned int net)132 eina_ntohl(unsigned int net)
133 {
134 #ifdef EINA_HAVE_WORDS_BIGENDIAN
135    return net;
136 #else
137    return eina_swap32(net);
138 #endif
139 }
140 
141 static inline unsigned long long
eina_ntohll(unsigned long long net)142 eina_ntohll(unsigned long long net)
143 {
144 #ifdef EINA_HAVE_WORDS_BIGENDIAN
145    return net;
146 #else
147    return eina_swap64(net);
148 #endif
149 }
150 
151 #endif
152