/**
* \file byteorder.c
*
* We want libnjb to be "endianness agnostic" i.e. the byte-ordering
* of the libnjb host platform shall not affect its functionality.
* These routines are written using shifting and byte operations that
* will produce the same result regardless of whether the host
* platform is little-endian, big-endian or even mixed-endian.
*
* NJB1 and the "series 3 family" (NJB2, NJB3, NJB Zen, NJB Zen 2.0) have
* different byte ordering. NJB1 is essentially big-endian, and the
* series 3 family little-endian. The terminology could be confusing,
* so we refer to the different endiannesses as "njb1-endian" and
* "njb3-endian".
*/
#include "libnjb.h"
#include "byteorder.h"
/**
* This function will take 8 bytes from the njb1-endian byte array
* pointed to by *dp and transform it to a
* u_int64_t on the host platform.
*
* @param dp a pointer to the 8 raw bytes in NJB1 endianness to convert
* @return an unsigned 64 bit integer
*/
u_int64_t njb1_bytes_to_64bit(unsigned char *dp)
{
u_int64_t ret;
ret = ((u_int64_t) dp[3] << 56);
ret = ret | ((u_int64_t) dp[2] << 48);
ret = ret | ((u_int64_t) dp[1] << 40);
ret = ret | ((u_int64_t) dp[0] << 32);
ret = ret | ((u_int64_t) dp[7] << 24);
ret = ret | ((u_int64_t) dp[6] << 16);
ret = ret | ((u_int64_t) dp[5] << 8);
ret = ret | (u_int64_t) dp[4];
return ret;
}
/**
* This function will write the u_int64_t of the
* host platform, val as NJB1-endian bytes
* beginning at the first byte in the byte array pointed to by
* *dp.
*
* @param val the unsigned 64 bit integer to convert to bytes
* @param dp a pointer to the byte array (of atleast 8 bytes)
* that shall hold the resulting bytes
*/
void from_64bit_to_njb1_bytes(u_int64_t val, unsigned char *dp)
{
dp[0] = (val >> 32) & 255;
dp[1] = (val >> 40) & 255;
dp[2] = (val >> 48) & 255;
dp[3] = (val >> 56) & 255;
dp[4] = val & 255;
dp[5] = (val >> 8) & 255;
dp[6] = (val >> 16) & 255;
dp[7] = (val >> 24) & 255;
}
/**
* This function will take 4 bytes from the NJB1-endian byte array
* pointed to by *dp and transform it to a
* u_int32_t on the host platform.
*
* @param dp a pointer to the 4 raw bytes in NJB1 endianness to convert
* @return an unsigned 32 bit integer
*/
u_int32_t njb1_bytes_to_32bit(unsigned char *dp)
{
u_int32_t ret;
ret = ((u_int32_t) dp[3] << 24);
ret = ret | ((u_int32_t) dp[2] << 16);
ret = ret | ((u_int32_t) dp[1] << 8);
ret = ret | (u_int32_t) dp[0];
return ret;
}
/**
* This function will take 4 bytes from the series 3-endian byte array
* pointed to by *dp and transform it to a
* u_int32_t on the host platform.
*
* @param dp a pointer to the 4 raw bytes in series 3 endianness to convert
* @return an unsigned 32 bit integer
*/
u_int32_t njb3_bytes_to_32bit(unsigned char *dp)
{
u_int32_t ret;
ret = ((u_int32_t) dp[0] << 24);
ret = ret | ((u_int32_t) dp[1] << 16);
ret = ret | ((u_int32_t) dp[2] << 8);
ret = ret | (u_int32_t) dp[3];
return ret;
}
/**
* This function will write the u_int32_t of the host
* platform, val as 4 NJB1-endian bytes beginning at
* the first byte in the byte array pointed to by *dp.
*
* @param val the unsigned 32 bit integer to convert to bytes
* @param dp a pointer to the byte array (of atleast 4 bytes)
* that shall hold the resulting bytes
*/
void from_32bit_to_njb1_bytes(u_int32_t val, unsigned char *dp)
{
dp[0] = val & 255;
dp[1] = (val >> 8) & 255;
dp[2] = (val >> 16) & 255;
dp[3] = (val >> 24) & 255;
}
/**
* This function will write the u_int32_t of the host
* platform, val as 4 series 3-endian bytes beginning at
* the first byte in the byte array pointed to by *dp.
*
* @param val the unsigned 32 bit integer to convert to bytes
* @param dp a pointer to the byte array (of atleast 4 bytes)
* that shall hold the resulting bytes
*/
void from_32bit_to_njb3_bytes(u_int32_t val, unsigned char *dp)
{
dp[0] = (val >> 24) & 255;
dp[1] = (val >> 16) & 255;
dp[2] = (val >> 8) & 255;
dp[3] = val & 255;
}
/**
* This function will take 2 bytes from the NJB1-endian byte array
* pointed to by *dp and transform it to
* a u_int16_t unsigned 16 bit integer on the host
* platform.
*
* @param dp a pointer to the 2 raw bytes in NJB1 endianness to convert
* @return an unsigned 16 bit integer
*/
u_int16_t njb1_bytes_to_16bit(unsigned char *dp)
{
u_int16_t ret;
ret = ((u_int16_t) dp[1] << 8);
ret = ret | (u_int16_t) dp[0];
return ret;
}
/**
* This function will take 2 bytes from the series 3-endian byte array
* pointed to by *dp and transform it to
* a u_int16_t unsigned 16 bit integer on the host
* platform.
*
* @param dp a pointer to the 2 raw bytes in series 3 endianness to convert
* @return an unsigned 16 bit integer
*/
u_int16_t njb3_bytes_to_16bit(unsigned char *dp)
{
u_int16_t ret;
ret = ((u_int16_t) dp[0] << 8);
ret = ret | (u_int16_t) dp[1];
return ret;
}
/**
* This function will write the u_int16_t of the host
* platform, val as 2 NJB1-endian bytes beginning at the
* first byte in the byte array pointed to by *dp.
*
* @param val the unsigned 16 bit integer to convert to bytes
* @param dp a pointer to the byte array (of atleast 2 bytes)
* that shall hold the resulting bytes
*/
void from_16bit_to_njb1_bytes(u_int16_t val, unsigned char *dp)
{
dp[0] = val & 255;
dp[1] = (val >> 8) & 255;
}
/**
* This function will write the u_int16_t of the host
* platform, val as 2 series 3-endian bytes beginning at the
* first byte in the byte array pointed to by *dp.
*
* @param val the unsigned 16 bit integer to convert to bytes
* @param dp a pointer to the byte array (of atleast 2 bytes)
* that shall hold the resulting bytes
*/
void from_16bit_to_njb3_bytes(u_int16_t val, unsigned char *dp)
{
dp[0] = (val >> 8) & 255;
dp[1] = val & 255;
}
/**
* This simply extract the most significant 16 bit parts of
* a 32 bit word.
*
* @param word the 32 bit word to get the most significant 16 bits
* for
* @return the most significant 16 bits as a 16 bit unsigned integer
*/
u_int16_t get_msw (u_int32_t word)
{
return (u_int16_t) (word >> 16) & 0xffff;
}
/**
* This simply extract the least significant 16 bit parts of
* a 32 bit word.
*
* @param word the 32 bit word to get the least significant 16 bits
* for
* @return the least significant 16 bits as a 16 bit unsigned integer
*/
u_int16_t get_lsw (u_int32_t word)
{
return (u_int16_t) word & 0xffff;
}
/**
* Create a 64 bit unsigned integer from two 32 bit integers
* representing the most/least significant part of it.
*
* @param msdw the most significant 32 bits
* @param lsdw the least significant 32 bits
* @return a 64 bit unsigned integer made by joining the two
* parts
*/
u_int64_t make64 (u_int32_t msdw, u_int32_t lsdw)
{
u_int64_t val;
val= msdw * 0x100000000ULL + lsdw;
return val;
}
/**
* Split a 64 bit unsigned integer into two unsigned 32 bit
* integer representing the most/least significant 32 bits
* of the incoming 64 bit integer.
*
* @param num the 64 bit integer to split
* @param msdw a pointer to the 32 bit integer that shall hold
* the most significant 32 bits of the 64 bit integer
* @param lsdw a pointer to the 32 bit integer that shall hold
* the least significant 32 bits of the 64 bit integer
*/
void split64 (u_int64_t num, u_int32_t *msdw, u_int32_t *lsdw)
{
u_int64_t val= num/0x100000000ULL;
*msdw= (u_int32_t) val;
*lsdw= (u_int32_t) ( num - val*0x100000000ULL );
}