diff -r 60fb6aec157d -r dc514a5d42a5 src/utils.c --- a/src/utils.c Mon Apr 03 19:09:31 2023 +0200 +++ b/src/utils.c Mon Apr 03 19:20:30 2023 +0200 @@ -28,19 +28,85 @@ #include "cx/utils.h" -#ifndef CX_SZMUL_BUILTIN -int cx_szmul_impl(size_t a, size_t b, size_t *result) { - if(a == 0 || b == 0) { - *result = 0; +#define CX_STREAM_BCOPY_BUF_SIZE 8192 +#define CX_STREAM_COPY_BUF_SIZE 1024 + +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 +) { + if (n == 0) { return 0; } - size_t r = a * b; - if(r / b == a) { - *result = r; - return 0; + + char *lbuf; + size_t ncp = 0; + + if (buf) { + if (bufsize == 0) return 0; + lbuf = buf; } else { - *result = 0; - return 1; + if (bufsize == 0) bufsize = CX_STREAM_BCOPY_BUF_SIZE; + lbuf = malloc(bufsize); + if (lbuf == NULL) { + return 0; + } + } + + size_t r; + size_t rn = bufsize > n ? n : bufsize; + while ((r = rfnc(lbuf, 1, rn, src)) != 0) { + r = wfnc(lbuf, 1, r, dest); + ncp += r; + n -= r; + rn = bufsize > n ? n : bufsize; + if (r == 0 || n == 0) { + break; + } + } + + if (lbuf != buf) { + free(lbuf); } + + return ncp; } + +size_t cx_stream_ncopy( + void *src, + void *dest, + cx_read_func rfnc, + cx_write_func wfnc, + size_t n +) { + if (n == 0) { + return 0; + } + + const size_t bufsize = CX_STREAM_COPY_BUF_SIZE; + char lbuf[bufsize]; + size_t ncp = 0; + + size_t r; + size_t rn = bufsize > n ? n : bufsize; + while ((r = rfnc(lbuf, 1, rn, src)) != 0) { + r = wfnc(lbuf, 1, r, dest); + ncp += r; + n -= r; + rn = bufsize > n ? n : bufsize; + if (r == 0 || n == 0) { + break; + } + } + + return ncp; +} + +#ifndef CX_SZMUL_BUILTIN +#include "szmul.c" #endif