gmio_core: add 64b functions in byte_codec.h

This commit is contained in:
Hugues Delorme 2016-12-14 15:28:51 +01:00
parent d859adf366
commit f369553af9
2 changed files with 120 additions and 32 deletions

View File

@ -32,54 +32,81 @@
#include "../global.h"
/*! Reads a 16bit integer from memory-location \p bytes (little-endian) */
GMIO_INLINE uint16_t gmio_decode_uint16_le(const uint8_t* bytes)
/* Functions that read NNbit uint from memory (little-endian)
* uintNN_t gmio_decode_uintNN_le(const uint8_t* bytes)
*
* Functions that read NNbit uint from memory (big-endian)
* uintNN_t gmio_decode_uintNN_be(const uint8_t* bytes)
*
* Functions that writes NNbit uint to memory in little-endian
* uintNN_t gmio_encode_uintNN_le(uintNN_t val, uint8_t* bytes);
*
* Functions that writes NNbit uint to memory in big-endian
* uintNN_t gmio_encode_uintNN_be(uintNN_t val, uint8_t* bytes);
*/
GMIO_INLINE uint16_t gmio_decode_uint16_le(const uint8_t* bytes);
GMIO_INLINE uint16_t gmio_decode_uint16_be(const uint8_t* bytes);
GMIO_INLINE void gmio_encode_uint16_le(uint16_t val, uint8_t* bytes);
GMIO_INLINE void gmio_encode_uint16_be(uint16_t val, uint8_t* bytes);
GMIO_INLINE uint32_t gmio_decode_uint32_le(const uint8_t* bytes);
GMIO_INLINE uint32_t gmio_decode_uint32_be(const uint8_t* bytes);
GMIO_INLINE void gmio_encode_uint32_le(uint32_t val, uint8_t* bytes);
GMIO_INLINE void gmio_encode_uint32_be(uint32_t val, uint8_t* bytes);
#ifdef GMIO_HAVE_INT64_TYPE
GMIO_INLINE uint64_t gmio_decode_uint64_le(const uint8_t* bytes);
GMIO_INLINE uint64_t gmio_decode_uint64_be(const uint8_t* bytes);
GMIO_INLINE void gmio_encode_uint64_le(uint64_t val, uint8_t* bytes);
GMIO_INLINE void gmio_encode_uint64_be(uint64_t val, uint8_t* bytes);
#endif /* GMIO_HAVE_INT64_TYPE */
/*
* Implementation
*/
uint16_t gmio_decode_uint16_le(const uint8_t* bytes)
{
/* |0 |1 | */
/* |BB|AA| -> 0xAABB */
return (bytes[1] << 8) | bytes[0];
}
/*! Reads a 16bit integer from memory-location \p bytes (big-endian) */
GMIO_INLINE uint16_t gmio_decode_uint16_be(const uint8_t* bytes)
uint16_t gmio_decode_uint16_be(const uint8_t* bytes)
{
/* |0 |1 | */
/* |AA|BB| -> 0xAABB */
return (bytes[0] << 8) | bytes[1];
}
/*! Writes 16bit integer \p val to the memory location at \p bytes in
* little-endian */
GMIO_INLINE void gmio_encode_uint16_le(uint16_t val, uint8_t* bytes)
void gmio_encode_uint16_le(uint16_t val, uint8_t* bytes)
{
bytes[0] = val & 0xFF;
bytes[1] = (val >> 8) & 0xFF;
}
/*! Reads a 32bit integer from memory-location \p bytes (little-endian) */
GMIO_INLINE uint32_t gmio_decode_uint32_le(const uint8_t* bytes)
void gmio_encode_uint16_be(uint16_t val, uint8_t* bytes)
{
bytes[0] = (val >> 8) & 0xFF;
bytes[1] = val & 0xFF;
}
uint32_t gmio_decode_uint32_le(const uint8_t* bytes)
{
/* |DD|CC|BB|AA| -> 0xAABBCCDD */
return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
}
/*! Reads a 32bit integer from memory-location \p bytes (mixed-endian) */
GMIO_INLINE uint32_t gmio_decode_uint32_me(const uint8_t* bytes)
{
/* |DD|CC|BB|AA| -> 0xCCDDAABB */
return (bytes[0] << 16) | (bytes[1] << 24) | (bytes[3] << 8) | bytes[2];
}
/*! Reads a 32bit integer from memory-location \p bytes (big-endian) */
GMIO_INLINE uint32_t gmio_decode_uint32_be(const uint8_t* bytes)
uint32_t gmio_decode_uint32_be(const uint8_t* bytes)
{
/* |DD|CC|BB|AA| -> 0xDDCCBBAA */
return bytes[3] | (bytes[2] << 8) | (bytes[1] << 16) | (bytes[0] << 24);
}
/*! Writes 32bit integer \p val to the memory location at \p bytes in
* little-endian */
GMIO_INLINE void gmio_encode_uint32_le(uint32_t val, uint8_t* bytes)
void gmio_encode_uint32_le(uint32_t val, uint8_t* bytes)
{
bytes[0] = val & 0xFF;
bytes[1] = (val >> 8) & 0xFF;
@ -87,9 +114,7 @@ GMIO_INLINE void gmio_encode_uint32_le(uint32_t val, uint8_t* bytes)
bytes[3] = (val >> 24) & 0xFF;
}
/*! Writes 32bit integer \p val to the memory location at \p bytes in
* big-endian */
GMIO_INLINE void gmio_encode_uint32_be(uint32_t val, uint8_t* bytes)
void gmio_encode_uint32_be(uint32_t val, uint8_t* bytes)
{
bytes[0] = (val >> 24) & 0xFF;
bytes[1] = (val >> 16) & 0xFF;
@ -97,4 +122,44 @@ GMIO_INLINE void gmio_encode_uint32_be(uint32_t val, uint8_t* bytes)
bytes[3] = val & 0xFF;
}
#ifdef GMIO_HAVE_INT64_TYPE
uint64_t gmio_decode_uint64_le(const uint8_t* bytes)
{
const uint64_t h32 = gmio_decode_uint32_le(bytes + 4); /* Decode high 32b */
return (h32 << 32) | gmio_decode_uint32_le(bytes);
}
uint64_t gmio_decode_uint64_be(const uint8_t* bytes)
{
const uint64_t l32 = gmio_decode_uint32_be(bytes); /* Decode low 32b */
return (l32 << 32) | gmio_decode_uint32_be(bytes + 4);
}
void gmio_encode_uint64_le(uint64_t val, uint8_t* bytes)
{
bytes[0] = val & 0xFF;
bytes[1] = (val >> 8) & 0xFF;
bytes[2] = (val >> 16) & 0xFF;
bytes[3] = (val >> 24) & 0xFF;
bytes[4] = (val >> 32) & 0xFF;
bytes[5] = (val >> 40) & 0xFF;
bytes[6] = (val >> 48) & 0xFF;
bytes[7] = (val >> 56) & 0xFF;
}
void gmio_encode_uint64_be(uint64_t val, uint8_t* bytes)
{
bytes[0] = (val >> 56) & 0xFF;
bytes[1] = (val >> 48) & 0xFF;
bytes[2] = (val >> 40) & 0xFF;
bytes[3] = (val >> 32) & 0xFF;
bytes[4] = (val >> 24) & 0xFF;
bytes[5] = (val >> 16) & 0xFF;
bytes[6] = (val >> 8) & 0xFF;
bytes[7] = val & 0xFF;
}
#endif /* GMIO_HAVE_INT64_TYPE */
#endif /* GMIO_INTERNAL_BYTE_CODEC_H */

