字节次序转换函数

/**
 * 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_ */

你可能感兴趣的:(字节次序转换函数)