ntoh16 与 hton16

本文介绍了将主机字节序转换为网络字节序的函数 hton16 和 hton32,以及相反操作的函数 ntoh16 和 ntoh32。这些函数对于实现网络通信中的数据格式统一至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
    * Functions hton16 and hton32 convert the host
    * representation of integer numbers into the network
    * representation as defined in "Trivial Internet Protocol",
    * section 2.1.
    * ntoh32 and ntoh16 are reverse functions to hton32 and hton16.
    *
    * Adjust the following definitions for the particular
    * hardware and C complier.
    */
   #define hton16(n) (((uint16)(n) >> 8) | ((uint16)(n) << 8))
   #define hton32(n) (ntoh16((uint32)(n) >> 16) | (ntoh16(n) << 16))
   #define ntoh16(n) hton16(n)
   #define ntoh32(n) hton32(n)

TS_MOD_PRIV_DEFN FUNC(uint16, TCPIP_CODE) TcpIp_CalcSum16Bit ( P2CONST(uint8, AUTOMATIC, TCPIP_APPL_DATA) dataPtr, uint16 initValue, uint16 length ) { #if (defined HAS_64BIT_TYPES) /* 64 bit architecture / types / memory bus */ typedef uint64 A_Type; typedef uint32 A2_Type; /* half an accumulator */ uint64 TcpIp_accu= 0u; /* 48 bit accumulator, so we retain the overflow of the 32bit adds - high part is only carry bits so < 16bits */ #else /* 32 bit architecture / types / memory bus */ typedef uint32 A_Type; typedef uint16 A2_Type; /* half an accumulator */ /* local alias to w32, using the TcpIp namespace to trigger define guard,... */ /* TCPIP_ACCU/TcpIp_accu defined as w32. w32 is already used for the peeling iterations and initialized with initValue */ #endif /* (defined HAS_64BIT_TYPES) */ const uint16 maxAlignment= sizeof(A_Type); const uint8 halfBits= sizeof(A2_Type)*8u; /* do we need to swap result bytes for LE ^ odd start address? */ /* Deviation MISRAC2012-8 */ uint8 shift= (((uint8)1u) & (uint8)(TS_IF_BE_LE((uint8),(uint8) ~(uint8)) ((uint32)(&dataPtr[0u])))) << 3u; /* 32 bit accumulator for 16-bit values - 64kB -> 32k carries max, so it can't overflow */ uint32 w32= ((uint32)initValue) << shift; /* put the initValue in the right place for its alignment! */ uint16_least index= 0u; /* MISRA -> must rely on compiler to do strength reduction */ /* peel till it's aligned */ if (!TCPIP_ISALIGNED(&dataPtr[index],maxAlignment) && (length > 0u)) { /* Deviation MISRAC2012-8 */ uint16 len1= maxAlignment - (((uint16)(usize)&dataPtr[index]) & (maxAlignment-1u)); /* len1 > 0 */ uint16 fatbool= TS_FATBOOL(uint16, length < len1); uint16 len2= TS_SELECT(uint16, fatbool, length,len1); /* now peel len2 iterations - len2 > 0 since length & len2 were both > 0 */ length-= len2; do { /* shift by 8 or 0 bits depending on alignment vs LE/BE */ w32 += TCPIP_SHIFTCHECKSUMBYTE(dataPtr[index]); ++index; --len2; } while (len2 > 0); } /* if (length!=0u) -- skip remaining loops! */ /* only aligned starts or length==0 comes here (but length=0 should've been jumping to the end of the loop (jump2jump opt) */ /* if 64bit is possible: read uint64, sum 32bit halves - LE/BE is don't care (associativity) & cyclical carry */ /* otherwise: read uint32, sum 16bit halves - LE/BE is don't care (associativity) & cyclical carry */ if (length >= maxAlignment) /* use the guarding-if from the compiler's loop-rotation to speed up short cases */ { do { /* Deviation MISRAC2012-9 */ const A_Type read= *((P2CONST(A_Type, AUTOMATIC, TCPIP_APPL_DATA))(&dataPtr[index])); TCPIP_ACCU += ((A_Type)((A2_Type)(read >> halfBits))) + ((A2_Type)read); index += maxAlignment; length -= maxAlignment; } while(length >= maxAlignment); #if (defined HAS_64BIT_TYPES) /* if we used a 64bit accu, fold the 2 16bit SIMD accumulators + 16bit carry parts into 32bit */ { /* mixed strategy for 32bit architectures with costly 64 bit ops: reduce to 32bit registers and avoid all 32bit overflows */ uint32 hi32= (uint32)(TCPIP_ACCU >> 32u); /* usually just takes the hi register (half) */ uint32 lo32= (uint32) TCPIP_ACCU; /* usually just takes the lo register (half) */ /* the rest of the computation is in 32 bit registers, without 32bit overflows: w32 is 24 bits max (initValue16 << 8) hi32 only contains the carry bits of 16k uint32 adds, so < 14 bits, so the high 18 bits are zero -> no narrowing Only the 2 lo values are full 16 bits and may produce a carry into the high part which holds the upper byte of initValue at most */ w32+= hi32 + (lo32 >> 16u) + ((uint16)lo32); } #endif /* (defined HAS_64BIT_TYPES) */ } /* now peel till we're done */ if (length > 0u) { do { /* shift by 8 or 0 bits depending on alignment vs LE/BE */ w32 += TCPIP_SHIFTCHECKSUMBYTE(dataPtr[index]); ++index; --length; } while(length > 0u); } { uint16 w16; w32= (w32 >> 16u) + ((uint16)w32); w16= ((uint16)(w32 >> 16u)) + ((uint16)w32); /* now swap the bytes for LE (HTON/NTOH), leave them for BE (& the other way round, if the address was odd) */ if (shift != 0u) { w16= COMSTACK_BYTE_MIRROR16(w16); /* __ROR(w16, shift), if there was a portable primitive */ } return w16; } }
最新发布
07-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值