2
0
mirror of https://github.com/boostorg/uuid.git synced 2026-01-19 04:42:16 +00:00

Add u16 support to endian.hpp

This commit is contained in:
Peter Dimov
2024-04-23 22:29:24 +03:00
parent 43c526386d
commit d7aca60d72
2 changed files with 205 additions and 0 deletions

View File

@@ -46,6 +46,11 @@ namespace detail {
#if defined(__GNUC__) || defined(__clang__)
inline std::uint16_t byteswap( std::uint16_t x )
{
return __builtin_bswap16( x );
}
inline std::uint32_t byteswap( std::uint32_t x )
{
return __builtin_bswap32( x );
@@ -58,6 +63,11 @@ inline std::uint64_t byteswap( std::uint64_t x )
#elif defined(_MSC_VER)
inline std::uint16_t byteswap( std::uint16_t x )
{
return _byteswap_ushort( x );
}
inline std::uint32_t byteswap( std::uint32_t x )
{
return _byteswap_ulong( x );
@@ -70,6 +80,11 @@ inline std::uint64_t byteswap( std::uint64_t x )
#else
inline std::uint16_t byteswap( std::uint16_t x )
{
return static_cast<std::uint16_t>( x << 8 | x >> 8 );
}
inline std::uint32_t byteswap( std::uint32_t x )
{
std::uint32_t step16 = x << 16 | x >> 16;
@@ -94,6 +109,47 @@ inline __uint128_t byteswap( __uint128_t x )
#endif
// load_*_u16
inline std::uint16_t load_native_u16( void const* p )
{
std::uint16_t tmp;
std::memcpy( &tmp, p, sizeof( tmp ) );
return tmp;
}
inline std::uint16_t load_little_u16( void const* p )
{
std::uint16_t tmp;
std::memcpy( &tmp, p, sizeof( tmp ) );
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_LITTLE_ENDIAN
return tmp;
#else
return detail::byteswap( tmp );
#endif
}
inline std::uint16_t load_big_u16( void const* p )
{
std::uint16_t tmp;
std::memcpy( &tmp, p, sizeof( tmp ) );
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_BIG_ENDIAN
return tmp;
#else
return detail::byteswap( tmp );
#endif
}
// load_*_u32
inline std::uint32_t load_native_u32( void const* p )
@@ -221,6 +277,35 @@ inline __uint128_t load_big_u128( void const* p )
#endif
// store_*_u16
inline void store_native_u16( void* p, std::uint16_t v )
{
std::memcpy( p, &v, sizeof( v ) );
}
inline void store_little_u16( void* p, std::uint16_t v )
{
#if BOOST_UUID_BYTE_ORDER != BOOST_UUID_ORDER_LITTLE_ENDIAN
v = detail::byteswap( v );
#endif
std::memcpy( p, &v, sizeof( v ) );
}
inline void store_big_u16( void* p, std::uint16_t v )
{
#if BOOST_UUID_BYTE_ORDER != BOOST_UUID_ORDER_BIG_ENDIAN
v = detail::byteswap( v );
#endif
std::memcpy( p, &v, sizeof( v ) );
}
// store_*_u32
inline void store_native_u32( void* p, std::uint32_t v )

View File

@@ -10,6 +10,24 @@ int main()
{
namespace detail = boost::uuids::detail;
// byteswap u16
{
std::uint16_t x = 0x0102;
std::uint16_t y = 0x0201;
BOOST_TEST_EQ( detail::byteswap( x ), y );
BOOST_TEST_EQ( detail::byteswap( y ), x );
}
{
std::uint16_t x = 0xFFEE;
std::uint16_t y = 0xEEFF;
BOOST_TEST_EQ( detail::byteswap( x ), y );
BOOST_TEST_EQ( detail::byteswap( y ), x );
}
// byteswap u32
{
@@ -60,6 +78,48 @@ int main()
#endif
// load u16
{
std::uint16_t x = 0x0102;
std::uint16_t y = 0x0201;
unsigned char data[] = { 0x01, 0x02 };
BOOST_TEST_EQ( detail::load_little_u16( data ), y );
BOOST_TEST_EQ( detail::load_big_u16( data ), x );
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_LITTLE_ENDIAN
BOOST_TEST_EQ( detail::load_native_u16( data ), y );
#else
BOOST_TEST_EQ( detail::load_native_u16( data ), x );
#endif
}
{
std::uint16_t x = 0xFFEE;
std::uint16_t y = 0xEEFF;
unsigned char data[] = { 0xFF, 0xEE };
BOOST_TEST_EQ( detail::load_little_u16( data ), y );
BOOST_TEST_EQ( detail::load_big_u16( data ), x );
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_LITTLE_ENDIAN
BOOST_TEST_EQ( detail::load_native_u16( data ), y );
#else
BOOST_TEST_EQ( detail::load_native_u16( data ), x );
#endif
}
// load u32
{
@@ -170,6 +230,66 @@ int main()
#endif
// store u16
{
std::uint16_t x = 0x0102;
std::uint16_t y = 0x0201;
unsigned char data[ 2 ] = {};
detail::store_little_u16( data, x );
BOOST_TEST_EQ( detail::load_little_u16( data ), x );
BOOST_TEST_EQ( detail::load_big_u16( data ), y );
detail::store_big_u16( data, x );
BOOST_TEST_EQ( detail::load_little_u16( data ), y );
BOOST_TEST_EQ( detail::load_big_u16( data ), x );
detail::store_native_u16( data, x );
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_LITTLE_ENDIAN
BOOST_TEST_EQ( detail::load_little_u16( data ), x );
BOOST_TEST_EQ( detail::load_big_u16( data ), y );
#else
BOOST_TEST_EQ( detail::load_little_u16( data ), y );
BOOST_TEST_EQ( detail::load_big_u16( data ), x );
#endif
}
{
std::uint16_t x = 0xFFEE;
std::uint16_t y = 0xEEFF;
unsigned char data[ 2 ] = {};
detail::store_little_u16( data, x );
BOOST_TEST_EQ( detail::load_little_u16( data ), x );
BOOST_TEST_EQ( detail::load_big_u16( data ), y );
detail::store_big_u16( data, x );
BOOST_TEST_EQ( detail::load_little_u16( data ), y );
BOOST_TEST_EQ( detail::load_big_u16( data ), x );
detail::store_native_u16( data, x );
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_LITTLE_ENDIAN
BOOST_TEST_EQ( detail::load_little_u16( data ), x );
BOOST_TEST_EQ( detail::load_big_u16( data ), y );
#else
BOOST_TEST_EQ( detail::load_little_u16( data ), y );
BOOST_TEST_EQ( detail::load_big_u16( data ), x );
#endif
}
// store u32
{