/** * byteorder.h * @brief * Byte Converter for 2, 4, 8 bytes numeric types *--------------------------------------------------------------------- * Big Endian: XDR (big endian) encoding of numeric types * * Register * 0x0A0B0C0D * Memory | | | | * |..| | | | | * a+0: |0A|<---------+ | | | * a+1: |0B|<-----------+ | | * a+2: |0C|<-------------+ | * a+3: |0D|<---------------+ * |..| * *--------------------------------------------------------------------- * Little Endian: NDR (little endian) encoding of numeric types * * Register * 0x0A0B0C0D * | | | | Memory * | | | | |..| * | | | +--------> a+0: |0D| * | | +----------> a+1: |0C| * | +------------> a+2: |0B| * +--------------> a+3: |0A| * |..| *--------------------------------------------------------------------- * * @author * cheungmine * @since 2012 * @date Jun. 18, 2013 */ #ifndef _BYTEORDER_H_ #define _BYTEORDER_H_ #if defined(__cplusplus) extern "C" { #endif #include <memory.h> #ifdef _MSC_VER # define __INLINE static __forceinline # define __INLINE_ALL __INLINE #else # define __INLINE static inline # if (defined(__APPLE__) && defined(__ppc__)) /* static inline __attribute__ here breaks osx ppc gcc42 build */ # define __INLINE_ALL static __attribute__((always_inline)) # else # define __INLINE_ALL static inline __attribute__((always_inline)) # endif #endif #if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) ||\ defined (_sgi) || defined (__sun) || defined (sun) || \ defined (__digital__) || defined (__HP_cc) # include <inttypes.h> #elif defined (_MSC_VER) && _MSC_VER < 1600 /* VS 2010 (_MSC_VER 1600) has stdint.h */ typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #elif defined (_AIX) # include <sys/inttypes.h> #else # include <stdint.h> #endif #ifndef byte_t typedef unsigned char byte_t; #endif static union { char c[4]; uint8_t f; } __endianess = {{'l','0','0','b'}}; #define __little_endian (((char)__endianess.f) == 'l') #define __big_endian (((char)__endianess.f) == 'b') __INLINE void swap_bytes(void *value, int size) { int i = 0; uint8_t t; uint8_t *b = (uint8_t*) value; for (; i < size/2; ++i) { t = b[i]; b[i] = b[size-i-1]; b[size-i-1] = t; } } /** * 2 bytes numeric converter: int16_t, uint16_t */ __INLINE int16_t int16_htole (int16_t val) { if (__big_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE int16_t int16_htobe (int16_t val) { if (__little_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE int16_t int16_letoh (int16_t val) { if (__big_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE int16_t int16_betoh (int16_t val) { if (__little_endian) { swap_bytes(&val, sizeof(val)); } return val; } /** * 4 bytes numeric converter: * int32_t, uint32_t * float */ __INLINE int32_t int32_htole (int32_t val) { if (__big_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE int32_t int32_htobe (int32_t val) { if (__little_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE int32_t int32_letoh (int32_t val) { if (__big_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE int32_t int32_betoh (int32_t val) { if (__little_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE float float32_htole (float val) { if (__big_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE float float32_htobe (float val) { if (__little_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE float float32_letoh (float val) { if (__big_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE float float32_betoh (float val) { if (__little_endian) { swap_bytes(&val, sizeof(val)); } return val; } /** * 8 bytes numeric converter */ __INLINE double float64_htole (double val) { if (__big_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE double float64_htobe (double val) { if (__little_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE double float64_letoh (double val) { if (__big_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE double float64_betoh (double val) { if (__little_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE int64_t int64_htole (int64_t val) { if (__big_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE int64_t int64_htobe (int64_t val) { if (__little_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE int64_t int64_letoh (int64_t val) { if (__big_endian) { swap_bytes(&val, sizeof(val)); } return val; } __INLINE int64_t int64_betoh (int64_t val) { if (__little_endian) { swap_bytes(&val, sizeof(val)); } return val; } #ifdef BYTEORDER_TEST #include <assert.h> static void byteorder_test_int16 (int16_t val) { int16_t a, b; a = b = val; swap_bytes(&a, sizeof(a)); swap_bytes(&a, sizeof(a)); assert(a == b); b = int16_htole(a); b = int16_letoh(b); assert(a == b); b = int16_htobe(a); b = int16_betoh(b); assert(a == b); } static void byteorder_test_int32 (int val) { int a, b; a = b = val; swap_bytes(&a, sizeof(a)); swap_bytes(&a, sizeof(a)); assert(a == b); b = int32_htole(a); b = int32_letoh(b); assert(a == b); b = int32_htobe(a); b = int32_betoh(b); assert(a == b); } static void byteorder_test_float32 (float val) { float a, b; a = b = val; swap_bytes(&a, sizeof(a)); swap_bytes(&a, sizeof(a)); assert(a == b); b = float32_htole(a); b = float32_letoh(b); assert(a == b); b = float32_htobe(a); b = float32_betoh(b); assert(a == b); } static void byteorder_test_float64 (double val) { double a, b; a = b = val; swap_bytes(&a, sizeof(a)); swap_bytes(&a, sizeof(a)); assert(a == b); b = float64_htole(a); b = float64_letoh(b); assert(a == b); b = float64_htobe(a); b = float64_betoh(b); assert(a == b); } #endif #if defined(__cplusplus) } #endif #endif /* _BYTEORDER_H_ */