libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

commit 91915af50bb56b9d496d4026323ba2d10905b827
parent 4b834afcd19940420d11d3d609e11c787cf11a4f
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date:   Sun,  2 Nov 2025 19:18:59 +0100

mhd_bithelpers.h: added 16-bit BE get/put

Diffstat:
Mconfigure.ac | 8++++++++
Msrc/mhd2/mhd_bithelpers.h | 95++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac @@ -3169,6 +3169,14 @@ AS_VAR_IF([mhd_cv_macro___func___avail], ["yes"], ) ] ) +AC_CACHE_CHECK([[whether __builtin_bswap16() is available]], + [[mhd_cv_func___builtin_bswap16_avail]], [dnl + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include<stdint.h>]], [[uint_least16_t a = 1; uint_least16_t b = __builtin_bswap16(a); a = b; (void) a;]])], + [[mhd_cv_func___builtin_bswap16_avail="yes"]],[[mhd_cv_func___builtin_bswap16_avail="no"]]) +]) +AS_IF([[test "x$mhd_cv_func___builtin_bswap16_avail" = "xyes"]], + [AC_DEFINE([[MHD_HAVE___BUILTIN_BSWAP16]], [[1]], [Define to 1 if you have __builtin_bswap16() builtin function])]) + AC_CACHE_CHECK([[whether __builtin_bswap32() is available]], [[mhd_cv_func___builtin_bswap32_avail]], [dnl AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include<stdint.h>]], [[uint_least32_t a = 1; uint_least32_t b = __builtin_bswap32(a); a = b; (void) a;]])], diff --git a/src/mhd2/mhd_bithelpers.h b/src/mhd2/mhd_bithelpers.h @@ -83,6 +83,27 @@ mhd_DATA_TRUNCATION_RUNTIME_CHECK_DISABLE +#if defined(MHD_HAVE___BUILTIN_BSWAP16) || \ + mhd_HAS_BUILTIN (__builtin_bswap16) +# define mhd_BYTES_SWAP16(value16) \ + ((uint16_t)__builtin_bswap16 ((uint16_t) value16)) +#elif defined(mhd_HAS_VC_INTRINSICS) +# ifndef __clang__ +# pragma intrinsic(_byteswap_ushort) +# endif /* ! __clang__ */ +# define mhd_BYTES_SWAP16(value16) \ + ((uint16_t)_byteswap_ushort ((uint16_t) value16)) +#else /* ! mhd_HAS_BUILTIN(__builtin_bswap32) */ +mhd_static_inline uint16_t +mhd_BYTES_SWAP16 (uint16_t value16) +{ + return (uint16_t) ((value16 << 8u) | (value16 >> 8u)); +} + + +#endif /* mhd_BYTES_SWAP16 */ + + #ifdef MHD_HAVE___BUILTIN_BSWAP32 # define mhd_BYTES_SWAP32(value32) \ ((uint32_t) __builtin_bswap32 ((uint32_t) value32)) @@ -95,7 +116,7 @@ mhd_DATA_TRUNCATION_RUNTIME_CHECK_DISABLE #elif \ mhd_HAS_BUILTIN (__builtin_bswap32) # define mhd_BYTES_SWAP32(value32) \ - ((uint32_t)__builtin_bswap32 ((uint32_t) value32)) + ((uint32_t) __builtin_bswap32 ((uint32_t) value32)) #else /* ! mhd_HAS_BUILTIN(__builtin_bswap32) */ mhd_static_inline uint32_t mhd_BYTES_SWAP32 (uint32_t value32) @@ -568,6 +589,78 @@ mhd_GET_UINTFAST32_BE(const void *addr) #endif +/* mhd_PUT_16BIT_BE (addr, value16) + * put 16-bit value16 to addr + * in big-endian mode. + */ +#if mhd_BYTE_ORDER == mhd_BIG_ENDIAN +# define mhd_PUT_16BIT_BE(addr, value16) \ + ((*(uint16_t*) (addr)) = (uint16_t) (value16)) +#elif mhd_BYTE_ORDER == mhd_LITTLE_ENDIAN +# define mhd_PUT_16BIT_BE(addr, value16) \ + ((*(uint16_t*) (addr)) = mhd_BYTES_SWAP16 (value16)) +#else /* mhd_BYTE_ORDER != mhd_LITTLE_ENDIAN */ +/* Endianness was not detected or non-standard like PDP-endian */ +mhd_static_inline void +mhd_PUT_16BIT_BE(void *addr, uint16_t value16) +{ + uint8_t *const dst = (uint8_t *) addr; + dst[0] = (uint8_t) (value16 >> 8u); + dst[1] = (uint8_t) (value16 >> 0u); +} +/* Indicate that mhd_PUT_16BIT_BE does not need aligned pointer */ +# define mhd_PUT_16BIT_BE_ALLOW_UNALIGNED 1 +#endif /* mhd_BYTE_ORDER != mhd_LITTLE_ENDIAN */ + +/* Put result safely to unaligned address */ +#ifdef mhd_PUT_16BIT_BE_ALLOW_UNALIGNED +# define mhd_PUT_16BIT_BE_UNALIGN(addr, value16) \ + mhd_PUT_16BIT_BE ((addr),(value16)) +#else /* ! mhd_PUT_16BIT_BE_ALLOW_UNALIGNED */ +# define mhd_PUT_16BIT_BE_UNALIGN(addr, value16) \ + do { uint16_t mhd__aligned_dst; \ + mhd_PUT_16BIT_BE (&mhd__aligned_dst, (value16)); \ + memcpy ((addr), &mhd__aligned_dst, \ + sizeof(mhd__aligned_dst)); } while (0) +#endif /* ! mhd_PUT_16BIT_BE_ALLOW_UNALIGNED */ + + +/* mhd_GET_16BIT_BE (addr) + * get big-endian 16-bit value stored at addr + */ +#if mhd_BYTE_ORDER == mhd_BIG_ENDIAN +# define mhd_GET_16BIT_BE(addr) \ + (*(const uint16_t*) (addr)) +#elif mhd_BYTE_ORDER == mhd_LITTLE_ENDIAN +# define mhd_GET_16BIT_BE(addr) \ + mhd_BYTES_SWAP16 (*(const uint16_t*) (addr)) +#else /* mhd_BYTE_ORDER != mhd_LITTLE_ENDIAN */ +/* Endianness was not detected or non-standard like PDP-endian */ +mhd_static_inline uint16_t +mhd_GET_16BIT_BE(const void *addr) +{ + const uint8_t *const src = (const uint8_t *) addr; + return (uint16_t) ((((uint16_t) src[0]) << 8u) | ((uint16_t) src[1])); +} +/* Indicate that mhd_GET_16BIT_BE does not need aligned pointer */ +# define mhd_GET_16BIT_BE_ALLOW_UNALIGNED 1 +#endif /* mhd_BYTE_ORDER != mhd_LITTLE_ENDIAN */ + +#ifdef mhd_GET_16BIT_BE_ALLOW_UNALIGNED +# define mhd_GET_16BIT_BE_UNALIGN(addr) mhd_GET_16BIT_BE ((addr)) +#else /* ! mhd_GET_16BIT_LE_ALLOW_UNALIGNED */ +/* Get value safely from an unaligned address */ +mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ uint16_t +mhd_GET_16BIT_BE_UNALIGN (const void *addr) +{ + uint16_t aligned_src; + memcpy (&aligned_src, + addr, + sizeof(aligned_src)); + return mhd_GET_16BIT_BE (&aligned_src); +} +#endif /* ! mhd_GET_16BIT_BE_ALLOW_UNALIGNED */ + /** * Rotate right 32-bit value by number of bits. */