celestia/src/celutil/bytes.h

107 lines
2.6 KiB
C

// bytes.h
//
// Copyright (C) 2001, Colin Walters <walters@verbum.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
#ifndef _BYTES_H_
#define _BYTES_H_
#ifndef _WIN32
#ifndef TARGET_OS_MAC
#include <config.h>
#endif /* TARGET_OS_MAC */
#endif /* _WIN32 */
#include <celutil/util.h>
#ifndef __BYTE_ORDER__
# ifdef _WIN32
// FIXME: we assume that windows runs on LE hw only
# define __BYTE_ORDER__ 1234
# else
# error "Unknown system or compiler"
# endif
#endif
/* Use the system byteswap.h definitions if we have them */
#ifdef HAVE_BYTESWAP_H
#include <byteswap.h>
#else
static unsigned short bswap_16 (unsigned short val)
{
return ((((val) >> 8) & 0xff) | (((val) & 0xff) << 8));
}
static unsigned int bswap_32(unsigned int val) {
return (((val) & 0xff000000) >> 24) | (((val) & 0x00ff0000) >> 8) |
(((val) & 0x0000ff00) << 8) | (((val) & 0x000000ff) << 24);
}
#endif
inline double bswap_double(double d)
{
COMPILE_TIME_ASSERT(sizeof(double) == 8)
union DoubleBytes
{
char bytes[8];
double d;
};
DoubleBytes db;
db.d = d;
char c;
c = db.bytes[0]; db.bytes[0] = db.bytes[7]; db.bytes[7] = c;
c = db.bytes[1]; db.bytes[1] = db.bytes[6]; db.bytes[6] = c;
c = db.bytes[2]; db.bytes[2] = db.bytes[5]; db.bytes[5] = c;
c = db.bytes[3]; db.bytes[3] = db.bytes[4]; db.bytes[4] = c;
return db.d;
}
#define SWAP_FLOAT(x, y) do { *(unsigned int *)&x = bswap_32( *(unsigned int *)&y ); } while (0)
#if defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__)
#define LE_TO_CPU_INT16(ret, val) (ret = bswap_16(val))
#define LE_TO_CPU_INT32(ret, val) (ret = bswap_32(val))
#define LE_TO_CPU_FLOAT(ret, val) SWAP_FLOAT(ret, val)
#define LE_TO_CPU_DOUBLE(ret, val) (ret = bswap_double(d))
#define BE_TO_CPU_INT16(ret, val) (ret = val)
#define BE_TO_CPU_INT32(ret, val) (ret = val)
#define BE_TO_CPU_FLOAT(ret, val) (ret = val)
#define BE_TO_CPU_DOUBLE(ret, val) (ret = val)
#else
#define BE_TO_CPU_INT16(ret, val) (ret = bswap_16(val))
#define BE_TO_CPU_INT32(ret, val) (ret = bswap_32(val))
#define BE_TO_CPU_FLOAT(ret, val) SWAP_FLOAT(ret, val)
#define BE_TO_CPU_DOUBLE(ret, val) (ret = bswap_double(d))
#define LE_TO_CPU_INT16(ret, val) (ret = val)
#define LE_TO_CPU_INT32(ret, val) (ret = val)
#define LE_TO_CPU_FLOAT(ret, val) (ret = val)
#define LE_TO_CPU_DOUBLE(ret, val) (ret = val)
#endif
#endif // _BYTES_H_