View File

@ -60,21 +60,44 @@ static const char* test_internal__byte_swap()
static const char* test_internal__byte_codec()
{
{ /* decode */
const uint8_t data[] = { 0x11, 0x22, 0x33, 0x44 };
const uint8_t data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 };
UTEST_ASSERT(gmio_decode_uint16_le(data) == 0x2211);
UTEST_ASSERT(gmio_decode_uint16_be(data) == 0x1122);
UTEST_ASSERT(gmio_decode_uint32_le(data) == 0x44332211);
UTEST_ASSERT(gmio_decode_uint32_be(data) == 0x11223344);
#ifdef GMIO_HAVE_INT64_TYPE
UTEST_ASSERT(gmio_decode_uint64_le(data) == 0x8877665544332211);
UTEST_ASSERT(gmio_decode_uint64_be(data) == 0x1122334455667788);
#endif
}
{ /* encode */
uint8_t data[] = { 0, 0, 0, 0 };
gmio_encode_uint16_le(0x1122, data);
UTEST_ASSERT(data[0] == 0x22 && data[1] == 0x11);
gmio_encode_uint32_le(0x11223344, data);
UTEST_ASSERT(data[0] == 0x44 && data[1] == 0x33 && data[2] == 0x22 && data[3] == 0x11);
gmio_encode_uint32_be(0x11223344, data);
UTEST_ASSERT(data[3] == 0x44 && data[2] == 0x33 && data[1] == 0x22 && data[0] == 0x11);
uint8_t bytes[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
gmio_encode_uint16_le(0x1122, bytes);
UTEST_ASSERT(bytes[0] == 0x22 && bytes[1] == 0x11);
gmio_encode_uint16_be(0x1122, bytes);
UTEST_ASSERT(bytes[0] == 0x11 && bytes[1] == 0x22);
gmio_encode_uint32_le(0x11223344, bytes);
static const uint8_t bytes_uint32_le[] = { 0x44, 0x33, 0x22, 0x11 };
UTEST_ASSERT(memcmp(bytes, bytes_uint32_le, 4) == 0);
gmio_encode_uint32_be(0x11223344, bytes);
static const uint8_t bytes_uint32_be[] = { 0x11, 0x22, 0x33, 0x44 };
UTEST_ASSERT(memcmp(bytes, bytes_uint32_be, 4) == 0);
#ifdef GMIO_HAVE_INT64_TYPE
gmio_encode_uint64_le(0x1122334455667788, bytes);
static const uint8_t bytes_uint64_le[] =
{ 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 };
UTEST_ASSERT(memcmp(bytes, bytes_uint64_le, 8) == 0);
gmio_encode_uint64_be(0x1122334455667788, bytes);
static const uint8_t bytes_uint64_be[] =
{ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 };
UTEST_ASSERT(memcmp(bytes, bytes_uint64_be, 8) == 0);
#endif
}
return NULL;