-
-
Save 00mjk/6eac258b7e1c5b63611ebead0cc3c5ec to your computer and use it in GitHub Desktop.
Big Endian and Little Endian Convert
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// read a little-endian number from memory into native byte order. | |
uint16_t read_le16( const void* p ); | |
uint32_t read_le32( const void* p ); // see read_le16 | |
uint64_t read_le64( const void* p ); // see read_le16 | |
// read a big-endian number from memory into native byte order. | |
uint16_t read_be16( const void* p ); | |
uint32_t read_be32( const void* p ); // see read_be16 | |
uint64_t read_be64( const void* p ); // see read_be16 | |
// write a little-endian number to memory in native byte order. | |
void write_le16( void* p, uint16_t x ); | |
void write_le32( void* p, uint32_t x ); // see write_le16 | |
void write_le64( void* p, uint64_t x ); // see write_le16 | |
// write a big-endian number to memory in native byte order. | |
void write_be16( void* p, uint16_t x ); | |
void write_be32( void* p, uint32_t x ); // see write_be16 | |
void write_be64( void* p, uint64_t x ); // see write_be16 | |
/** | |
* zero-extend \<size\> (truncated to 8) bytes of little-endian data to uint64_t, | |
* starting at address \<p\> (need not be aligned). | |
**/ | |
uint64_t movzx_le64( const uint8_t * p, size_t size_bytes ); | |
uint64_t movzx_be64( const uint8_t * p, size_t size_bytes ); | |
/** | |
* sign-extend \<size\> (truncated to 8) bytes of little-endian data to int64_t, | |
* starting at address \<p\> (need not be aligned). | |
**/ | |
int64_t movsx_le64( const uint8_t * p, size_t size_bytes ); | |
int64_t movsx_be64( const uint8_t * p, size_t size_bytes ); | |
// read a little-endian number from memory into native byte order. | |
uint16_t read_le16( const void* p ) | |
{ | |
return TO_LE16( *(uint16_t* )p ); | |
} | |
uint32_t read_le32( const void* p ) | |
{ | |
return TO_LE32( *(uint32_t* )p ); | |
} // see read_le16 | |
uint64_t read_le64( const void* p ) | |
{ | |
return TO_LE64( *(uint64_t* )p ); | |
} // see read_le16 | |
// read a big-endian number from memory into native byte order. | |
uint16_t read_be16( const void* p ) | |
{ | |
return TO_BE16( *(uint16_t* )p ); | |
} | |
uint32_t read_be32( const void* p ) | |
{ | |
return TO_BE32( *(uint32_t* )p ); | |
} // see read_be16 | |
uint64_t read_be64( const void* p ) | |
{ | |
return TO_BE64( *(uint64_t* )p ); | |
} // see read_be16 | |
// write a little-endian number to memory in native byte order. | |
void write_le16( void* p, uint16_t x ) | |
{ | |
*(uint16_t*) p = TO_LE16( x ); | |
} | |
void write_le32( void* p, uint32_t x ) | |
{ | |
*(uint32_t*) p = TO_LE32( x ); | |
} // see write_le16 | |
void write_le64( void* p, uint64_t x ) | |
{ | |
*(uint64_t*) p = TO_LE64( x ); | |
} // see write_le16 | |
// write a big-endian number to memory in native byte order. | |
void write_be16( void* p, uint16_t x ) | |
{ | |
*(uint16_t*) p = TO_BE16( x ); | |
} | |
void write_be32( void* p, uint32_t x ) | |
{ | |
*(uint32_t*) p = TO_BE32( x ); | |
} // see write_be16 | |
void write_be64( void* p, uint64_t x ) | |
{ | |
*(uint64_t*) p = TO_BE64( x ); | |
} // see write_be16 | |
/** | |
* zero-extend \<size\> (truncated to 8) bytes of little-endian data to uint64_t, | |
* starting at address \<p\> (need not be aligned). | |
**/ | |
uint32_t std_min( size_t a, size_t b ) | |
{ | |
if ( a < b ) | |
return a; | |
else | |
return b; | |
} | |
uint64_t movzx_le64( const uint8_t * p, size_t size_bytes ) | |
{ | |
uint64_t number = 0; | |
for ( uint32_t i = 0; i < std_min( size_bytes, (size_t) 8u ); i++ ) | |
number |= ( (uint64_t) p[ i ] ) << ( i * 8 ); | |
return number; | |
} | |
uint64_t movzx_be64( const uint8_t * p, size_t size_bytes ) | |
{ | |
uint64_t number = 0; | |
for ( uint32_t i = 0; i < std_min( size_bytes, (size_t) 8u ); i++ ) | |
{ | |
number <<= 8; | |
number |= p[ i ]; | |
} | |
return number; | |
} | |
/** | |
* sign-extend \<size\> (truncated to 8) bytes of little-endian data to int64_t, | |
* starting at address \<p\> (need not be aligned). | |
**/ | |
inline int64_t SignExtend( uint64_t bits, size_t size_bytes ) | |
{ | |
// no point in sign-extending if >= 8 bytes were requested | |
if ( size_bytes < 8 ) | |
{ | |
const uint64_t sign_bit = BIT64( ( size_bytes * 8 ) - 1 ); | |
// number would be negative in the smaller type, | |
// so sign-extend, i.e. set all more significant bits. | |
if ( bits & sign_bit ) | |
{ | |
const uint64_t valid_bit_mask = ( sign_bit + sign_bit ) - 1; | |
bits |= ~valid_bit_mask; | |
} | |
} | |
const int64_t number = (int64_t) ( bits ); | |
return number; | |
} | |
int64_t movsx_le64( const uint8_t * p, size_t size_bytes ) | |
{ | |
const uint64_t number = movzx_le64( p, size_bytes ); | |
return SignExtend( number, size_bytes ); | |
} | |
int64_t movsx_be64( const uint8_t * p, size_t size_bytes ) | |
{ | |
const uint64_t number = movzx_be64( p, size_bytes ); | |
return SignExtend( number, size_bytes ); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if BYTE_ORDER == __ORDER_BIG_ENDIAN__ | |
//Host byte order to network byte order (at compile time) | |
#define HTONS(value) (value) | |
#define HTONL(value) (value) | |
//Network byte order to host byte order (at compile time) | |
#define NTOHS(value) (value) | |
#define NTOHL(value) (value) | |
//Host byte order to little-endian byte order (at compile time) | |
#define HTOLE16(value) __SWAP16__(value) | |
#define HTOLE32(value) __SWAP32__(value) | |
#define HTOLE64(value) __SWAP64__(value) | |
//Little-endian byte order to host byte order (at compile time) | |
#define LETOH16(value) __SWAP16__(value) | |
#define LETOH32(value) __SWAP32__(value) | |
#define LETOH64(value) __SWAP64__(value) | |
//Host byte order to big-endian byte order (at compile time) | |
#define HTOBE16(value) (value) | |
#define HTOBE32(value) (value) | |
#define HTOBE64(value) (value) | |
//Big-endian byte order to host byte order (at compile time) | |
#define BETOH16(value) (value) | |
#define BETOH32(value) (value) | |
#define BETOH64(value) (value) | |
#else | |
//Host byte order to network byte order (at compile time) | |
#define HTONS(value) __SWAP16__(value) | |
#define HTONL(value) __SWAP32__(value) | |
//Network byte order to host byte order (at compile time) | |
#define NTOHS(value) __SWAP16__(value) | |
#define NTOHL(value) __SWAP32__(value) | |
//Host byte order to little-endian byte order (at compile time) | |
#define HTOLE16(value) (value) | |
#define HTOLE32(value) (value) | |
#define HTOLE64(value) (value) | |
//Little-endian byte order to host byte order (at compile time) | |
#define LETOH16(value) (value) | |
#define LETOH32(value) (value) | |
#define LETOH64(value) (value) | |
//Host byte order to big-endian byte order (at compile time) | |
#define HTOBE16(value) __SWAP16__(value) | |
#define HTOBE32(value) __SWAP32__(value) | |
#define HTOBE64(value) __SWAP64__(value) | |
//Big-endian byte order to host byte order (at compile time) | |
#define BETOH16(value) __SWAP16__(value) | |
#define BETOH32(value) __SWAP32__(value) | |
#define BETOH64(value) __SWAP64__(value) | |
#endif | |
#if BYTE_ORDER == __ORDER_BIG_ENDIAN__ | |
// convert a little-endian number to/from native byte order. | |
# define TO_LE16(x) swap16(x) | |
# define TO_LE32(x) swap32(x) | |
# define TO_LE64(x) swap64(x) | |
// convert a big-endian number to/from native byte order. | |
# define TO_BE16(x) (x) | |
# define TO_BE32(x) (x) | |
# define TO_BE64(x) (x) | |
#else | |
// convert a little-endian number to/from native byte order. | |
# define TO_LE16(x) (x) | |
# define TO_LE32(x) (x) | |
# define TO_LE64(x) (x) | |
// convert a big-endian number to/from native byte order. | |
# define TO_BE16(x) swap16(x) | |
# define TO_BE32(x) swap32(x) | |
# define TO_BE64(x) swap64(x) | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment