ucx/utils.c

changeset 17
11dffb40cd91
parent 5
88625853ae74
child 39
3e55bed345f9
--- a/ucx/utils.c	Fri Aug 16 12:41:30 2013 +0200
+++ b/ucx/utils.c	Sat Aug 17 12:04:04 2013 +0200
@@ -27,7 +27,10 @@
  */
 
 #include "utils.h"
-#include "math.h"
+#include <math.h>
+#include <stdio.h>
+#include <limits.h>
+#include <errno.h>
 
 /* COPY FUCNTIONS */
 void* ucx_strcpy(void* s, void* data) {
@@ -45,7 +48,37 @@
     return cpy;
 }
 
-/* COMPARE FUNCTION */
+size_t ucx_stream_copy(void *src, void *dest, read_func readfnc,
+        write_func writefnc, char* buf, size_t bufsize, size_t n) {
+    if(n == 0 || bufsize == 0) {
+        return 0;
+    }
+    
+    size_t ncp = 0;
+    if (!buf) {
+        buf = (char*)malloc(bufsize);
+        if(buf == NULL) {
+            return 0;
+        }
+    }
+    
+    size_t r;
+    size_t rn = bufsize > n ? n : bufsize;
+    while((r = readfnc(buf, 1, rn, src)) != 0) {
+        r = writefnc(buf, 1, r, dest);
+        ncp += r;
+        n -= r;
+        rn = bufsize > n ? n : bufsize;
+        if(r == 0 || n == 0) {
+            break;
+        }
+    }
+    
+    free(buf);
+    return ncp;
+}
+
+/* COMPARE FUNCTIONS */
 
 int ucx_strcmp(void *s1, void *s2, void *data) {
     return strcmp((char*)s1, (char*)s2);
@@ -98,3 +131,86 @@
 int ucx_memcmp(void *ptr1, void *ptr2, void *n) {
     return memcmp(ptr1, ptr2, *((size_t*)n));
 }
+
+/* PRINTF FUNCTIONS */
+
+#define UCX_PRINTF_BUFSIZE 256
+
+int ucx_fprintf(void *stream, write_func wfc, const char *fmt, ...) {
+    va_list ap;
+    int ret;
+    va_start(ap, fmt);
+    ret = ucx_vfprintf(stream, wfc, fmt, ap);
+    va_end(ap);
+    return ret;
+}
+
+int ucx_vfprintf(void *stream, write_func wfc, const char *fmt, va_list ap) {
+    char buf[UCX_PRINTF_BUFSIZE];
+    va_list ap2;
+    va_copy(ap2, ap);
+    int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap);
+    if (ret < 0) {
+        return ret;
+    } else if (ret < UCX_PRINTF_BUFSIZE) {
+        return (int)wfc(buf, 1, ret, stream);
+    } else {
+        if (ret == INT_MAX) {
+            errno = ENOMEM;
+            return -1;
+        }
+        
+        int len = ret + 1;
+        char *newbuf = (char*)malloc(len);
+        if (!newbuf) {
+            return -1;
+        }
+        
+        ret = vsnprintf(newbuf, len, fmt, ap2);
+        va_end(ap2);
+        if (ret > 0) {
+            ret = (int)wfc(newbuf, 1, ret, stream);
+        }
+        free(newbuf);
+    }
+    return ret;
+}
+
+sstr_t ucx_asprintf(UcxAllocator *allocator, const char *fmt, ...) {
+    va_list ap;
+    sstr_t ret;
+    va_start(ap, fmt);
+    ret = ucx_vasprintf(allocator, fmt, ap);
+    va_end(ap);
+    return ret;
+}
+
+sstr_t ucx_vasprintf(UcxAllocator *a, const char *fmt, va_list ap) {
+    sstr_t s;
+    s.ptr = NULL;
+    s.length = 0;
+    va_list ap2;
+    va_copy(ap2, ap);
+    char buf[UCX_PRINTF_BUFSIZE];
+    int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap);
+    if (ret > 0 && ret < UCX_PRINTF_BUFSIZE) {
+        s.ptr = (char*)a->malloc(a->pool, ret + 1);
+        s.length = (size_t)ret;
+        memcpy(s.ptr, buf, ret);
+        s.ptr[s.length] = '\0';
+    } else if (ret == INT_MAX) {
+        errno = ENOMEM;
+    } else  {
+        int len = ret + 1;
+        s.ptr = (char*)a->malloc(a->pool, len);
+        ret = vsnprintf(s.ptr, len, fmt, ap2);
+        va_end(ap2);
+        if (ret < 0) {
+            free(s.ptr);
+            s.ptr = NULL;
+        } else {
+            s.length = (size_t)ret;
+        }
+    }
+    return s;
+}

mercurial