Thread: Endian Question

  1. #1
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404

    Endian Question

    I am writing a data buffer which will handle data that will be sent out on a socket stream. So needless to say, it will be in a big endian format because that is the network standard.

    The following code puts this data in correctly:
    Code:
    buffer_add_int16(sendbuff, 0xBBCC);
    If I look at the buffer byte for byte, it is in the order 0xBB 0xCC, which is good.

    The problem comes along when I try to read it out of the buffer. My system is little endian.
    Here is my function for reading out a WORD sized datatype:
    Code:
    uint16_t buffer_get_int16(buffer_t *buffer)
    {
    	uint16_t ret;
    
    	buffer_get_bytes(buffer, buffer->buffer_position, &ret, 2);
    	buffer->buffer_position+=2;
    	
    	if (__BYTE_ORDER == buffer->buffer_byte_order)
    		return ret;
    	else
    		return ntohs(ret);
    }
    
    void *buffer_get_bytes(buffer_t *buffer, uint16_t offset, void *data, uint16_t length)
    {
    	memcpy(data, buffer->buffer_data + offset, length);
    	return data;
    }
    I have checked, and __BYTE_ORDER == buffer->buffer_byte_order is false, so it sends ret through ntohs. But doing this gives it to me in big endian, which is what I don't want.

    Really all I am asking is there something done under the hood that automatically converts it to little endian when I pull it out of the buffer?

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Strange.
    Maybe try to reverse the byte order by yourself instead of doing that with ntohs. Like:
    Code:
    memcpy(data, buffer->buffer_data + offset + 1, 1);
    memcpy(data + 1, buffer->buffer_data + offset, 1);
    And check again.

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    There's nothing magical happening, it's all within your code. Read it one byte at a time and you'll see that it is as it should be.
    You haven't shown the code for buffer_add_int16.
    Just step through both functions with a debugger. If there's something wrong you'll spot it soon enough.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Code:
    word ChangeEndianness(word temp){
       char junk;
      
       junk = *(char*)&temp;
       temp << 8;
       temp = temp | junk;
     
       return temp;
       }
    or

    Code:
    word ChangeEndianness_Fast(word temp){
    
       __asm {
          mov ax , temp
          xchg ah , al
          mov temp , ax
          }
    
       return temp;
       }
    Last edited by abachler; 01-07-2009 at 12:28 PM.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by abachler View Post
    Code:
    word ChangeEndianness(word temp){
       char junk;
      
       junk = *(char*)&temp;
       temp << 8;
       temp = temp | junk;
     
       return temp;
       }
    or

    Code:
    word ChangeEndianness_Fast(word temp){
    
       __asm {
          mov ax , temp
          xchg ah , al
          mov temp , ax
          }
    
       return temp;
       }
    Why reinvent the wheel? Just use ntohs() & htons()...
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  6. #6
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Because I dont like the whole wheel thing, its too roundy, I want something thats more efficient.

  7. #7
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Are you using the loopback address mechanism or are you actually sending the data over the wire ie sending and receiving hosts are different

  8. #8
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    The interface is simple enough to spare those manual checkings, you don't even have to know your host encoding or the network encoding, simply use htons/nl() when you send a 16 or 32 bits integer and ntohs/l() when you receive it. This is the portable way. Besides, if you _know_ the sender and the receiver have the same architecture (let's say intel-like), you don't even have to encode/decode it... just ensure the header part of the packets is correctly encoded, your data is not used by the network layers anyway.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by abachler View Post
    Because I dont like the whole wheel thing, its too roundy, I want something thats more efficient.
    And you have measured the existing ntohs() etc, and found that your code is faster? Because I've at least seen some implementatins where the macro expansion or code in the function does something very similar to what you posted here - so I'm not sure there's much to be gained.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Big Endian Little Endian Complex- Converting Characters
    By bd02eagle in forum C Programming
    Replies: 3
    Last Post: 07-11-2006, 01:01 AM
  2. Big and little endian
    By Cactus_Hugger in forum C Programming
    Replies: 4
    Last Post: 10-12-2005, 07:07 PM
  3. Replies: 10
    Last Post: 06-26-2005, 11:27 AM
  4. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM