Solved

byte swapping

Posted on 2002-07-22
12
506 Views
Last Modified: 2010-05-18
I was trying to put a integer in little endian into big endian. For example the integer value 4.
0000 0000 0000 0100
and I was expecting the value
0100 0000 0000 0000
16384 or 2^14

I'm not getting that result however.

int main(void){
void *returnVal = NULL;
int val = 4;
 returnVal = byteSwap(&val,sizeof(val));
cout<<"returnVal = "<<*(int *)returnVal<<endl;
}

void *byteSwap(void *src, int numBytes){
char *dst = new char[numBytes];
dst = dst + (numBytes - 1); //start at last byte of new memory block
char *cSrcPtr = (char *)src;
for(int i=0; i < numBytes; i++)
memcpy(dst--,cSrcPtr++,sizeof(char));
//also tried *dst-- = *cSrcPtr++;
return dst;
}

I read that there is a swab function that does this, but I don't have this function on my Linux machine and I want to do it myself anyway.

My end goal is to use this function with structures.
0
Comment
Question by:mitchguy
  • 5
  • 3
  • 2
  • +1
12 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 7169804
Why don't you use

'ntohs()', 'ntohl()'

or

'htons()', 'htonl()'

respectively? They were created for that very purpose:

BYTEORDER(3)        Linux Programmer's Manual        BYTEORDER(3)

NAME
       htonl,  htons,  ntohl, ntohs - convert values between host
       and network byte order

SYNOPSIS
       #include <netinet/in.h>

       unsigned long int htonl(unsigned long int hostlong);

       unsigned short int htons(unsigned short int hostshort);

       unsigned long int ntohl(unsigned long int netlong);

       unsigned short int ntohs(unsigned short int netshort);

DESCRIPTION
       The htonl() function converts the  long  integer  hostlong
       from host byte order to network byte order.

       The  htons() function converts the short integer hostshort
       from host byte order to network byte order.

       The ntohl() function converts  the  long  integer  netlong
       from network byte order to host byte order.

       The  ntohs()  function converts the short integer netshort
       from network byte order to host byte order.

       On the i80x86 the host byte  order  is  Least  Significant
       Byte first, whereas the network byte order, as used on the
       Internet, is Most Significant Byte first.

CONFORMING TO
       BSD 4.3

SEE ALSO
       gethostbyname(3), getservent(3)
0
 
LVL 30

Accepted Solution

by:
Zoppo earned 100 total points
ID: 7169815
BTW, a simple byte swap function could be done like:

void
swapBytes( char* pszText, int iLen )
{
     int iEnd = iLen >> 1;
     iLen--;
     for ( int i = 0; i < iEnd; i++ )
     {
          pszText[i] ^= pszText[iLen-i];
          pszText[iLen-i] ^= pszText[i];
          pszText[i] ^= pszText[iLen-i];
     }
}

int main()
{
     char* pszText = strdup( "0123456789" );
     cout << pszText << endl;
     swapBytes( pszText, strlen( pszText ) );
     cout << pszText << endl;
     return 0;
}


Output:

0123456789
9876543210


ZOPPO
0
 
LVL 86

Expert Comment

by:jkr
ID: 7169830
>>My end goal is to use this function with structures.

You'd only have to apply the byte order change to struct members that are in fact integers, everything else (e.g. strings, binary data) has to remain "untouched".
0
 
LVL 32

Expert Comment

by:jhance
ID: 7170049
jkr,

I question the wisdom of using any of:

'ntohs()', 'ntohl()', 'htons()', 'htonl()'

to perform a general purpose byte swapping operation.  

On some platforms these functions do nothing because the machine byte-order matches the network byte-order.
0
 
LVL 86

Expert Comment

by:jkr
ID: 7170069
>>to perform a general purpose byte swapping operation

Sure, but the question was "I was trying to put a integer in little endian into big endian"

>>On some platforms these functions do nothing

And that's what they are for - otherwise, the programmer would have to take care whether an endianity conversion was required or not. By using these, you will be on the safe side, as these functions will take care about what to do depending on the platform the same source code was compiled on.
0
 
LVL 32

Expert Comment

by:jhance
ID: 7170087
Well, I agree that it is possible that these functions may do what is needed but again, in the general case, these are not reliable for byte swapping due to the reasons mentioned above.

Of course it's hard to say for sure since the question is somewhat ambiguous....

I just wanted to point out that on SOME platforms, these functions are intended to do nothing.  And in this case the "reference point" is how the TCPIP protocol defines byte ordering, not big vs. little endian.  These functions are intended to translate from MACHINE to NETWORK byte order and back regardless of what the host machine uses.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:mitchguy
ID: 7170271
I do want a general purpose byte swapping algorithm. sorry for the ambiguity. I will be sending messages back and fourth from client/server. The packets will be messages which are structures containing different types and sizes.

ZOPPO
Your example seems to work fine for strings but not for integers.

jkr
I didn't quite understand what you meant by
"You'd only have to apply the byte order change to struct members that are in fact integers, everything else (e.g. strings, binary data) has to remain "untouched"."
0
 
LVL 86

Expert Comment

by:jkr
ID: 7170280
>>I didn't quite understand what you meant

That's pretty unambiguous: Binary data and strings are not byte-order dependant such as integers and floats, so you will not want to 'swap bytes' for them.
0
 

Author Comment

by:mitchguy
ID: 7170310
jkr
I thought strings also needed to be accounted for.
0
 
LVL 86

Expert Comment

by:jkr
ID: 7170329
>>I thought strings also needed to be accounted for.

No, certainly not. If you'd do that, the 'other' side will receive garbage. That also applies to UNICODE, even though it's tech. speaking an 'unsigned short, but it comes with a byte order mark.
0
 

Author Comment

by:mitchguy
ID: 7170440
I make a mistake, it works fine for integers as you probably already know.
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 7171120
excuse me for late response, but I wrote my comment directly before I left the office...

have a nice day,

regards,

ZOPPO
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now