Serghei Amelian wrote:
> Are cineva idee daca exista vreo directiva de preprocesor la GCC care sa-mi
> indice daca sunt pe platforma big endian sau pe little endian?
>
Poti folosi headerele sistem:
#include <endian.h>
#if __BYTE_ORDER == __LITTLE_ENDIAN
...
#else
...
#endif
> Am codul asta:
>
> bool readUInt32(const unsigned char *str, unsigned int *tgt)
> {
> *tgt = 0;
>
> unsigned int b0, b1, b2, b3;
>
> b0 = str[0];
> b1 = str[1];
> b2 = str[2];
> b3 = str[3];
>
> if(bigEndian)
> *tgt = (b3 | (b2 << 8) | (b1 << 16) | (b0 << 24));
> else
> *tgt = (b0 | (b1 << 8) | (b2 << 16) | (b3 << 24));
>
> return true;
> }
>
> In principiu incarc niste fisiere TIFF de pe disk si pe acolo exista tot
> felul
> de informatii de offset cu care gasesc locatia paginilor. Si platforma si
> tiff-ul pot fi little/big endian. La tiff nu e problema ca zice in antet de
> care e. Alta chestie: codul de mai sus poate functiona pe alte platforme
> decat x86? Mentionez ca nu am nici un fel de experienta pe alte platforme
> decat Intel pe 32 biti.
>
Chestia de mai sus e corecta doar daca 'str' e in ordine nativa (LE pe
masina LE, BE pe masina BE). Or in cazul asta conversia o poti face
neconditionat mult mai simplu: *tgd = *(unsigned int*)str.
Altfel o sa-ti scoata goange. Presupunand ca incerci sa citesti valoarea
0x04030201:
* str e LE (01, 02, 03, 04), masina e BE => *tgt == 0x01020304
* str e BE (04, 03, 02, 01), masina e LE => *tgt == 0x01020304
Nu asta vrei. Cel mai elegant mi se pare:
#include <stdint.h>
#include <endian.h>
#define swab32(x) \
({ \
__u32 __x = (x); \
((__u32)( \
(((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
(((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \
(((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \
(((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
})
uint32_t readUInt32(const uint8_t *str, int endianess) {
uint32_t res = *(uint32_t*)str;
if (endianess != __BYTE_ORDER)
res = swab32(res);
return res;
}
Mai poti arunca o privire prin /usr/include/linux/byteorder/*.h pentru idei.
---
fm
_______________________________________________
RLUG mailing list
[email protected]
http://lists.lug.ro/mailman/listinfo/rlug