265 lines
6.6 KiB
C
265 lines
6.6 KiB
C
#ifndef UC_PACK_H_
|
|
#define UC_PACK_H_
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifndef UC_INLINE
|
|
#ifdef __GNUC__
|
|
# ifdef __clang__
|
|
# define UC_INLINE inline __attribute__((always_inline))
|
|
# else
|
|
# define UC_INLINE inline __attribute__((always_inline,flatten))
|
|
# endif
|
|
#else
|
|
# define UC_INLINE inline
|
|
#endif
|
|
#endif
|
|
|
|
/** Functions for serializing/de-serializing integers to and from
|
|
* byte arrays.
|
|
* These functions are independant of the host endian. Only
|
|
* thing to care about is the endian format of the data in
|
|
* the byte array.
|
|
*/
|
|
|
|
|
|
/** Serialize a uint16_t to a byte array in little endian format.
|
|
* @param v The value to serialize
|
|
* @param r The byte array to place the integer in. Must be at least of size 2.
|
|
*/
|
|
static UC_INLINE void uc_pack_16_le(uint16_t v, uint8_t *r)
|
|
{
|
|
r[0] = v;
|
|
r[1] = v >> 8;
|
|
}
|
|
|
|
/** De-serialize a uint16_t from a byte array in little endian format.
|
|
* @param r The byte array to containing the integer in. Must be at least of size 2.
|
|
* @param return The deserialized integer from the byte array.
|
|
*/
|
|
static UC_INLINE uint16_t uc_unpack_16_le(const uint8_t *r)
|
|
{
|
|
uint32_t v;
|
|
|
|
v = r[0];
|
|
v |= r[1] << 8;
|
|
|
|
return v;
|
|
}
|
|
|
|
/** Serialize a uint32_t to a 3 byte(24 bits) array in little endian format.
|
|
* Only the bottom 24 bits of the uint32_t are used.
|
|
*
|
|
* @param v The value to serialize
|
|
* @param r The byte array to place the integer in. Must be at least of size 3.
|
|
*/
|
|
static UC_INLINE void uc_pack_24_le(uint32_t v, uint8_t *r)
|
|
{
|
|
r[0] = v;
|
|
r[1] = v >> 8;
|
|
r[2] = v >> 16;
|
|
}
|
|
|
|
/** De-serialize a uint32_t from a 3 byte (24 bit) byte array in little endian format.
|
|
* @param r The byte array to containing the integer in. Must be at least of size 3.
|
|
* @param return The deserialized integer from the byte array.
|
|
*/
|
|
static UC_INLINE uint32_t uc_unpack_24_le(const uint8_t *r)
|
|
{
|
|
uint32_t v;
|
|
|
|
v = r[0];
|
|
v |= r[1] << 8;
|
|
v |= r[2] << 16;
|
|
|
|
return v;
|
|
}
|
|
|
|
/** Serialize a uint32_t to a byte array in little endian format.
|
|
* @param v The value to serialize
|
|
* @param r The byte array to place the integer in. Must be at least of size 4.
|
|
*/
|
|
static UC_INLINE void uc_pack_32_le(uint32_t v, uint8_t *r)
|
|
{
|
|
r[0] = v;
|
|
r[1] = v >> 8;
|
|
r[2] = v >> 16;
|
|
r[3] = v >> 24;
|
|
}
|
|
|
|
/** De-serialize a uint32_t from a byte array in little endian format.
|
|
* @param r The byte array to containing the integer in. Must be at least of size 4.
|
|
* @param return The deserialized integer from the byte array.
|
|
*/
|
|
static UC_INLINE uint32_t uc_unpack_32_le(const uint8_t *r)
|
|
{
|
|
uint32_t v;
|
|
|
|
v = r[0];
|
|
v |= r[1] << 8;
|
|
v |= r[2] << 16;
|
|
v |= (uint32_t)r[3] << 24;
|
|
|
|
return v;
|
|
}
|
|
|
|
/** Serialize a uint64_t to a byte array in little endian format.
|
|
* @param v The value to serialize
|
|
* @param r The byte array to place the integer in. Must be at least of size 8
|
|
*/
|
|
static UC_INLINE void uc_pack_64_le(uint64_t v, uint8_t *r)
|
|
{
|
|
r[0] = v;
|
|
r[1] = v >> 8;
|
|
r[2] = v >> 16;
|
|
r[3] = v >> 24;
|
|
r[4] = v >> 32ULL;
|
|
r[5] = v >> 40ULL;
|
|
r[6] = v >> 48ULL;
|
|
r[7] = v >> 56ULL;
|
|
}
|
|
|
|
/** De-serialize a uint64_t from a byte array in little endian format.
|
|
* @param r The byte array to containing the integer in. Must be at least of size 8.
|
|
* @param return The deserialized integer from the byte array
|
|
*/
|
|
static UC_INLINE uint64_t uc_unpack_64_le(const uint8_t *r)
|
|
{
|
|
uint64_t v;
|
|
|
|
v = r[0];
|
|
v |= r[1] << 8;
|
|
v |= r[2] << 16;
|
|
v |= (uint32_t)r[3] << 24;
|
|
v |= (uint64_t)r[4] << 32ULL;
|
|
v |= (uint64_t)r[5] << 40ULL;
|
|
v |= (uint64_t)r[6] << 48ULL;
|
|
v |= (uint64_t)r[7] << 56ULL;
|
|
|
|
return v;
|
|
}
|
|
|
|
/** Serialize a uint16_t to a byte array in big endian format.
|
|
* @param v The value to serialize
|
|
* @param r The byte array to place the integer in. Must be at least of size 2.
|
|
*/
|
|
static UC_INLINE void uc_pack_16_be(uint32_t v, uint8_t *r)
|
|
{
|
|
r[0] = v >> 8;
|
|
r[1] = v;
|
|
}
|
|
|
|
/** De-serialize a uint16_t from a byte array in big endian format.
|
|
* @param r The byte array to containing the integer in. Must be at least of size 2.
|
|
* @param return The deserialized integer from the byte array
|
|
*/
|
|
static UC_INLINE uint16_t uc_unpack_16_be(const uint8_t *r)
|
|
{
|
|
uint16_t v;
|
|
|
|
v = r[0] << 8;
|
|
v |= r[1];
|
|
|
|
return v;
|
|
}
|
|
|
|
/** Serialize a uint32_t to a 3 byte(24 bits) array in big endian format.
|
|
* Only the bottom 24 bits of the uint32_t are used.
|
|
*
|
|
* @param v The value to serialize
|
|
* @param r The byte array to place the integer in. Must be at least of size 3.
|
|
*/
|
|
static UC_INLINE void uc_pack_24_be(uint32_t v, uint8_t *r)
|
|
{
|
|
r[0] = v >> 16;
|
|
r[1] = v >> 8;
|
|
r[2] = v;
|
|
}
|
|
|
|
/** De-serialize a uint32_t from a 3 byte (24 bit) byte array in big endian format.
|
|
* @param r The byte array to containing the integer in. Must be at least of size 3.
|
|
* @param return The deserialized integer from the byte array.
|
|
*/
|
|
static UC_INLINE uint32_t uc_unpack_24_be(const uint8_t *r)
|
|
{
|
|
uint32_t v;
|
|
|
|
v = r[0] << 16;
|
|
v |= r[1] << 8;
|
|
v |= r[2];
|
|
|
|
return v;
|
|
}
|
|
|
|
/** Serialize a uint32_t to a byte array in big endian format.
|
|
* @param v The value to serialize
|
|
* @param r The byte array to place the integer in. Must be at least of size 4.
|
|
*/
|
|
static UC_INLINE void uc_pack_32_be(uint32_t v, uint8_t *r)
|
|
{
|
|
r[0] = v >> 24;
|
|
r[1] = v >> 16;
|
|
r[2] = v >> 8;
|
|
r[3] = v;
|
|
}
|
|
|
|
/** De-serialize a uint32_t from a byte array in big endian format.
|
|
* @param r The byte array to containing the integer in. Must be at least of size 4.
|
|
* @param return The deserialized integer from the byte array
|
|
*/
|
|
static UC_INLINE uint32_t uc_unpack_32_be(const uint8_t *r)
|
|
{
|
|
uint32_t v;
|
|
|
|
v = (uint32_t)r[0] << 24;
|
|
v |= r[1] << 16;
|
|
v |= r[2] << 8;
|
|
v |= r[3];
|
|
|
|
return v;
|
|
}
|
|
|
|
/** Serialize a uint16_t to a byte array in big endian format.
|
|
* @param v The value to serialize
|
|
* @param r The byte array to place the integer in. Must be at least of size 8
|
|
*/
|
|
static UC_INLINE void uc_pack_64_be(uint64_t v, uint8_t *r)
|
|
{
|
|
r[0] = v >> 56ULL;
|
|
r[1] = v >> 48ULL;
|
|
r[2] = v >> 40ULL;
|
|
r[3] = v >> 32ULL;
|
|
r[4] = v >> 24;
|
|
r[5] = v >> 16;
|
|
r[6] = v >> 8;
|
|
r[7] = v;
|
|
}
|
|
|
|
/** De-serialize a uint64_t from a byte array in big endian format.
|
|
* @param r The byte array to containing the integer in. Must be at least of size 4.
|
|
* @param return The deserialized integer from the byte array
|
|
*/
|
|
static UC_INLINE uint64_t uc_unpack_64_be(const uint8_t *r)
|
|
{
|
|
uint64_t v;
|
|
|
|
v = (uint64_t)r[0] << 56ULL;
|
|
v |= (uint64_t)r[1] << 48ULL;
|
|
v |= (uint64_t)r[2] << 40ULL;
|
|
v |= (uint64_t)r[3] << 32ULL;
|
|
v |= (uint32_t)r[4] << 24;
|
|
v |= r[5] << 16;
|
|
v |= r[6] << 8;
|
|
v |= r[7];
|
|
|
|
return v;
|
|
}
|
|
|
|
|
|
|
|
#undef UC_INLINE
|
|
|
|
|
|
#endif
|
|
|