Jump to content
  • Advertisement
Sign in to follow this  
KumGame

Byte Swapping issue

This topic is 4578 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi folks.. I'm in a trouble... I'm working on Mac OS and my product has to be universal binary. I'm using Carbon framework and the byte swapping gives me weird results. I'm doing something like this.. ....... Code goes here..... SInt32 test; CFSwappedFloat32 temp; #Ifndef __BIG_ENDIAN__ // swap the bytes test = CFSwapInt32HostToBig(intData); temp = CFConvertFloat32HostToSwapped(floatData); ...... #endif //Write to file I do the reverse swapping while reading the saved file.. The above method works fine if I write file in a PowerPC and read it using same machine. but doesn work if I try to read it using an Intel Mac.. I'm using eMac G4 machine (PowerPC, Mac OS X 10.4.4) Any help will be of great use ...

Share this post


Link to post
Share on other sites
Advertisement
I don't know the answer, but in addition to your post here you might also try the gdnet *nix forum (I don't know if that would be considered a crosspost), and also idevgames.com. I'm sure that between here and idevgames you can get the info you need.

Share this post


Link to post
Share on other sites
In C++ you can write this to detect the endianess of a system:

static inline
bool isLittleEndian()
{
union U {
int i;
char c;
} u;

u.i = 0x0102;
return u.c == 0x02;
}


If optimization is turned on, the compiler will reduce this to a single assembler instruction, depending on if the compilation target is little or big endian (IA32 in this case):

0: b8 01 00 00 00 mov $0x1,%eax
5: c3 ret


Then you can use this function to decide on compile-time if conversions are needed. For instance:

int bar()
{
int result;
if (isLittleEndian())
{
result = 3;
}
else
{
result = 5;
}
return result;
}


compiles down to:

00000000 <bar()>:
0: b8 03 00 00 00 mov $0x3,%eax
5: c3 ret

Only code for the correct version of endianess is generated.

Share this post


Link to post
Share on other sites
You can apply this to change network byte order:

unsigned int h2n(unsigned int ui)
{
enum { N = sizeof(unsigned int) };

union {
unsigned int ui;
unsigned char uc[N];
} u;

u.ui = ui;

if (isLittleEndian())
{
for (int i = 0; i < N/2; i++)
{
unsigned char c = u.uc;
u.uc = u.uc[N-i-1];
u.uc[N-i-1] = c;
}
}

return u.ui;
}



Share this post


Link to post
Share on other sites

Thanks a lot for ur replies...

Now it works fine.. Mistake was with my code.. Again, a silly mistake :)

Thanks again..

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

static inline
bool isLittleEndian()
{
union U {
int i;
char c;
} u;

u.i = 0x0102;
return u.c == 0x02;
}


I use a very similar function, it just doesn't have a union.


bool IsLittleEndian()
{
int i = 0x01;
char *p = (char *) &i;
return (p[0] == 0x01);
}

Share this post


Link to post
Share on other sites
AP, your compiles down to:

0: 83 ec 10 sub $0x10,%esp
3: b8 01 00 00 00 mov $0x1,%eax
8: 89 44 24 0c mov %eax,0xc(%esp)
c: 31 c0 xor %eax,%eax
e: 80 7c 24 0c 01 cmpb $0x1,0xc(%esp)
13: 0f 94 c0 sete %al
16: 83 c4 10 add $0x10,%esp
19: c3 ret


The compiler used was GCC:

Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.1.0/configure --prefix=/home/nmi --enable-languages=c,c++,java --enable-bootstrap --with-x --enable-java-awt=gtk,xlib --enable-gtk-cairo
Thread model: posix
gcc version 4.1.0



As you can see, your version performs the endianess check at runtime, while mine does this at compile time. Having a compile time decision allows the optimiser to remove the dead code.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
That's very useful to know and there was me thinking it was an elegant function :(
Thank you nmi.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!