DevMaster.net Forums
[[ Home | Forums | 3D Engines Database | Wiki | Articles/Tutorials | Game Dev Jobs | IRC Chat Network | Contact Us ]]

Go Back   DevMaster.net Forums > Site Discussions > Code & Snapshot Discussion
User Name
Password
Register FAQ Members List Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Search this Thread Display Modes
Old 09-17-2004, 02:26 AM   #1
NomadRock
Senior Member
 
NomadRock's Avatar
 
Join Date: Aug 2004
Location: USA
Posts: 829
Default

Code:
unsigned int convertEndianness(unsigned int data) { char * c; char temp; unsigned int test = 0x000000FF; if((char*)(&test)[0] == (char)(0xFF)) // this machine is little endian { c = (char*)(&data); temp = c[0]; c[0] = c[3]; c[3] = temp; temp = c[1]; c[1] = c[2]; c[2] = temp; } return data; }

When programming across networks it is often necessary to transfer data between a machine that is little endian and a machine that is big endian. See the Wikipedia entry for more information on the subject.

Generally network transmission should be in big endian. This function will prep data for sending across the network and do the reverse for data recieved across the network. This way the endianness of the opposite machine does not matter. First it checks to see if the first byte is the same as the least significant byte. If this is the case then the machine is little endian and the data must be converted.
___________________________________________
Jesse Coyle
NomadRock is offline   Reply With Quote
Old 09-17-2004, 05:09 AM   #2
Nick
Senior Member
 
Join Date: Aug 2004
Location: Ghent, Belgium
Posts: 1,056
Default

Nice trick to automatically compile for the endianness of the local machine!

There's an x86 instruction for swapping endianness quickly: bswap.
Nick is offline   Reply With Quote
Old 09-17-2004, 05:23 AM   #3
davepermen
Senior Member
 
davepermen's Avatar
 
Join Date: Jan 2003
Location: Switzerland
Posts: 1,333
Default

cool. never noticed this one
___________________________________________
davepermen.net
-Loving a Person is having the wish to see this Person happy, no matter what that means to yourself.
-No matter what it means to myself....
davepermen is offline   Reply With Quote
Old 09-17-2004, 07:23 AM   #4
NomadRock
Senior Member
 
NomadRock's Avatar
 
Join Date: Aug 2004
Location: USA
Posts: 829
Default

I basically never use assembly so I didn't know about that, but the whole point of the function was to be as portable as possible, I figure if I don't know the endianness of the machine I probably wont know the archetecture either. You are right though, if this is used in a performance critical location it is better to sacrifice readability in order to put in multiple code paths in so you can use the assembly of each architecture. The apps I was writing were not proccessor bound on network transmission though, so I didn't have to worry about optomization.
___________________________________________
Jesse Coyle
NomadRock is offline   Reply With Quote
Old 09-17-2004, 07:55 AM   #5
Michael
Member
 
Join Date: Sep 2004
Posts: 67
Default

You could also simply use htonl and the likes.
Michael is offline   Reply With Quote
Old 09-17-2004, 11:51 AM   #6
freak0r
New Member
 
Join Date: Sep 2004
Location: Switzerland
Posts: 1
Default

Code:
c = (char*)(&data); if(c[0] == (char)(data % 256)) // this machine is little endian

I don't think thats a good idea. Think about a value like 0xFFABCDFF. The above code will determine the 'machine' to be little endian, although it doesn't necessary need to be. You basically compare the first byte of the value with the total value modulo 256. This will lead to potentially wrong results if the first and last byte are identical.

Or am I missing the obvious?? It's still early morning :)
freak0r is offline   Reply With Quote
Old 09-17-2004, 02:16 PM   #7
Michael
Member
 
Join Date: Sep 2004
Posts: 67
Default

No, I think that's a bug. You should do the check on some known data, such as:
Code:
bool isLittleEndian() { int foo=1; return 1==*((char*)&foo); }

Or just use htonl etc...
Michael is offline   Reply With Quote
Old 09-17-2004, 02:46 PM   #8
NomadRock
Senior Member
 
NomadRock's Avatar
 
Join Date: Aug 2004
Location: USA
Posts: 829
Default

There is an error in the code but that is not it. I modulus by 256 to zero out the other bytes, but this would not work if the lower byte is zero already. I will fix the code to accomidate this.
___________________________________________
Jesse Coyle
NomadRock is offline   Reply With Quote
Old 09-17-2004, 02:54 PM   #9
NomadRock
Senior Member
 
NomadRock's Avatar
 
Join Date: Aug 2004
Location: USA
Posts: 829
Default

I suppose even better I could use
Code:
#define LITTLE_ENDIAN ((0xFF000000 >> 24) & (255))
___________________________________________
Jesse Coyle
NomadRock is offline   Reply With Quote
Old 09-17-2004, 03:10 PM   #10
Michael
Member
 
Join Date: Sep 2004
Posts: 67
Default

Quote:
Originally Posted by NomadRock
I suppose even better I could use
Code:
#define LITTLE_ENDIAN ((0x000000FF << 24) & (0xFF000000))
[snapback]11708[/snapback]
No.
Michael is offline   Reply With Quote
Old 09-17-2004, 03:40 PM   #11
NomadRock
Senior Member
 
NomadRock's Avatar
 
Join Date: Aug 2004
Location: USA
Posts: 829
Default

Ok, what is wrong with that?
___________________________________________
Jesse Coyle
NomadRock is offline   Reply With Quote
Old 09-17-2004, 03:42 PM   #12
Michael
Member
 
Join Date: Sep 2004
Posts: 67
Default

It doesn't return 0 for big endian machines.
Michael is offline   Reply With Quote
Old 09-17-2004, 04:44 PM   #13
NomadRock
Senior Member
 
NomadRock's Avatar
 
Join Date: Aug 2004
Location: USA
Posts: 829
Default

Quite true, good catch. Corrected as such. I really wish I didn't have to worry too much about the low level, but it is a good learning experience. Hopefully others can learn from this too.

BTW, I checked up on htonl, this is basically what I attempt to implement. Unfortunatly I do not have endian.h where it is supposed to reside on my mingw compiler. Is this a linux only include?
___________________________________________
Jesse Coyle
NomadRock is offline   Reply With Quote
Old 09-17-2004, 05:10 PM   #14
Francois Hamel
Valued Member
 
Francois Hamel's Avatar
 
Join Date: Aug 2004
Location: Quebec, Canada
Posts: 109
Default

Here's what you can do:

Code:
unsigned char myFakeWORD[2] = { 0xFF, 0x00 }; unsigned short myRealWORD = *((unsigned short*)myFakeWORD); if(myRealWORD == 0xFF00) { printf("we are in BIG ENDIAN baby!"); } else { printf("oh crap...not LITTLE ENDIAN! Who invented this shit!?"); }
___________________________________________
I post with style, do you?
http://fhamel.blogspot.com/
Francois Hamel is offline   Reply With Quote
Old 09-17-2004, 05:15 PM   #15
Francois Hamel
Valued Member
 
Francois Hamel's Avatar
 
Join Date: Aug 2004
Location: Quebec, Canada
Posts: 109
Default

damn I think I should pay more attention before posting...
sorry for stating the already stated
___________________________________________
I post with style, do you?
http://fhamel.blogspot.com/
Francois Hamel is offline   Reply With Quote
Old 09-17-2004, 10:28 PM   #16
Michael
Member
 
Join Date: Sep 2004
Posts: 67
Default

You could include one of the WinSock headers.
Michael is offline   Reply With Quote
Old 09-18-2004, 01:08 AM   #17
NomadRock
Senior Member
 
NomadRock's Avatar
 
Join Date: Aug 2004
Location: USA
Posts: 829
Default

The whole idea is for this to work outside of windows x86 systems as well as on those systems.

I was writing an app in C that could be compiled on windows, linux, or solaris.
___________________________________________
Jesse Coyle
NomadRock is offline   Reply With Quote
Old 09-18-2004, 07:44 AM   #18
Michael
Member
 
Join Date: Sep 2004
Posts: 67
Default

htonl etc are available on basically every platform that has a BSD-style socket interface.
Michael is offline   Reply With Quote
Old 09-18-2004, 11:00 AM   #19
NomadRock
Senior Member
 
NomadRock's Avatar
 
Join Date: Aug 2004
Location: USA
Posts: 829
Default

I wanted to try and avoid a page of #if / #includes to find the right headers on any system
___________________________________________
Jesse Coyle
NomadRock is offline   Reply With Quote
Old 09-18-2004, 11:15 AM   #20
Michael
Member
 
Join Date: Sep 2004
Posts: 67
Default

If you would restrict your set of a platforms to the relevant (quasi)standard, and the relevant (quasi)standard would enforce the existance of certain header files, that was possible. <wink>
Michael is offline   Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Forum Jump


All times are GMT -7. The time now is 07:45 AM.


Powered by vBulletin
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.