src/ucx/utils.c

changeset 490
d218607f5a7e
parent 415
d938228c382e
child 504
c094afcdfb27
--- a/src/ucx/utils.c	Sat Mar 25 17:18:51 2023 +0100
+++ b/src/ucx/utils.c	Fri May 05 18:02:11 2023 +0200
@@ -28,19 +28,67 @@
 
 #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
+) {
+    char buf[CX_STREAM_COPY_BUF_SIZE];
+    return cx_stream_bncopy(src, dest, rfnc, wfnc,
+                            buf, CX_STREAM_COPY_BUF_SIZE, n);
+}
+
+#ifndef CX_SZMUL_BUILTIN
+#include "szmul.c"
 #endif

mercurial