X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=mware%2Fbyteorder.h;h=0ed874bbf68910da09c38ee7565fa05d30cc58ea;hb=33d48af0258dd55e1d2b51a4ae2f87401dcb00e9;hp=cf7d137418aafca7bb91c3fe5fa3cbd910954cc3;hpb=aaed3ed803ffbd77b476d71055388cf00232469a;p=bertos.git diff --git a/mware/byteorder.h b/mware/byteorder.h old mode 100755 new mode 100644 index cf7d1374..0ed874bb --- a/mware/byteorder.h +++ b/mware/byteorder.h @@ -1,8 +1,33 @@ -/*! +/** * \file * * * \brief Functions to convert integers to/from host byte-order. @@ -13,35 +38,232 @@ * \author Stefano Fedrigo */ -/* - * $Log$ - * Revision 1.1 2004/07/20 16:26:15 bernie - * Import byte-order macros into DevLib. - * - */ - #ifndef MWARE_BYTEORDER_H #define MWARE_BYTEORDER_H -#include -#include +#include +#include + +/** + * Swap upper and lower bytes in a 16-bit value. + */ +INLINE uint16_t swab16(uint16_t x) +{ + return ((x & (uint16_t)0x00FFU) << 8) + | ((x & (uint16_t)0xFF00U) >> 8); +} + +/** + * Reverse bytes in a 32-bit value (e.g.: 0x12345678 -> 0x78563412). + */ +INLINE uint32_t swab32(uint32_t x) +{ + return ((x & (uint32_t)0x000000FFUL) << 24) + | ((x & (uint32_t)0x0000FF00UL) << 8) + | ((x & (uint32_t)0x00FF0000UL) >> 8) + | ((x & (uint32_t)0xFF000000UL) >> 24); +} + +/** + * Reverse bytes in a 64-bit value. + */ +INLINE uint64_t swab64(uint64_t x) +{ + return (uint64_t)swab32(x >> 32) + | ((uint64_t)swab32(x & 0xFFFFFFFFUL) << 32); +} + +/** + * Reverse bytes in a float value. + */ +INLINE float swab_float(float x) +{ + /* Avoid breaking strict aliasing rules. */ + char *cx = (char *)(&x); + STATIC_ASSERT(sizeof(float) == 4); + #define BYTEORDER_SWAP(a, b) ((a) ^= (b) ^= (a) ^= (b)) + BYTEORDER_SWAP(cx[0], cx[3]); + BYTEORDER_SWAP(cx[1], cx[2]); + #undef BYTEORDER_SWAP + return x; +} + +INLINE uint16_t cpu_to_be16(uint16_t x) +{ + return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab16(x) : x; +} + +INLINE uint16_t cpu_to_le16(uint16_t x) +{ + return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab16(x) : x; +} + +INLINE uint32_t cpu_to_be32(uint32_t x) +{ + return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab32(x) : x; +} + +INLINE uint32_t cpu_to_le32(uint32_t x) +{ + return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab32(x) : x; +} + +INLINE uint64_t cpu_to_be64(uint64_t x) +{ + return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab64(x) : x; +} + +INLINE uint64_t cpu_to_le64(uint64_t x) +{ + return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab64(x) : x; +} + +INLINE float cpu_to_be_float(float x) +{ + return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab_float(x) : x; +} + +INLINE float cpu_to_le_float(float x) +{ + return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab_float(x) : x; +} + +INLINE uint16_t be16_to_cpu(uint16_t x) +{ + return cpu_to_be16(x); +} -INLINE uint16_t cpu_to_be16(uint16_t n); -INLINE uint16_t cpu_to_be16(uint16_t n) +INLINE uint16_t le16_to_cpu(uint16_t x) { - if (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) - n = n << 8 | n >> 8; + return cpu_to_le16(x); +} - return n; +INLINE uint32_t be32_to_cpu(uint32_t x) +{ + return cpu_to_be32(x); } -INLINE uint16_t cpu_to_le16(uint16_t n); -INLINE uint16_t cpu_to_le16(uint16_t n) +INLINE uint32_t le32_to_cpu(uint32_t x) { - if (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) - n = n << 8 | n >> 8; + return cpu_to_le32(x); +} - return n; +INLINE uint64_t be64_to_cpu(uint64_t x) +{ + return cpu_to_be64(x); } +INLINE uint64_t le64_to_cpu(uint64_t x) +{ + return cpu_to_le64(x); +} + +INLINE float be_float_to_cpu(float x) +{ + return cpu_to_be_float(x); +} + +INLINE float le_float_to_cpu(float x) +{ + return cpu_to_le_float(x); +} + +INLINE uint16_t host_to_net16(uint16_t x) +{ + return cpu_to_be16(x); +} + +INLINE uint16_t net_to_host16(uint16_t x) +{ + return be16_to_cpu(x); +} + +INLINE uint32_t host_to_net32(uint32_t x) +{ + return cpu_to_be32(x); +} + +INLINE uint32_t net_to_host32(uint32_t x) +{ + return be32_to_cpu(x); +} + +INLINE uint64_t host_to_net64(uint64_t x) +{ + return cpu_to_be64(x); +} + +INLINE uint64_t net_to_host64(uint64_t x) +{ + return be64_to_cpu(x); +} + +INLINE float host_to_net_float(float x) +{ + return cpu_to_be_float(x); +} + +INLINE float net_to_host_float(float x) +{ + return be_float_to_cpu(x); +} + +#ifdef __cplusplus + +/// Type generic byte swapping. +template +INLINE T swab(T x); + +template<> INLINE uint16_t swab(uint16_t x) { return swab16(x); } +template<> INLINE uint32_t swab(uint32_t x) { return swab32(x); } +template<> INLINE uint64_t swab(uint64_t x) { return swab64(x); } +template<> INLINE int16_t swab(int16_t x) { return static_cast(swab16(static_cast(x))); } +template<> INLINE int32_t swab(int32_t x) { return static_cast(swab32(static_cast(x))); } +template<> INLINE int64_t swab(int64_t x) { return static_cast(swab64(static_cast(x))); } +template<> INLINE float swab(float x) { return swab_float(x); } + +/// Type generic conversion from CPU byte order to big-endian byte order. +template +INLINE T cpu_to_be(T x) +{ + return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab(x) : x; +} + +/// Type generic conversion from CPU byte-order to little-endian. +template +INLINE T cpu_to_le(T x) +{ + return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab(x) : x; +} + +/// Type generic conversion from big endian byte-order to CPU byte order. +template +INLINE T be_to_cpu(T x) +{ + return cpu_to_be(x); +} + +/// Type generic conversion from little-endian byte order to CPU byte order. +template +INLINE T le_to_cpu(T x) +{ + return cpu_to_le(x); +} + +/// Type generic conversion from network byte order to host byte order. +template +INLINE T net_to_host(T x) +{ + return be_to_cpu(x); +} + +/// Type generic conversion from host byte order to network byte order. +template +INLINE T host_to_net(T x) +{ + return net_to_host(x); +} + +#endif /* __cplusplus */ + #endif /* MWARE_BYTEORDER_H */