Thread: Endian change & Byte Array -> Struct

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    1

    Endian change & Byte Array -> Struct

    So, I recently ran into a problem where I have a byte array { 0, 196, 0, 0, 0, 42 } and I need to copy that into a struct defined as:
    Code:
    typedef struct tdFOO {
      UINT16 ID;
      UINT32 RetVal;
      .
      .
      .
    } FOO;
    Also, the byte order in the byte array needs to be reversed. I'm communicating with a system with a different endianness, so I can't just memcpy the byte array into my structure. Also, when I did try (before I realized the bytes were out of order), the memcpy only populated the first structure variable (ID) and none of the others.

    What I actually need is for the byte array to look like: { 196, 0, 42, 0, 0, 0 }

    Which when copied into the structure would cause ID = 196 and RetVal to = 42

    The only way I can think to do it is to write a function that swaps the appropriate number of bytes based on the type of the struct variable where it will be assigned, and then do a memcpy of the bytes I just swapped directly into the struct variable.

    Then I just do that over, and over, and over again until I've copied every value.

    Thanks!

  2. #2
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Posts
    2,158
    You fail to mention what the sizes of the remaining tdFOO variables are.

    >> Then I just do that over, and over, and over again until I've copied every value.
    Or use a loop.

    You should convert your variables' endianess using hton and ntoh.
    hton(3)

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    the memcpy only populated the first structure variable (ID) and none of the others.
    This would likely be because of padding between the members of your struct. A compiler is free to insert padding anywhere in a struct (except for right at the beginning) in order to align members properly. On a 32-bit system, I would expect there to be 2 bytes of padding after your first member, for example, so that the next one is aligned on a 4-byte boundary.

    I don't see any particular need for a memcpy(). You can do something like:
    Code:
    whatever.ID = swap16(&memory[0]);
    whatever.RetVal = swap32(&memory[2]);
    ...
    If you have control over the other end, I absolutely agree with using the ntoh family of functions if they're available. They're designed precisely for what you're doing.

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Something generic:

    Code:
    void* to_le( void* buf, size_t len )
    {
    	typedef unsigned char byte;
    	typedef byte* pbyte;
    	static size_t const val = 1, res = *( ( pbyte )&val ) == 0;
    	pbyte ptr = ( pbyte )buf, end = ( ptr + len ) - 1;
    	if( res )
    	{
    		for( ; ptr < end; ++ptr, --end )
    		{
    			*ptr ^= *end;
    			*end = *ptr ^ *end;
    			*ptr ^= *end;
    		}
    	}
    	return buf;
    }
    
    void* to_le16( void* buf )
    {
    	return to_le( buf, 2 );
    }
    
    void* to_le32( void* buf )
    {
    	return to_le( buf, 4 );
    }
    
    void* to_le64( void* buf )
    {
    	return to_le( buf, 8 );
    }
    Warning: untested code. =}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Struct (with pointer) to byte array
    By rabencor in forum C Programming
    Replies: 1
    Last Post: 02-08-2009, 05:27 AM
  2. brace-enclosed error
    By jdc18 in forum C++ Programming
    Replies: 53
    Last Post: 05-03-2007, 05:49 PM
  3. Replies: 10
    Last Post: 05-18-2006, 11:23 PM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM