![]() |
|
Endianness |
DanielH
Member #934
January 2001
![]() |
Does Allegro have a function to check endianness? Can someone post a snippet of a) how to tell what endianness the machine has b) how they would read/write an 32bit int? You could read/write little e regardless of machine type then convert to big e if required. Sound about correct? |
Niunio
Member #1,975
March 2002
![]() |
IIRC there's a define somewhere in the header files (maybe type.h?) so you can use #IFDEF to know the endianess. Also, there are defines for the target system (CPU and operating system). ----------------- |
DanielH
Member #934
January 2001
![]() |
FYI, Allegro defines endianness with ALLEGRO_LITTLE_ENDIAN or ALLEGRO_BIG_ENDIAN defined What about this pseudocode? 1// returns number of bytes written or EOF if error
2int write(ALLEGRO_FILE *file, type value)
3{
4 // if big endian, swap bytes
5#ifdef ALLEGRO_BIG_ENDIAN
6 value = swap_bytes(&value, sizeof(type));
7#endif
8
9 // write little endian
10 return write_bytes(file, &value, sizeof(type));
11}
12
13// returns number of bytes read or EOF if error
14int read(ALLEGRO_FILE *file, type&value)
15{
16 // read little endian
17 int sz = read_bytes(file, &value, sizeof(type));
18
19 if (sz == EOF) return EOF:
20
21 // if big endian, swap bytes
22#ifdef ALLEGRO_BIG_ENDIAN
23 value = swap_bytes(&value, sizeof(type));
24#endif
25
26 return sz;
27}
|
GullRaDriel
Member #3,861
September 2003
![]() |
Allegro aside, here are some macros I'm using in my lib, mainly a scap of a lot of detection macros that I took here and there. 1/*! Little endian macro value */
2#define BYTEORDER_LITTLE_ENDIAN 0 // Little endian machine.
3/*! Big endian macro value */
4#define BYTEORDER_BIG_ENDIAN 1 // Big endian machine.
5
6
7#ifndef BYTEORDER_ENDIAN
8// Detect with GCC 4.6's macro.
9#if defined(__BYTE_ORDER__)
10#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
11#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
12#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
13#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
14#else
15#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
16#warning "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN."
17#warning "Setting default to BYTEORDER_LITTLE_ENDIAN"
18#endif
19// Detect with GLIBC's endian.h.
20#elif defined(__GLIBC__)
21#include <endian.h>
22#if (__BYTE_ORDER == __LITTLE_ENDIAN)
23#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
24#elif (__BYTE_ORDER == __BIG_ENDIAN)
25#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
26#else
27#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
28#warning "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN."
29#warning "Setting default to BYTEORDER_LITTLE_ENDIAN"
30#endif
31// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro.
32#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
33#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
34#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
35#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
36// Detect with architecture macros.
37#elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
38#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
39#elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
40#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
41#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
42#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
43#else
44#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
45#warning "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN."
46#warning "Setting default to BYTEORDER_LITTLE_ENDIAN"
47#endif
48#endif
Well. Old and new GCC specific code, maybe. I had no problem with it on Solaris, AIX, Linux, Windows MinGW. BTW I also had to detect 32 or 64 bits, and that little piece covered all my needs: 1#if defined( _WIN32 ) || defined( _WIN64 )
2#if defined( _WIN64 )
3#define __ENVBITS ENV_64BITS
4#else
5#define __ENVBITS ENV_32BITS
6#endif
7#endif
8
9#if !defined( __ENVBITS )
10#if defined( __GNUC__ )
11#if defined( __x86_64__ ) || defined( __ppc64__ )
12#define __ENVBITS __ENV_64BITS
13#else
14#define __ENVBITS __ENV_32BITS
15#endif
16#endif
17#endif
Your mileage may vary. It may only be right on my own os targets. Edit: "Code is like shit - it only smells if it is not yours" |