Files
libucore/include/ucore/pack.h
T
2013-03-06 22:22:04 +01:00

258 lines
6.4 KiB
C

#ifndef UCORE_PACK_H_
#define UCORE_PACK_H_
#include <stdint.h>
#ifdef __GNUC__
# define UC_INLINE inline __attribute__((always_inline))
#else
# define UC_INLINE inline
#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 |= 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 = 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