Skip to content

Commit

Permalink
sys/libc: add endian.h
Browse files Browse the repository at this point in the history
This provides glibc, NetBSD, FreeBSD compatible endian.h header with a
lean and simple API to convert between host byte order to little endian
and big endian and the other way around.
  • Loading branch information
maribu committed Jan 30, 2024
1 parent 1d11b67 commit 68018fe
Showing 1 changed file with 114 additions and 0 deletions.
114 changes: 114 additions & 0 deletions sys/libc/include/endian.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright (C) 2024 Otto-von-Guericke-Universität Magdeburg
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/

/**
* @addtogroup posix
* @{
*/
/**
* @file
* @brief libc header for endian conversion
*
* @author Marian Buschsieweke <[email protected]>
*/

#ifndef ENDIAN_H
#define ENDIAN_H

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#ifdef DOXYGEN
/**
* @brief A numeric constant representing little endian byte order
*/
#define LITTLE_ENDIAN implementation_defined

/**
* @brief A numeric constant representing big endian byte order
*/
#define BIG_ENDIAN implementation_defined

/**
* @brief A numeric constant representing PDP endian byte order
*/
#define PDP_ENDIAN implementation_defined

/**
* @brief The byte order of this machines indicated by the constant
* @ref BIG_ENDIAN or @ref LITTLE_ENDIAN
*
* @note This numeric constant is available at preprocessor time, so you
* can compare this to @ref BIG_ENDIAN or @ref LITTLE_ENDIAN in
* `#if` directives.
*/
#define BYTE_ORDER <LITTLE_ENDIAN or BIG_ENDIAN>

uint16_t htobe16(uint16_t host_16bits); /**< host to big endian, 16 bit */
uint16_t htole16(uint16_t host_16bits); /**< host to little endian, 16 bit */
uint16_t be16toh(uint16_t big_endian_16bits); /**< big endian to host, 16 bit */
uint16_t le16toh(uint16_t little_endian_16bits);/**< little endian to host, 16 bit */

uint32_t htobe32(uint32_t host_32bits); /**< host to big endian, 32 bit */
uint32_t htole32(uint32_t host_32bits); /**< host to little endian, 32 bit */
uint32_t be32toh(uint32_t big_endian_32bits); /**< big endian to host, 32 bit */
uint32_t le32toh(uint32_t little_endian_32bits);/**< little endian to host, 32 bit */

uint64_t htobe64(uint64_t host_64bits); /**< host to big endian, 64 bit */
uint64_t htole64(uint64_t host_64bits); /**< host to little endian, 64 bit */
uint64_t be64toh(uint64_t big_endian_64bits); /**< big endian to host, 64 bit */
uint64_t le64toh(uint64_t little_endian_64bits);/**< little endian to host, 64 bit */

#else /* DOXYGEN */

#define LITTLE_ENDIAN _LITTLE_ENDIAN
#define BIG_ENDIAN _BIG_ENDIAN
#define PDP_ENDIAN _PDP_ENDIAN
#define BYTE_ORDER _BYTE_ORDER

#if BYTE_ORDER == LITTLE_ENDIAN
# define htobe16(_x) __builtin_bswap16(_x)
# define htole16(_x) ((__uint16_t)(_x))
# define be16toh(_x) __builtin_bswap16(_x)
# define le16toh(_x) ((__uint16_t)(_x))
# define htobe32(_x) __builtin_bswap32(_x)
# define htole32(_x) ((__uint32_t)(_x))
# define be32toh(_x) __builtin_bswap32(_x)
# define le32toh(_x) ((__uint32_t)(_x))
# define htobe64(_x) __builtin_bswap64(_x)
# define htole64(_x) ((__uint64_t)(_x))
# define be64toh(_x) __builtin_bswap64(_x)
# define le64toh(_x) ((__uint64_t)(_x))
#elif BYTE_ORDER == BIG_ENDIAN
# define htole16(_x) __builtin_bswap16(_x)
# define htobe16(_x) ((__uint16_t)(_x))
# define le16toh(_x) __builtin_bswap16(_x)
# define be16toh(_x) ((__uint16_t)(_x))
# define htole32(_x) __builtin_bswap32(_x)
# define htobe32(_x) ((__uint32_t)(_x))
# define le32toh(_x) __builtin_bswap32(_x)
# define be32toh(_x) ((__uint32_t)(_x))
# define htole64(_x) __builtin_bswap64(_x)
# define htobe64(_x) ((__uint64_t)(_x))
# define le64toh(_x) __builtin_bswap64(_x)
# define be64toh(_x) ((__uint64_t)(_x))
#else
# error "Byte order not supported"
#endif

#endif /* DOXYGEN */

#ifdef __cplusplus
}
#endif

#endif /* ENDIAN_H */
/** @} */

0 comments on commit 68018fe

Please sign in to comment.