|
23 | 23 | */ |
24 | 24 | #if defined(__linux__) |
25 | 25 | # include <endian.h> |
| 26 | + |
26 | 27 | #elif defined(__FreeBSD__) || defined(__NetBSD__) |
27 | | -# include <sys/endian.h> |
| 28 | +# include <sys/endian.h> |
| 29 | + |
28 | 30 | #elif defined(__OpenBSD__) |
29 | 31 | # include <sys/types.h> |
30 | 32 | # ifndef be16toh |
31 | 33 | # define be16toh(x) betoh16(x) |
32 | 34 | # define be32toh(x) betoh32(x) |
33 | 35 | # define be64toh(x) betoh64(x) |
34 | 36 | # endif |
35 | | -#elif defined(__APPLE__) || defined(_WIN32) |
36 | | -# define be16toh(x) ntohs(x) |
37 | | -# define htobe16(x) htons(x) |
38 | | -# define be32toh(x) ntonl(x) |
39 | | -# define htobe32(x) htonl(x) |
40 | | -# if defined(_WIN32) |
41 | | -/* |
42 | | - * Not sure, why htonll() and ntohll() are undefined in Visual Studio 2019: |
43 | | - * |
44 | | - *# define be64toh(x) ntohll(x) |
45 | | - *# define htobe64(x) htonll(x) |
46 | | - */ |
47 | | -# define htobe64(x) ((1==htonl(1)) ? (x) : (((uint64_t)htonl((x) & 0xFFFFFFFFUL)) << 32) | htonl((uint32_t)((x) >> 32))) |
48 | | -# define be64toh(x) ((1==ntohl(1)) ? (x) : (((uint64_t)ntohl((x) & 0xFFFFFFFFUL)) << 32) | ntohl((uint32_t)((x) >> 32))) |
49 | | -# else |
50 | | -# define be64toh(x) ntohll(x) |
51 | | -# define htobe64(x) htonll(x) |
| 37 | + |
| 38 | +#elif defined(__APPLE__) |
| 39 | +/* Darwin does NOT have a native htonll/ntohll. Use OSByteOrder helpers. */ |
| 40 | +# include <libkern/OSByteOrder.h> |
| 41 | +# ifndef htobe16 |
| 42 | +# define htobe16(x) OSSwapHostToBigInt16((uint16_t)(x)) |
| 43 | +# define be16toh(x) OSSwapBigToHostInt16((uint16_t)(x)) |
| 44 | +# define htobe32(x) OSSwapHostToBigInt32((uint32_t)(x)) |
| 45 | +# define be32toh(x) OSSwapBigToHostInt32((uint32_t)(x)) |
| 46 | +# define htobe64(x) OSSwapHostToBigInt64((uint64_t)(x)) |
| 47 | +# define be64toh(x) OSSwapBigToHostInt64((uint64_t)(x)) |
| 48 | +# endif |
| 49 | + |
| 50 | +#elif defined(_WIN32) |
| 51 | +/* Windows lacks be*toh; build from htonl/ntohl or use byte-swap intrinsics. */ |
| 52 | +# define be16toh(x) ntohs((uint16_t)(x)) |
| 53 | +# define htobe16(x) htons((uint16_t)(x)) |
| 54 | +# define be32toh(x) ntohl((uint32_t)(x)) |
| 55 | +# define htobe32(x) htonl((uint32_t)(x)) |
| 56 | +/* Portable 64-bit swap using two 32-bit ops */ |
| 57 | +# define htobe64(x) ((1==htonl(1)) ? (uint64_t)(x) : (((uint64_t)htonl((uint32_t)((x) & 0xFFFFFFFFu))) << 32) | htonl((uint32_t)((x) >> 32))) |
| 58 | +# define be64toh(x) ((1==ntohl(1)) ? (uint64_t)(x) : (((uint64_t)ntohl((uint32_t)((x) & 0xFFFFFFFFu))) << 32) | ntohl((uint32_t)((x) >> 32))) |
| 59 | +#endif |
| 60 | + |
| 61 | +/* As a final fallback attempt, derive from compiler endianness macros */ |
| 62 | +#ifndef htobe64 |
| 63 | +# if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) |
| 64 | +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ |
| 65 | +# define __ns_bswap64(v) __builtin_bswap64((uint64_t)(v)) |
| 66 | +# define htobe64(x) __ns_bswap64(x) |
| 67 | +# define be64toh(x) __ns_bswap64(x) |
| 68 | +# define htobe32(x) htonl((uint32_t)(x)) |
| 69 | +# define be32toh(x) ntohl((uint32_t)(x)) |
| 70 | +# define htobe16(x) htons((uint16_t)(x)) |
| 71 | +# define be16toh(x) ntohs((uint16_t)(x)) |
| 72 | +# else |
| 73 | +# define htobe64(x) (uint64_t)(x) |
| 74 | +# define be64toh(x) (uint64_t)(x) |
| 75 | +# endif |
52 | 76 | # endif |
53 | 77 | #endif |
54 | 78 |
|
|
0 commit comments