From de99380f12f8e2fe4acf7734db0e1e37a356c45f Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sat, 11 Jun 2022 15:37:39 +0300 Subject: continue documentation --- include/apos/unaligned.h | 252 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 216 insertions(+), 36 deletions(-) (limited to 'include/apos/unaligned.h') diff --git a/include/apos/unaligned.h b/include/apos/unaligned.h index 85d67b0..332c992 100644 --- a/include/apos/unaligned.h +++ b/include/apos/unaligned.h @@ -9,64 +9,244 @@ #include #include -#define get_unaligned(ptr) \ - _Generic(*(ptr), uint8_t \ - : __get_unaligned_uint8_t, uint16_t \ - : __get_unaligned_uint16_t, uint32_t \ - : __get_unaligned_uint32_t, uint64_t \ - : __get_unaligned_uint64_t, int8_t \ - : __get_unaligned_int8_t, int16_t \ - : __get_unaligned_int16_t, int32_t \ - : __get_unaligned_int32_t, int64_t \ - : __get_unaligned_int64_t)((void *)ptr) - -#define put_unaligned(val, ptr) \ - _Generic(*(ptr), uint8_t \ - : __put_unaligned_uint8_t, uint16_t \ - : __put_unaligned_uint16_t, uint32_t \ - : __put_unaligned_uint32_t, uint64_t \ - : __put_unaligned_uint64_t, int8_t \ - : __put_unaligned_int8_t, int16_t \ - : __put_unaligned_int16_t, int32_t \ - : __put_unaligned_int32_t, int64_t \ - : __put_unaligned_int64_t)(val, (void *)ptr) - -#define DEFINE_GET(type) \ - static inline type __get_unaligned_##type(void *ptr) \ - { \ - const struct __packed { \ - type x; \ - } *__pptr = ptr; \ - return __pptr->x; \ +/** + * Get unaligned value. Type of value is deduced from pointer type. + * + * @param ptr Pointer to possibly unaligned value to read. + * @return Value pointed to by \c ptr. + */ +#define get_unaligned(ptr) \ + _Generic(*(ptr), \ + uint8_t: get_unaligned_uint8_t, \ + uint16_t: get_unaligned_uint16_t, \ + uint32_t: get_unaligned_uint32_t, \ + uint64_t: get_unaligned_uint64_t, \ + \ + int8_t: get_unaligned_int8_t, \ + int16_t: get_unaligned_int16_t, \ + int32_t: get_unaligned_int32_t, \ + int64_t: get_unaligned_int64_t)((void *)ptr) + +/** + * Put unaligned value. Type of value is deduced from pointer type. + * + * @param val Value to write to memory. + * @param ptr Pointer to possibly unaligned address. + */ +#define put_unaligned(val, ptr) \ + _Generic(*(ptr), \ + uint8_t: put_unaligned_uint8_t, \ + uint16_t: put_unaligned_uint16_t, \ + uint32_t: put_unaligned_uint32_t, \ + uint64_t: put_unaligned_uint64_t, \ + \ + int8_t: put_unaligned_int8_t, \ + int16_t: put_unaligned_int16_t, \ + int32_t: put_unaligned_int32_t, \ + int64_t: put_unaligned_int64_t)(val, (void *)ptr) + +/** + * Helper macro for defining an unaligned value reader. + * + * @param type Type of value reader to define. + */ +#define DEFINE_GET(type) \ + static inline type get_unaligned_##type(void *ptr) \ + { \ + const struct __packed { \ + type x; \ + } *__pptr = ptr; \ + return __pptr->x; \ } +/** + * Read possibly unaligned \ref uint8_t. + * + * Technically speaking a byte can't be unaligned, but this is just here for + * cohesion. + * + * @warning Prefer using \ref get_unaligned(). + * + * @param ptr Pointer to \ref uint8_t to read. + * @return Value pointed to by \c ptr. + */ DEFINE_GET(uint8_t); + +/** + * Read possibly unaligned \ref uint16_t. + * + * @warning Prefer using \ref get_unaligned(). + * + * @param ptr Pointer to \ref uint16_t to read. + * @return Value pointed to by \c ptr. + */ DEFINE_GET(uint16_t); + +/** + * Read possibly unaligned \ref uint32_t. + * + * @warning Prefer using \ref get_unaligned(). + * + * @param ptr Pointer to \ref uint32_t to read. + * @return Value pointed to by \c ptr. + */ DEFINE_GET(uint32_t); + +/** + * Read possibly unaligned \ref uint64_t. + * + * @warning Prefer using \ref get_unaligned(). + * + * @param ptr Pointer to \ref uint64_t to read. + * @return Value pointed to by \c ptr. + */ DEFINE_GET(uint64_t); + +/** + * Read possibly unaligned \ref int8_t. + * + * Technically speaking a byte can't be unaligned, but this is just here for + * cohesion. + * + * @warning Prefer using \ref get_unaligned(). + * + * @param ptr Pointer to \ref int8_t to read. + * @return Value pointed to by \c ptr. + */ DEFINE_GET(int8_t); + +/** + * Read possibly unaligned \ref int16_t. + * + * @warning Prefer using \ref get_unaligned(). + * + * @param ptr Pointer to \ref int16_t to read. + * @return Value pointed to by \c ptr. + */ DEFINE_GET(int16_t); + +/** + * Read possibly unaligned \ref int32_t. + * + * @warning Prefer using \ref get_unaligned(). + * + * @param ptr Pointer to \ref int32_t to read. + * @return Value pointed to by \c ptr. + */ DEFINE_GET(int32_t); + +/** + * Read possibly unaligned \ref int64_t. + * + * @warning Prefer using \ref get_unaligned(). + * + * @param ptr Pointer to \ref int64_t to read. + * @return Value pointed to by \c ptr. + */ DEFINE_GET(int64_t); #undef DEFINE_GET -#define DEFINE_PUT(type) \ - static inline void __put_unaligned_##type(type val, void *ptr) \ - { \ - struct __packed { \ - type x; \ - } *__pptr = ptr; \ - __pptr->x = val; \ +/** + * Helper macro for defining an unaligned writer. + * + * @param type Type of value to write. + */ +#define DEFINE_PUT(type) \ + static inline void put_unaligned_##type(type val, void *ptr) \ + { \ + struct __packed { \ + type x; \ + } *__pptr = ptr; \ + __pptr->x = val; \ } +/** + * Write possibly unaligned \ref uint8_t. + * + * Technically speaking a byte can't be unaligned, but this is just here for + * cohesion. + * + * @warning Prefer using \ref put_unaligned(). + * + * @param val Value to write. + * @param ptr Address to write to. + */ DEFINE_PUT(uint8_t); + +/** + * Write possibly unaligned \ref uint16_t. + * + * @warning Prefer using \ref put_unaligned(). + * + * @param val Value to write. + * @param ptr Address to write to. + */ DEFINE_PUT(uint16_t); + +/** + * Write possibly unaligned \ref uint32_t. + * + * @warning Prefer using \ref put_unaligned(). + * + * @param val Value to write. + * @param ptr Address to write to. + */ DEFINE_PUT(uint32_t); + +/** + * Write possibly unaligned \ref uint64_t. + * + * @warning Prefer using \ref put_unaligned(). + * + * @param val Value to write. + * @param ptr Address to write to. + */ DEFINE_PUT(uint64_t); + +/** + * Write possibly unaligned \ref int8_t. + * + * Technically speaking a byte can't be unaligned, but this is just here for + * cohesion. + * + * @warning Prefer using \ref put_unaligned(). + * + * @param val Value to write. + * @param ptr Address to write to. + */ DEFINE_PUT(int8_t); + +/** + * Write possibly unaligned \ref int16_t. + * + * @warning Prefer using \ref put_unaligned(). + * + * @param val Value to write. + * @param ptr Address to write to. + */ DEFINE_PUT(int16_t); + +/** + * Write possibly unaligned \ref int32_t. + * + * @warning Prefer using \ref put_unaligned(). + * + * @param val Value to write. + * @param ptr Address to write to. + */ DEFINE_PUT(int32_t); + +/** + * Write possibly unaligned \ref int64_t. + * + * @warning Prefer using \ref put_unaligned(). + * + * @param val Value to write. + * @param ptr Address to write to. + */ DEFINE_PUT(int64_t); +#undef DEFINE_PUT + #endif /* APOS_UNALIGNED_H */ -- cgit v1.3