/* q_endian.h endianness handling $Id: q_endian.h,v 1.5 2011/10/08 12:33:03 sezero Exp $ Copyright (C) 1996-1997 Id Software, Inc. Copyright (C) 2007-2011 O.Sezer 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __QENDIAN_H #define __QENDIAN_H /* * endianness stuff: is supposed * to succeed in locating the correct endian.h * this BSD style may not work everywhere. */ #undef ENDIAN_GUESSED_SAFE #undef ENDIAN_ASSUMED_UNSAFE #undef ENDIAN_RUNTIME_DETECT /* if you want to detect byte order at runtime * instead of compile time, define this as 1 : */ #define ENDIAN_RUNTIME_DETECT 0 #include /* include more if it didn't work: */ #if !defined(BYTE_ORDER) # if defined(__linux__) || defined(__linux) # include # elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) # include # elif defined(__sun) || defined(__svr4__) # include # elif defined(_AIX) # include # elif defined(sgi) # include # elif defined(__DJGPP__) # include # endif #endif /* endian includes */ #if defined(__BYTE_ORDER) && !defined(BYTE_ORDER) #define BYTE_ORDER __BYTE_ORDER #endif /* __BYTE_ORDER */ #if !defined(PDP_ENDIAN) #if defined(__PDP_ENDIAN) #define PDP_ENDIAN __PDP_ENDIAN #else #define PDP_ENDIAN 3412 #endif #endif /* NUXI endian (not supported) */ #if defined(__LITTLE_ENDIAN) && !defined(LITTLE_ENDIAN) #define LITTLE_ENDIAN __LITTLE_ENDIAN #endif /* __LITTLE_ENDIAN */ #if defined(__BIG_ENDIAN) && !defined(BIG_ENDIAN) #define BIG_ENDIAN __BIG_ENDIAN #endif /* __LITTLE_ENDIAN */ #if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) # if (BYTE_ORDER != LITTLE_ENDIAN) && (BYTE_ORDER != BIG_ENDIAN) # error "Unsupported endianness." # endif #else /* one of the definitions is mising. */ # undef BYTE_ORDER # undef LITTLE_ENDIAN # undef BIG_ENDIAN # undef PDP_ENDIAN # define LITTLE_ENDIAN 1234 # define BIG_ENDIAN 4321 # define PDP_ENDIAN 3412 #endif /* byte order defs */ #if !defined(BYTE_ORDER) /* supposedly safe assumptions: these may actually * be OS dependant and listing all possible compiler * macros here is impossible (the ones here are gcc * flags, mostly.) so, proceed carefully.. */ # if defined(__DJGPP__) || defined(MSDOS) || defined(__MSDOS__) # define BYTE_ORDER LITTLE_ENDIAN /* DOS */ # elif defined(__sun) || defined(__svr4__) /* solaris */ # if defined(_LITTLE_ENDIAN) /* x86 */ # define BYTE_ORDER LITTLE_ENDIAN # elif defined(_BIG_ENDIAN) /* sparc */ # define BYTE_ORDER BIG_ENDIAN # endif # elif defined(__i386) || defined(__i386__) || defined(__386__) || defined(_M_IX86) # define BYTE_ORDER LITTLE_ENDIAN /* any x86 */ # elif defined(__amd64) || defined(__x86_64__) || defined(_M_X64) # define BYTE_ORDER LITTLE_ENDIAN /* any x64 */ # elif defined(_M_IA64) # define BYTE_ORDER LITTLE_ENDIAN /* ia64 / Visual C */ # elif defined (__ppc__) || defined(__POWERPC__) || defined(_M_PPC) # define BYTE_ORDER BIG_ENDIAN /* PPC: big endian */ # elif (defined(__alpha__) || defined(__alpha)) || defined(_M_ALPHA) # define BYTE_ORDER LITTLE_ENDIAN /* should be safe */ # elif defined(_WIN32) || defined(_WIN64) /* windows : */ # define BYTE_ORDER LITTLE_ENDIAN /* should be safe */ # elif defined(__hppa) || defined(__hppa__) || defined(__sparc) || defined(__sparc__) /* others: check! */ # define BYTE_ORDER BIG_ENDIAN # endif # if defined(BYTE_ORDER) /* raise a flag, just in case: */ # define ENDIAN_GUESSED_SAFE BYTE_ORDER # endif #endif /* supposedly safe assumptions */ #if !defined(BYTE_ORDER) /* brain-dead fallback: default to little endian. * change if necessary, or use runtime detection! */ # define BYTE_ORDER LITTLE_ENDIAN # define ENDIAN_ASSUMED_UNSAFE BYTE_ORDER #endif /* fallback. */ extern int host_byteorder; extern int host_bigendian; /* bool */ extern int DetectByteorder (void); extern void ByteOrder_Init (void); /* byte swapping. most times we want to convert to * little endian: our data files are written in LE * format. sometimes, such as when writing to net, * we also convert to big endian. */ #if ENDIAN_RUNTIME_DETECT extern int (*BigLong) (int); extern int (*LittleLong) (int); #else /* ! ENDIAN_RUNTIME_DETECT */ extern int LongSwap (int); #if (BYTE_ORDER == BIG_ENDIAN) #define BigLong(l) (l) #define LittleLong(l) LongSwap((l)) #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define BigLong(l) LongSwap((l)) #define LittleLong(l) (l) #endif /* swap macros */ #endif /* runtime det */ #endif /* __QENDIAN_H */