![]() |
|
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 scrap 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" |
guin hanki
Member #23,491
August 2022
|
It seems there is a definition somewhere in the header files (maybe type.h?) so you can check the endianness using #IFDEF. It specifies the target system's CPU and operating system.https://maxifoot.info/ |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
You can perform a run time check easily enough. bool BigEndian() { int pack = 'b' << 24 | 'e' << 16 | 'e' << 8 | 'l'; return (char*)(pack)[0] == 'b'; }
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Polybios
Member #12,293
October 2010
|
Beels live in memory. |
DanielH
Member #934
January 2001
![]() |
Yes, as I said before, it's defined by Allegro depending on how Allegro was compiled ALLEGRO_LITTLE_ENDIAN or ALLEGRO_BIG_ENDIAN This is about what I have. Written and Read as little. Convert to big if needed. 1 void SwapBytes(const void* input, void* output, size_t bytes);
2 int32_t WriteBytes(Allegro::File& file, const void* value, size_t bytes);
3 int32_t ReadBytes(Allegro::File& file, void* value, size_t bytes);
4
5 template <typename type>
6 int32_t WritePrimitive(Allegro::File& file, const type value)
7 {
8 const type output;
9
10#ifdef ALLEGRO_LITTLE_ENDIAN
11 output = value;
12#else
13 SwapBytes(value, output, sizeof(type));
14#endif
15
16 return Wind::WriteBytes(file, &output, sizeof(type));
17 }
18
19 // special case. read/write as byte 0 or 1
20 template <> int32_t WritePrimitive(Allegro::File& file, const bool& input);
21
22
23 template <typename type>
24 int32_t ReadPrimitive(Allegro::File& file, type& value)
25 {
26 type input;
27 int32_t size = Wind::ReadBytes(file, &input, sizeof(type));
28
29 if (size == EOF)
30 {
31 return EOF;
32 }
33
34#ifdef ALLEGRO_BIG_ENDIAN
35 SwapBytes(input, value, sizeof(type));
36#else
37 value = input;
38#endif
39 return 0;
40 }
41
42 // special case. read/write as byte 0 or 1
43 template <> int32_t ReadPrimitive(Allegro::File& file, const bool& input);
|
|