--- a/src/ucx/cx/utils.h Sat Mar 25 17:18:51 2023 +0100 +++ b/src/ucx/cx/utils.h Fri May 05 18:02:11 2023 +0200 @@ -51,14 +51,22 @@ */ #define cx_for_n(varname, n) for (size_t varname = 0 ; (varname) < (n) ; (varname)++) +/** + * Convenience macro for swapping two pointers. + */ +#ifdef __cplusplus +#define cx_swap_ptr(left, right) do {auto cx_tmp_swap_var = left; left = right; right = cx_tmp_swap_var;} while(0) +#else +#define cx_swap_ptr(left, right) do {void *cx_tmp_swap_var = left; left = right; right = cx_tmp_swap_var;} while(0) +#endif + // cx_szmul() definition #if (__GNUC__ >= 5 || defined(__clang__)) && !defined(CX_NO_SZMUL_BUILTIN) #define CX_SZMUL_BUILTIN -#if __WORDSIZE == 32 /** - * Alias for \c __builtin_umul_overflow. + * Alias for \c __builtin_mul_overflow. * * Performs a multiplication of size_t values and checks for overflow. * @@ -69,22 +77,7 @@ * @return zero, if no overflow occurred and the result is correct, non-zero * otherwise */ -#define cx_szmul(a, b, result) __builtin_umul_overflow(a, b, result) -#else // __WORDSIZE != 32 -/** - * Alias for \c __builtin_umull_overflow. - * - * Performs a multiplication of size_t values and checks for overflow. - * - * @param a first operand - * @param b second operand - * @param result a pointer to a size_t, where the result should - * be stored - * @return zero, if no overflow occurred and the result is correct, non-zero - * otherwise - */ -#define cx_szmul(a, b, result) __builtin_umull_overflow(a, b, result) -#endif // __WORDSIZE +#define cx_szmul(a, b, result) __builtin_mul_overflow(a, b, result) #else // no GNUC or clang bultin @@ -114,7 +107,87 @@ */ int cx_szmul_impl(size_t a, size_t b, size_t *result); -#endif +#endif // cx_szmul + + +/** + * Reads data from a stream and writes it to another stream. + * + * @param src the source stream + * @param dest the destination stream + * @param rfnc the read function + * @param wfnc the write function + * @param buf a pointer to the copy buffer or \c NULL if a buffer + * shall be implicitly created on the heap + * @param bufsize the size of the copy buffer - if \p buf is \c NULL you can + * set this to zero to let the implementation decide + * @param n the maximum number of bytes that shall be copied. + * If this is larger than \p bufsize, the content is copied over multiple + * iterations. + * @return the total number of bytes copied + */ +__attribute__((__nonnull__(1, 2, 3, 4))) +size_t cx_stream_bncopy( + void *src, + void *dest, + cx_read_func rfnc, + cx_write_func wfnc, + char *buf, + size_t bufsize, + size_t n +); + +/** + * Reads data from a stream and writes it to another stream. + * + * @param src the source stream + * @param dest the destination stream + * @param rfnc the read function + * @param wfnc the write function + * @param buf a pointer to the copy buffer or \c NULL if a buffer + * shall be implicitly created on the heap + * @param bufsize the size of the copy buffer - if \p buf is \c NULL you can + * set this to zero to let the implementation decide + * @return total number of bytes copied + */ +#define cx_stream_bcopy(src, dest, rfnc, wfnc, buf, bufsize) \ + cx_stream_bncopy(src, dest, rfnc, wfnc, buf, bufsize, SIZE_MAX) + +/** + * Reads data from a stream and writes it to another stream. + * + * The data is temporarily stored in a stack allocated buffer. + * + * @param src the source stream + * @param dest the destination stream + * @param rfnc the read function + * @param wfnc the write function + * @param n the maximum number of bytes that shall be copied. + * @return total number of bytes copied + */ +__attribute__((__nonnull__)) +size_t cx_stream_ncopy( + void *src, + void *dest, + cx_read_func rfnc, + cx_write_func wfnc, + size_t n +); + +/** + * Reads data from a stream and writes it to another stream. + * + * The data is temporarily stored in a stack allocated buffer. + * + * @param src the source stream + * @param dest the destination stream + * @param rfnc the read function + * @param wfnc the write function + * @param n the maximum number of bytes that shall be copied. + * @return total number of bytes copied + */ +#define cx_stream_copy(src, dest, rfnc, wfnc) \ + cx_stream_ncopy(src, dest, rfnc, wfnc, SIZE_MAX) #ifdef __cplusplus }