1 // "License": Public Domain 2 // I, Mathias Panzenböck, place this file hereby into the public domain. Use it at your own risk for whatever you like. 3 // In case there are jurisdictions that don't support putting things in the public domain you can also consider it to 4 // be "dual licensed" under the BSD, MIT and Apache licenses, if you want to. This code is trivial anyway. Consider it 5 // an example on how to get the endian conversion functions on different platforms. 6 7 #ifndef PORTABLE_ENDIAN_H__ 8 #define PORTABLE_ENDIAN_H__ 9 10 #if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__) 11 12 # define __WINDOWS__ 13 14 #endif 15 16 #if defined(__linux__) || defined(__CYGWIN__) 17 /* Define necessary macros for the header to expose all fields. */ 18 # if !defined(_BSD_SOURCE) 19 # define _BSD_SOURCE 20 # endif 21 # if !defined(__USE_BSD) 22 # define __USE_BSD 23 # endif 24 # if !defined(_DEFAULT_SOURCE) 25 # define _DEFAULT_SOURCE 26 # endif 27 # include <endian.h> 28 # include <features.h> 29 /* See http://linux.die.net/man/3/endian */ 30 # if defined(htobe16) && defined(htole16) && defined(be16toh) && defined(le16toh) && defined(htobe32) && defined(htole32) && defined(be32toh) && defined(htole32) && defined(htobe64) && defined(htole64) && defined(be64) && defined(le64) 31 /* Do nothing. The macros we need already exist. */ 32 # elif !defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 9))) 33 # include <arpa/inet.h> 34 # if defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN) 35 # define htobe16(x) htons(x) 36 # define htole16(x) (x) 37 # define be16toh(x) ntohs(x) 38 # define le16toh(x) (x) 39 40 # define htobe32(x) htonl(x) 41 # define htole32(x) (x) 42 # define be32toh(x) ntohl(x) 43 # define le32toh(x) (x) 44 45 # define htobe64(x) (((uint64_t)htonl(((uint32_t)(((uint64_t)(x)) >> 32)))) | (((uint64_t)htonl(((uint32_t)(x)))) << 32)) 46 # define htole64(x) (x) 47 # define be64toh(x) (((uint64_t)ntohl(((uint32_t)(((uint64_t)(x)) >> 32)))) | (((uint64_t)ntohl(((uint32_t)(x)))) << 32)) 48 # define le64toh(x) (x) 49 # elif defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN) 50 # define htobe16(x) (x) 51 # define htole16(x) (((((uint16_t)(x)) >> 8))|((((uint16_t)(x)) << 8))) 52 # define be16toh(x) (x) 53 # define le16toh(x) (((((uint16_t)(x)) >> 8))|((((uint16_t)(x)) << 8))) 54 55 # define htobe32(x) (x) 56 # define htole32(x) (((uint32_t)htole16(((uint16_t)(((uint32_t)(x)) >> 16)))) | (((uint32_t)htole16(((uint16_t)(x)))) << 16)) 57 # define be32toh(x) (x) 58 # define le32toh(x) (((uint32_t)le16toh(((uint16_t)(((uint32_t)(x)) >> 16)))) | (((uint32_t)le16toh(((uint16_t)(x)))) << 16)) 59 60 # define htobe64(x) (x) 61 # define htole64(x) (((uint64_t)htole32(((uint32_t)(((uint64_t)(x)) >> 32)))) | (((uint64_t)htole32(((uint32_t)(x)))) << 32)) 62 # define be64toh(x) (x) 63 # define le64toh(x) (((uint64_t)le32toh(((uint32_t)(((uint64_t)(x)) >> 32)))) | (((uint64_t)le32toh(((uint32_t)(x)))) << 32)) 64 # else 65 # error Byte Order not supported or not defined. 66 # endif 67 # endif 68 69 #elif defined(__APPLE__) 70 71 # include <libkern/OSByteOrder.h> 72 73 # define htobe16(x) OSSwapHostToBigInt16(x) 74 # define htole16(x) OSSwapHostToLittleInt16(x) 75 # define be16toh(x) OSSwapBigToHostInt16(x) 76 # define le16toh(x) OSSwapLittleToHostInt16(x) 77 78 # define htobe32(x) OSSwapHostToBigInt32(x) 79 # define htole32(x) OSSwapHostToLittleInt32(x) 80 # define be32toh(x) OSSwapBigToHostInt32(x) 81 # define le32toh(x) OSSwapLittleToHostInt32(x) 82 83 # define htobe64(x) OSSwapHostToBigInt64(x) 84 # define htole64(x) OSSwapHostToLittleInt64(x) 85 # define be64toh(x) OSSwapBigToHostInt64(x) 86 # define le64toh(x) OSSwapLittleToHostInt64(x) 87 88 # define __BYTE_ORDER BYTE_ORDER 89 # define __BIG_ENDIAN BIG_ENDIAN 90 # define __LITTLE_ENDIAN LITTLE_ENDIAN 91 # define __PDP_ENDIAN PDP_ENDIAN 92 93 #elif defined(__OpenBSD__) 94 95 # include <sys/endian.h> 96 97 #elif defined(__HAIKU__) 98 99 # include <endian.h> 100 101 #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) 102 103 # include <sys/endian.h> 104 105 # if !defined(be16toh) 106 # define be16toh(x) betoh16(x) 107 # define le16toh(x) letoh16(x) 108 # endif 109 110 # if !defined(be32toh) 111 # define be32toh(x) betoh32(x) 112 # define le32toh(x) letoh32(x) 113 # endif 114 115 # if !defined(be64toh) 116 # define be64toh(x) betoh64(x) 117 # define le64toh(x) letoh64(x) 118 # endif 119 120 #elif defined(__WINDOWS__) 121 122 # if BYTE_ORDER == LITTLE_ENDIAN 123 124 # define htobe16(x) _byteswap_ushort(x) 125 # define htole16(x) (x) 126 # define be16toh(x) _byteswap_ushort(x) 127 # define le16toh(x) (x) 128 129 # define htobe32(x) _byteswap_ulong(x) 130 # define htole32(x) (x) 131 # define be32toh(x) _byteswap_ulong(x) 132 # define le32toh(x) (x) 133 134 # define htobe64(x) _byteswap_uint64(x) 135 # define be64toh(x) _byteswap_uint64(x) 136 # define htole64(x) (x) 137 # define le64toh(x) (x) 138 139 # elif BYTE_ORDER == BIG_ENDIAN 140 141 /* that would be xbox 360 */ 142 # define htobe16(x) (x) 143 # define htole16(x) __builtin_bswap16(x) 144 # define be16toh(x) (x) 145 # define le16toh(x) __builtin_bswap16(x) 146 147 # define htobe32(x) (x) 148 # define htole32(x) __builtin_bswap32(x) 149 # define be32toh(x) (x) 150 # define le32toh(x) __builtin_bswap32(x) 151 152 # define htobe64(x) (x) 153 # define htole64(x) __builtin_bswap64(x) 154 # define be64toh(x) (x) 155 # define le64toh(x) __builtin_bswap64(x) 156 157 # else 158 159 # error byte order not supported 160 161 # endif 162 163 # define __BYTE_ORDER BYTE_ORDER 164 # define __BIG_ENDIAN BIG_ENDIAN 165 # define __LITTLE_ENDIAN LITTLE_ENDIAN 166 # define __PDP_ENDIAN PDP_ENDIAN 167 168 #elif defined(__sun) 169 170 # include <sys/byteorder.h> 171 172 # define htobe16(x) BE_16(x) 173 # define htole16(x) LE_16(x) 174 # define be16toh(x) BE_16(x) 175 # define le16toh(x) LE_16(x) 176 177 # define htobe32(x) BE_32(x) 178 # define htole32(x) LE_32(x) 179 # define be32toh(x) BE_32(x) 180 # define le32toh(x) LE_32(x) 181 182 # define htobe64(x) BE_64(x) 183 # define htole64(x) LE_64(x) 184 # define be64toh(x) BE_64(x) 185 # define le64toh(x) LE_64(x) 186 187 #elif defined _AIX /* AIX is always big endian */ 188 # define be64toh(x) (x) 189 # define be32toh(x) (x) 190 # define be16toh(x) (x) 191 # define le32toh(x) \ 192 ((((x) & 0xff) << 24) | \ 193 (((x) & 0xff00) << 8) | \ 194 (((x) & 0xff0000) >> 8) | \ 195 (((x) & 0xff000000) >> 24)) 196 # define le64toh(x) \ 197 ((((x) & 0x00000000000000ffL) << 56) | \ 198 (((x) & 0x000000000000ff00L) << 40) | \ 199 (((x) & 0x0000000000ff0000L) << 24) | \ 200 (((x) & 0x00000000ff000000L) << 8) | \ 201 (((x) & 0x000000ff00000000L) >> 8) | \ 202 (((x) & 0x0000ff0000000000L) >> 24) | \ 203 (((x) & 0x00ff000000000000L) >> 40) | \ 204 (((x) & 0xff00000000000000L) >> 56)) 205 # ifndef htobe64 206 # define htobe64(x) be64toh(x) 207 # endif 208 # ifndef htobe32 209 # define htobe32(x) be32toh(x) 210 # endif 211 # ifndef htobe16 212 # define htobe16(x) be16toh(x) 213 # endif 214 215 216 #else 217 218 # error platform not supported 219 220 #endif 221 222 #endif 223