Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does this line of C code mean?

Tags:

c++

c

delphi

I'm converting some C code to Delphi. Can someone please explain to me what this line means?

nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00 )
 | ( pBuffer[ 1 ] & 0x00FF );

Here is the rest of the code for context:

USHORT UTIL_htons( USHORT hostshort )
{
 PUCHAR pBuffer;
 USHORT nResult;

 nResult = 0;
 pBuffer = (PUCHAR )&hostshort;

 nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00 )
  | ( pBuffer[ 1 ] & 0x00FF );

 return( nResult );
}

USHORT UTIL_ntohs( USHORT netshort )
{
 return( UTIL_htons( netshort ) );
}
ULONG UTIL_htonl( ULONG hostlong )
{
 PUCHAR pBuffer;
 ULONG nResult;
 UCHAR c, *pResult;

 pBuffer = (PUCHAR )&hostlong;

 if( !pBuffer )
 {
  return( 0L );
 }

 pResult = (UCHAR * )&nResult;

 c = ((UCHAR * )pBuffer)[ 0 ];
 ((UCHAR * )pResult)[ 0 ] = ((UCHAR * )pBuffer)[ 3 ];
 ((UCHAR * )pResult)[ 3 ] = c;

 c = ((UCHAR * )pBuffer)[ 1 ];
 ((UCHAR * )pResult)[ 1 ] = ((UCHAR * )pBuffer)[ 2 ];
 ((UCHAR * )pResult)[ 2 ] = c;

 return( nResult );
}
ULONG UTIL_ntohl( ULONG netlong )
{
 return( UTIL_htonl( netlong ) );
}

Thanks in advance Bojan

like image 414
bojan gavrilovic Avatar asked Jan 22 '23 02:01

bojan gavrilovic


2 Answers

Apparently (all those defines in uppercase make it hard reading) the functions are swapping the internal byte ordering of values that occupy 2 or 4 bytes. For example:

UTIL_htons(0x1234); /* returns 0x3412 */
UTIL_htonl(0x12345678); /* returns 0x78563412 */

I have no idea how to write them in Delphi ...

Hopefully they are already written and the library Delphi uses has them with some name or other. Check your documentation.


Edit

nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00 ) | ( pBuffer[ 1 ] & 0x00FF );

in this line

pBuffer[0] is the first element of the array pBuffer
pBuffer[0] << 8 is shifting that value 8 bits to the left (0x12 becomes 0x1200)
(...) & 0xFF00 is redundant: it resets the rightmost 8 bits

In pBuffer[1] & 0x00FF only the rightmost 8 bits are kept (so 0x1234 becomes 0x0034)

The other operation | is a bitwise or

( ... & 0xFF00) | ( ... & 0xFF00) is the leftmost 8 bits of the first part and the rightmost 8 bits of the second part.


Edit: hto* / *toh naming

The functions htonl, htons, ntohl, ntohs in C are used to convert values between host and network byte order.

The byte ordering is not necessarily different (network byte order is big-endian), so the first part of the functions should check if the host byte ordering is little- or big-endian before doing the swaps ... or the check was done previously in the program that uses the functions you posted.

like image 184
pmg Avatar answered Jan 31 '23 13:01

pmg


You do not have to translate them, just include WinSock, it has all four of them!

like image 33
Jens Mühlenhoff Avatar answered Jan 31 '23 15:01

Jens Mühlenhoff