Fall back to naive built-in byte-swap routines
EL5 lacks htobe64 and friends. Using its byteswap.h requires an endianness check in our headers, which is fragile and compiler-dependent. It's a fair amount of code [1], and is only useful on EL5. So instead, let's include a fallback implementation of these functions, and use it whenever we can't find the (now-)standard Linux or OS X routines. The fallback is endianness-independent and should work on any platform. [1] https://github.com/rurban/mosh/commit/da1a5abd1e09f0c1e9295357bb480a643d9dc8e3
This commit is contained in:
committed by
Keith Winstein
parent
85d197346a
commit
c2a5941f88
@@ -27,12 +27,84 @@
|
||||
# elif defined(HAVE_SYS_ENDIAN_H)
|
||||
# include <sys/endian.h>
|
||||
# endif
|
||||
|
||||
#elif HAVE_OSX_SWAP
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# define htobe64 OSSwapHostToBigInt64
|
||||
# define be64toh OSSwapBigToHostInt64
|
||||
# define htobe16 OSSwapHostToBigInt16
|
||||
# define be16toh OSSwapBigToHostInt16
|
||||
|
||||
#else
|
||||
|
||||
/* Use our fallback implementation, which is correct for any endianness. */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Make sure they aren't macros */
|
||||
#undef htobe64
|
||||
#undef be64toh
|
||||
#undef htobe16
|
||||
#undef be16toh
|
||||
|
||||
/* Use unions rather than casts, to comply with strict aliasing rules. */
|
||||
|
||||
inline uint64_t htobe64( uint64_t x ) {
|
||||
uint8_t xs[ 8 ] = {
|
||||
( x >> 56 ) & 0xFF,
|
||||
( x >> 48 ) & 0xFF,
|
||||
( x >> 40 ) & 0xFF,
|
||||
( x >> 32 ) & 0xFF,
|
||||
( x >> 24 ) & 0xFF,
|
||||
( x >> 16 ) & 0xFF,
|
||||
( x >> 8 ) & 0xFF,
|
||||
x & 0xFF };
|
||||
union {
|
||||
const uint8_t *p8;
|
||||
const uint64_t *p64;
|
||||
} u;
|
||||
u.p8 = xs;
|
||||
return *u.p64;
|
||||
}
|
||||
|
||||
inline uint64_t be64toh( uint64_t x ) {
|
||||
union {
|
||||
const uint8_t *p8;
|
||||
const uint64_t *p64;
|
||||
} u;
|
||||
u.p64 = &x;
|
||||
return ( uint64_t( u.p8[ 0 ] ) << 56 )
|
||||
| ( uint64_t( u.p8[ 1 ] ) << 48 )
|
||||
| ( uint64_t( u.p8[ 2 ] ) << 40 )
|
||||
| ( uint64_t( u.p8[ 3 ] ) << 32 )
|
||||
| ( uint64_t( u.p8[ 4 ] ) << 24 )
|
||||
| ( uint64_t( u.p8[ 5 ] ) << 16 )
|
||||
| ( uint64_t( u.p8[ 6 ] ) << 8 )
|
||||
| ( uint64_t( u.p8[ 7 ] ) );
|
||||
}
|
||||
|
||||
inline uint16_t htobe16( uint16_t x ) {
|
||||
uint8_t xs[ 2 ] = {
|
||||
( x >> 8 ) & 0xFF,
|
||||
x & 0xFF };
|
||||
union {
|
||||
const uint8_t *p8;
|
||||
const uint16_t *p16;
|
||||
} u;
|
||||
u.p8 = xs;
|
||||
return *u.p16;
|
||||
}
|
||||
|
||||
inline uint16_t be16toh( uint16_t x ) {
|
||||
union {
|
||||
const uint8_t *p8;
|
||||
const uint16_t *p16;
|
||||
} u;
|
||||
u.p16 = &x;
|
||||
return ( uint16_t( u.p8[ 0 ] ) << 8 )
|
||||
| ( uint16_t( u.p8[ 1 ] ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user