What does this line of C code mean?

I am converting C code to Delphi. Can someone 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 Boyan

+4
source share
4 answers

Apparently (all the uppercase ones make it hard to read), functions replace the internal ordering of bytes of values ​​that occupy 2 or 4 bytes. For instance:

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

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

I hope they are already written, and the Delphi library uses them with some name. Check your documentation.


Edit

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

in this line

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

In pBuffer[1] & 0x00FF , only the pBuffer[1] & 0x00FF 8 bits are stored (therefore, 0x1234 becomes 0x0034)

Another operation | is dimensional or

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


Edit: hto * / * toh naming

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

The byte order is not necessarily different (the byte order over the network is byte), so the first part of the function must check whether the host byte order is small or big-endian before performing the swaps ... or the check was performed earlier in a program that uses functions that you posted.

+4
source

You do not need to translate them, just turn on WinSock , it has all four!

+3
source

This seems to be just a swap of bytes, which you can implement very simply:

 function Swap32(const Value: DWORD): DWORD; assembler; asm bswap eax; end; function Swap16(const Value: WORD): WORD; assembler; asm xchg al, ah; end; 
+2
source

rather obscure bitwise expression

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

means that:

 var pBuffer: PByteArray; nResult: Word; 

therefore, Pascal's structured clarity will look like this:

 WordRec(nResult).Hi := pBuffer^[0]; WordRec(nResult).Lo := pBuffer^[1]; 

even the implicit byteswap here is pretty obvious.

0
source

All Articles