fixed buffer

Fri, 30 Nov 2012 13:10:58 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 30 Nov 2012 13:10:58 +0100
changeset 76
655020a30e77
parent 75
990734f548ef
child 77
51311a5685d3

fixed buffer

test/buffer_tests.c file | annotate | diff | comparison | revisions
test/buffer_tests.h file | annotate | diff | comparison | revisions
test/main.c file | annotate | diff | comparison | revisions
test/map_tests.c file | annotate | diff | comparison | revisions
ucx/buffer.c file | annotate | diff | comparison | revisions
ucx/buffer.h file | annotate | diff | comparison | revisions
ucx/ucx.h file | annotate | diff | comparison | revisions
--- a/test/buffer_tests.c	Sun Nov 04 20:50:12 2012 +0100
+++ b/test/buffer_tests.c	Fri Nov 30 13:10:58 2012 +0100
@@ -5,11 +5,8 @@
 #include "buffer_tests.h"
 
 UCX_TEST_IMPLEMENT(test_ucx_buffer_seektell) {
-    char *buffer = (char*) malloc(16);
-    memset(buffer, 32, 7);
-    buffer[7] = 0;
-
-    UcxBuffer *b = ucx_buffer_new(buffer, 16, UCX_BUFFER_DEFAULT);
+    UcxBuffer *b = ucx_buffer_new(NULL, 32, UCX_BUFFER_DEFAULT);
+    b->size = 16; // less than capacity
     int r;
 
     UCX_TEST_BEGIN
@@ -34,17 +31,16 @@
 
     r = ucx_buffer_seek(b, -5, SEEK_END);
     UCX_TEST_ASSERT(r == 0, "seek END-5 failed");
-    UCX_TEST_ASSERT(b->pos == 2, "seek END-5 set wrong position");
+    UCX_TEST_ASSERT(b->pos == 11, "seek END-5 set wrong position");
 
-    r = ucx_buffer_seek(b, -10, SEEK_END);
+    r = ucx_buffer_seek(b, -20, SEEK_END);
     UCX_TEST_ASSERT(r != 0, "seek END beyond bounds shall fail");
-    UCX_TEST_ASSERT(b->pos == 2,
+    UCX_TEST_ASSERT(b->pos == 11,
             "failed seek shall leave pos unchanged");
 
     UCX_TEST_END
 
     ucx_buffer_free(b);
-    free(buffer);
 }
 
 UCX_TEST_IMPLEMENT(test_ucx_buffer_putc) {
@@ -52,19 +48,34 @@
     memset(buffer, 32, 16);
 
     UcxBuffer *b = ucx_buffer_new(buffer, 16, UCX_BUFFER_DEFAULT);
+    b->size = b->capacity;
     int r;
 
     UCX_TEST_BEGIN
 
-    ucx_buffer_putc(b, 48); ucx_buffer_putc(b, 48); ucx_buffer_putc(b, 48);
+    ucx_buffer_putc(b, '0');
+    ucx_buffer_putc(b, '0');
+    ucx_buffer_putc(b, '0');
+    
     UCX_TEST_ASSERT(b->pos == 3, "pos wrong after first 3 puts");
     ucx_buffer_seek(b, 10, SEEK_CUR);
-    ucx_buffer_putc(b, 48); ucx_buffer_putc(b, 48); ucx_buffer_putc(b, 48);
+    
+    ucx_buffer_putc(b, '0');
+    ucx_buffer_putc(b, '0');
+    ucx_buffer_putc(b, '0');
+    
     UCX_TEST_ASSERT(b->pos == 16, "pos wrong after last 3 puts");
     UCX_TEST_ASSERT(ucx_buffer_eof(b), "eof not set");
     UCX_TEST_ASSERT(ucx_buffer_putc(b, 48) == EOF,
             "put shall return EOF when buffer is full");
-    UCX_TEST_ASSERT(memcmp(buffer, "000          000", 16) == 0,
+    
+    ucx_buffer_seek(b, 3, SEEK_SET);
+    ucx_buffer_putc(b, 'a');
+    ucx_buffer_putc(b, 'b');
+    ucx_buffer_putc(b, 'c');
+    
+    UCX_TEST_ASSERT(b->size == 16, "wrong size after seek and puts");
+    UCX_TEST_ASSERT(memcmp(buffer, "000abc       000", 16) == 0,
             "buffer contains incorrect content");
 
     UCX_TEST_END
@@ -73,6 +84,30 @@
     free(buffer);
 }
 
+UCX_TEST_IMPLEMENT(test_ucx_buffer_putc_ax) {
+    UcxBuffer *b = ucx_buffer_new(NULL, 2, UCX_BUFFER_AUTOEXTEND);
+    
+    UCX_TEST_BEGIN
+    
+    ucx_buffer_putc(b, '0');
+    ucx_buffer_putc(b, '1');
+    
+    UCX_TEST_ASSERT(b->pos == 2, "pos wrong after first 2 puts");
+    UCX_TEST_ASSERT(b->capacity == 2, "buffer erroneously extended");
+    
+    ucx_buffer_putc(b, 'a');
+    
+    UCX_TEST_ASSERT(b->pos == 3, "pos wrong after 1 put");
+    UCX_TEST_ASSERT(b->capacity == 4, "buffer not properly extended");
+    UCX_TEST_ASSERT(b->size == 3, "wrong buffer size");
+    
+    UCX_TEST_ASSERT(b->space[2] == 'a', "wrong content");
+    
+    UCX_TEST_END
+    
+    
+}
+
 UCX_TEST_IMPLEMENT(test_ucx_buffer_getc) {
     char *buffer = (char*) malloc(16);
     memset(buffer, 32, 8);
@@ -81,6 +116,7 @@
     }
 
     UcxBuffer *b = ucx_buffer_new(buffer, 16, UCX_BUFFER_DEFAULT);
+    b->size = b->capacity;
     int r;
 
     UCX_TEST_BEGIN
@@ -132,7 +168,7 @@
     memset(buffer, 49, 16);
     ucx_buffer_seek(b, 0, SEEK_SET);
     r = ucx_buffer_write((void*)threebytestring, 3, 6, b);
-    UCX_TEST_ASSERT(r == 15, "three byte string not correctly trimed");
+    UCX_TEST_ASSERT(r == 5, "three byte string not correctly trimed");
     UCX_TEST_ASSERT(b->pos == 15,
             "position after write of three byte string incorrect");
     UCX_TEST_ASSERT(!ucx_buffer_eof(b), "eof shall not be set");
@@ -146,7 +182,7 @@
 }
 
 UCX_TEST_IMPLEMENT(test_ucx_buffer_write_ax) {
-    char *buffer = (char*) malloc(4);
+    char *buffer = (char*) malloc(16);
 
     UcxBuffer *b = ucx_buffer_new(buffer, 16,
             UCX_BUFFER_AUTOEXTEND | UCX_BUFFER_AUTOFREE);
@@ -158,7 +194,7 @@
     r = ucx_buffer_write((void*)teststring, 1, 20, b);
     buffer = (char*) b->space; /*autoextend enabled, we MUST retrieve pointer*/
     UCX_TEST_ASSERT(r == 20, "not all characters written");
-    UCX_TEST_ASSERT(b->size == 32, "buffer not properly extended");
+    UCX_TEST_ASSERT(b->capacity == 32, "buffer not properly extended");
     UCX_TEST_ASSERT(b->pos == 20, "position incorrect");
     UCX_TEST_ASSERT(memcmp(buffer,
             "this is way too much\0\0\0\0\0\0\0\0\0\0\0\0", 32) == 0,
@@ -170,54 +206,53 @@
 }
 
 UCX_TEST_IMPLEMENT(test_ucx_buffer_read) {
-    char *buffer = (char*) malloc(16);
-    memset(buffer, 56, 8);
-    for (int i = 8; i < 16 ; i++) {
-        buffer[i] = 40+i;
-    }
-
-    UcxBuffer *b = ucx_buffer_new(buffer, 16, UCX_BUFFER_DEFAULT);
+    UcxBuffer *b = ucx_buffer_new(NULL, 8, UCX_BUFFER_AUTOFREE);
+    
+    char buf[32];
+    memset(buf, 'X', 32);
     int r;
-
+    
     UCX_TEST_BEGIN
-
-    char rb[16];
-    memset(rb, 32, 16);
-
-    ucx_buffer_seek(b, 8, SEEK_SET);
-    r = ucx_buffer_read(rb, 1, 16, b);
-    UCX_TEST_ASSERT(r == 8, "read did not stop at buffer end");
-    UCX_TEST_ASSERT(memcmp(rb, "01234567        ", 16) == 0,
+    
+    ucx_buffer_write("01234567", 1, 8, b);
+    UCX_TEST_ASSERT(b->pos == 8, "buffer not correctly filled");
+    b->pos = 0;
+    
+    r = ucx_buffer_read(buf, 1, 2, b);
+    UCX_TEST_ASSERT(r == 2, "wrong number of bytes read");
+    UCX_TEST_ASSERT(buf[0] == '0' && buf[1] == '1' && buf[2] == 'X',
             "buffer incorrect after first read");
-    UCX_TEST_ASSERT(ucx_buffer_eof(b), "eof shall be set");
-
-    ucx_buffer_seek(b, 0, SEEK_SET);
-    r = ucx_buffer_read(rb+8, 1, 8, b);
-    UCX_TEST_ASSERT(r == 8, "read did not read the specified amount of bytes");
-    UCX_TEST_ASSERT(memcmp(rb, "0123456788888888", 16) == 0,
-                "buffer incorrect after second read");
-
+    
+    r = ucx_buffer_read(buf + 2, 1, 8, b);
+    UCX_TEST_ASSERT(r == 6, "wrong number of bytes read(2)");
+    UCX_TEST_ASSERT(memcmp(buf, "01234567XX", 10) == 0,
+            "buffer incorrect after second read");
+    
+    memset(buf, 'X', 32);
     ucx_buffer_seek(b, 0, SEEK_SET);
-    r = ucx_buffer_read(rb, 3, 6, b);
-    UCX_TEST_ASSERT(r == 15,
-            "three byte read did not read the desired amount of bytes");
-    UCX_TEST_ASSERT(memcmp(rb, "8888888801234568", 16) == 0,
-                    "buffer incorrect after three byte read");
-
+    r = ucx_buffer_read(buf, 3, 3, b);
+    
+    UCX_TEST_ASSERT(r == 2, "wrong number of blocks read");
+    UCX_TEST_ASSERT(memcmp(buf, "012345XX", 8) == 0,
+            "buffer incorrect after three byte read");
+    
+    
     UCX_TEST_END
-
-    ucx_buffer_free(b);
-    free(buffer);
+    
+    
 }
 
 UCX_TEST_IMPLEMENT(test_ucx_buffer_extract) {
     char *buffer = (char*) malloc(16);
     strcpy(buffer, "this is a test!");
 
-    UcxBuffer *src = ucx_buffer_new(buffer, 16, UCX_BUFFER_AUTOFREE),
-            *dst = ucx_buffer_extract(src, 5, 5, UCX_BUFFER_DEFAULT);
+    UcxBuffer *src = ucx_buffer_new(buffer, 16, UCX_BUFFER_AUTOFREE);
+    src->size = 15;
+    UcxBuffer *dst = ucx_buffer_extract(src, 5, 5, UCX_BUFFER_DEFAULT);
 
     UCX_TEST_BEGIN
+    UCX_TEST_ASSERT(dst != NULL, "ucx_buffer_extract returned NULL");
+            
     UCX_TEST_ASSERT((dst->flags & UCX_BUFFER_AUTOFREE) == UCX_BUFFER_AUTOFREE,
             "autofree flag shall be enforced");
     UCX_TEST_ASSERT(dst->size == 5, "wrong size for new buffer");
@@ -234,3 +269,48 @@
     ucx_buffer_free(dst);
     ucx_buffer_free(src);
 }
+
+UCX_TEST_IMPLEMENT(test_ucx_buffer_generic_copy) {
+    UcxBuffer *b1 = ucx_buffer_new(NULL, 64, UCX_BUFFER_DEFAULT);
+    UcxBuffer *b2 = ucx_buffer_new(NULL, 2, UCX_BUFFER_AUTOEXTEND);
+    
+    UCX_TEST_BEGIN
+    
+    ucx_buffer_write("01234567", 1, 8, b1);
+    ucx_buffer_write("abcdefgh", 1, 8, b1);
+    UCX_TEST_ASSERT(b1->size == 16, "failed to fill buffer b1");
+    ucx_buffer_seek(b1, 0, SEEK_SET);
+    
+    size_t ncp = ucx_buffer_copy(b1, b2, ucx_buffer_read, ucx_buffer_write);
+    UCX_TEST_ASSERT(ncp == 16, "wrong number of copied bytes");
+    UCX_TEST_ASSERT(b2->size == 16, "b2 has wrong size");
+    UCX_TEST_ASSERT(memcmp(b1->space, b2->space, 16) == 0,
+            "b1 and b2 have not the same content");
+    
+    memset(b2->space, 0, b2->capacity);
+    b2->pos = 0;
+    b2->size = 0;
+    ucx_buffer_seek(b1, 0, SEEK_SET);
+    
+    FILE *file = tmpfile();
+    UCX_TEST_ASSERT(file, "test file cannot be opened, test aborted");
+    
+    ncp = ucx_buffer_copy(b1, file, ucx_buffer_read, fwrite);
+    UCX_TEST_ASSERT(ncp == 16, "copied wrong number of bytes to file");
+    
+    fseek(file, 0, SEEK_SET);
+    
+    ncp = ucx_buffer_copy(file, b2, fread, ucx_buffer_write);
+    UCX_TEST_ASSERT(ncp == 16, "copied wrong number of bytes from file");
+    
+    UCX_TEST_ASSERT(memcmp(b1->space, b2->space, 16) == 0,
+            "b1 and b2 content mismatch");
+    
+    fclose(file);
+    
+    
+    UCX_TEST_END
+    
+    ucx_buffer_free(b1);
+    ucx_buffer_free(b2);
+}
--- a/test/buffer_tests.h	Sun Nov 04 20:50:12 2012 +0100
+++ b/test/buffer_tests.h	Fri Nov 30 13:10:58 2012 +0100
@@ -16,11 +16,13 @@
 
 UCX_TEST_DECLARE(test_ucx_buffer_seektell);
 UCX_TEST_DECLARE(test_ucx_buffer_putc);
+UCX_TEST_DECLARE(test_ucx_buffer_putc_ax);
 UCX_TEST_DECLARE(test_ucx_buffer_getc);
 UCX_TEST_DECLARE(test_ucx_buffer_write);
 UCX_TEST_DECLARE(test_ucx_buffer_write_ax);
 UCX_TEST_DECLARE(test_ucx_buffer_read);
 UCX_TEST_DECLARE(test_ucx_buffer_extract);
+UCX_TEST_DECLARE(test_ucx_buffer_generic_copy);
 
 #ifdef	__cplusplus
 }
--- a/test/main.c	Sun Nov 04 20:50:12 2012 +0100
+++ b/test/main.c	Fri Nov 30 13:10:58 2012 +0100
@@ -166,11 +166,13 @@
         /* UcxMemstream Tests */
         ucx_test_register(suite, test_ucx_buffer_seektell);
         ucx_test_register(suite, test_ucx_buffer_putc);
+        ucx_test_register(suite, test_ucx_buffer_putc_ax);
         ucx_test_register(suite, test_ucx_buffer_getc);
         ucx_test_register(suite, test_ucx_buffer_write);
         ucx_test_register(suite, test_ucx_buffer_write_ax);
         ucx_test_register(suite, test_ucx_buffer_read);
         ucx_test_register(suite, test_ucx_buffer_extract);
+        ucx_test_register(suite, test_ucx_buffer_generic_copy);
 
         ucx_test_run(suite, stdout);
         fflush(stdout);
--- a/test/map_tests.c	Sun Nov 04 20:50:12 2012 +0100
+++ b/test/map_tests.c	Fri Nov 30 13:10:58 2012 +0100
@@ -266,7 +266,7 @@
 
     UCX_TEST_BEGIN
     FILE *f = tmpfile();
-    UCX_TEST_ASSERT(f, "test file cannot be opened, test aborted")
+    UCX_TEST_ASSERT(f, "test file cannot be opened, test aborted");
     int r;
     r = ucx_map_store_enc(map, f, NULL, NULL);
     ucx_map_free(map);
--- a/ucx/buffer.c	Sun Nov 04 20:50:12 2012 +0100
+++ b/ucx/buffer.c	Fri Nov 30 13:10:58 2012 +0100
@@ -3,22 +3,23 @@
 #include <stdlib.h>
 #include <string.h>
 
-UcxBuffer *ucx_buffer_new(void *space, size_t length, int flags) {
+UcxBuffer *ucx_buffer_new(void *space, size_t size, int flags) {
     UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer));
     if (buffer) {
         buffer->flags = flags;
         if (!space) {
-            buffer->space = malloc(length);
+            buffer->space = malloc(size);
             if (!buffer->space) {
                 free(buffer);
                 return NULL;
             }
-            memset(buffer->space, 0, length);
+            memset(buffer->space, 0, size);
             buffer->flags |= UCX_BUFFER_AUTOFREE;
         } else {
             buffer->space = space;
         }
-        buffer->size = length;
+        buffer->capacity = size;
+        buffer->size = 0;
 
         buffer->pos = 0;
     }
@@ -33,8 +34,11 @@
     free(buffer);
 }
 
-UcxBuffer *restrict ucx_buffer_extract(
-        UcxBuffer *restrict src, size_t start, size_t length, int flags) {
+UcxBuffer* ucx_buffer_extract(
+        UcxBuffer *src, size_t start, size_t length, int flags) {
+    if(src->size == 0) {
+        return NULL;
+    }
     if (length == 0) {
         length = src->size - start;
     }
@@ -42,17 +46,18 @@
         return NULL;
     }
 
-    UcxBuffer *restrict dst = (UcxBuffer*) malloc(sizeof(UcxBuffer));
+    UcxBuffer *dst = (UcxBuffer*) malloc(sizeof(UcxBuffer));
     if (dst) {
         dst->space = malloc(length);
         if (!dst->space) {
             free(dst);
             return NULL;
         }
+        dst->capacity = length;
         dst->size = length;
         dst->flags = flags | UCX_BUFFER_AUTOFREE;
         dst->pos = 0;
-        memcpy(dst->space, (char*)src->space+start, length);
+        memcpy(dst->space, src->space+start, length);
     }
     return dst;
 }
@@ -67,12 +72,12 @@
         npos = buffer->pos;
         break;
     case SEEK_END:
-        npos = strlen((const char*) buffer->space);
+        npos = buffer->size;
         break;
     }
 
     npos += offset;
-
+    
     if (npos < 0 || npos > buffer->size) {
         return -1;
     } else {
@@ -86,57 +91,114 @@
     return buffer->pos >= buffer->size;
 }
 
-size_t ucx_bufio(void* d, size_t s, size_t n, UcxBuffer *b, _Bool read) {
-    size_t len = s*n;
-    if (b->pos + len > b->size) {
-        if ((b->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
-            size_t newsize = b->size;
-            while (b->pos + len > newsize) newsize <<= 1;
-            void *newspace = realloc(b->space, newsize);
-            if (newspace) {
-                memset((char*)newspace+b->size, 0, newsize-b->size);
-                b->space = newspace;
-                b->size = newsize;
-            } else {
-                len = -1;
+int ucx_buffer_extend(UcxBuffer *buffer, size_t len) {
+    size_t newcap = buffer->capacity;
+    while (buffer->pos + len > newcap) newcap <<= 1;
+    
+    char *newspace = realloc(buffer->space, newcap);
+    if (newspace) {
+        memset(newspace+buffer->size, 0, newcap-buffer->size);
+        buffer->space = newspace;
+        buffer->capacity = newcap;
+    } else {
+        return -1;
+    }
+    
+    return 0;
+}
+
+size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems,
+        UcxBuffer *buffer) {
+    size_t len = size * nitems;
+    if (buffer->pos + len > buffer->capacity) {
+        if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
+            if(ucx_buffer_extend(buffer, len)) {
+                return -1;
             }
         } else {
-            len = b->size - b->pos;
-            if (s > 1) len -= len%s;
+            len = buffer->capacity - buffer->pos;
+            if (size > 1) len -= len%size;
         }
     }
-
+    
     if (len <= 0) {
         return len;
     }
+    
+    memcpy(buffer->space + buffer->pos, ptr, len);
+    buffer->pos += len;
+    if(buffer->pos > buffer->size) {
+        buffer->size = buffer->pos;
+    }
+    
+    return len / size;
+}
 
-    if (read) {
-        memcpy(d, (char*)b->space+b->pos, len);
-    } else {
-        memcpy((char*)b->space+b->pos, d, len);
+size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
+        UcxBuffer *buffer) {
+    size_t len = size * nitems;
+    if (buffer->pos + len > buffer->size) {
+        len = buffer->size - buffer->pos;
+        if (size > 1) len -= len%size;
     }
-    b->pos += len;
-
-    return len;
+    
+    if (len <= 0) {
+        return len;
+    }
+    
+    memcpy(ptr, buffer->space + buffer->pos, len);
+    buffer->pos += len;
+    
+    return len / size;
 }
 
 int ucx_buffer_putc(UcxBuffer *buffer, int c) {
-    if (ucx_buffer_eof(buffer)) {
-        return EOF;
-    } else {
-        c &= 0xFF;
-        ((char*)(buffer->space))[buffer->pos] = (char) c;
-        buffer->pos++;
-        return c;
+    if(buffer->pos >= buffer->capacity) {
+        if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
+            if(ucx_buffer_extend(buffer, 1)) {
+                return EOF;
+            }
+        } else {
+            return EOF;
+        }
     }
+    
+    c &= 0xFF;
+    buffer->space[buffer->pos] = (char) c;
+    buffer->pos++;
+    if(buffer->pos > buffer->size) {
+        buffer->size = buffer->pos;
+    }
+    return c;
 }
 
 int ucx_buffer_getc(UcxBuffer *buffer) {
     if (ucx_buffer_eof(buffer)) {
         return EOF;
     } else {
-        int c = ((char*)(buffer->space))[buffer->pos];
+        int c = buffer->space[buffer->pos];
         buffer->pos++;
         return c;
     }
 }
+
+size_t ucx_buffer_generic_copy(void *s1, void *s2,
+        read_func readfnc, write_func writefnc, size_t bufsize) {
+    size_t ncp = 0;
+    char *buf = malloc(bufsize);
+    if(buf == NULL) {
+        return 0;
+    }
+    
+    size_t r;
+    while((r = readfnc(buf, 1, bufsize, s1)) != 0) {
+        r = writefnc(buf, 1, r, s2);
+        ncp += r;
+        if(r == 0) {
+            break;
+        }
+    }
+    
+    free(buf);
+    return ncp;
+}
--- a/ucx/buffer.h	Sun Nov 04 20:50:12 2012 +0100
+++ b/ucx/buffer.h	Fri Nov 30 13:10:58 2012 +0100
@@ -16,14 +16,15 @@
 
 /* the user shall not modify values, but may get the latest pointer */
 typedef struct {
-    void *space;
+    char *space;
     size_t pos;
+    size_t capacity;
     size_t size;
     int flags;
 } UcxBuffer;
 
 /* if space is NULL, new space is allocated and the autofree flag is enforced */
-UcxBuffer *ucx_buffer_new(void *space, size_t length, int flags);
+UcxBuffer *ucx_buffer_new(void *space, size_t size, int flags);
 void ucx_buffer_free(UcxBuffer* buffer);
 
 /*
@@ -31,7 +32,7 @@
  * if length is zero, the whole remaining buffer shall be extracted
  * the position of the new buffer is set to zero
  */
-UcxBuffer *restrict ucx_buffer_extract(UcxBuffer *restrict src,
+UcxBuffer* ucx_buffer_extract(UcxBuffer *src,
         size_t start, size_t length, int flags);
 #define ucx_buffer_clone(src,flags) \
     ucx_buffer_extract(src, 0, 0, flags)
@@ -51,21 +52,46 @@
 int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence);
 
 /*
- * returns non-zero, iff the current buffer position has exceeded the last
+ * returns non-zero, if the current buffer position has exceeded the last
  * available byte of the underlying buffer
  *
  */
 int ucx_buffer_eof(UcxBuffer *buffer);
 
-size_t ucx_bufio(void *d, size_t s, size_t n, UcxBuffer* b, _Bool read);
+
+int ucx_buffere_extend(UcxBuffer *buffer, size_t len);
+
+size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems,
+        UcxBuffer *buffer);
+
+size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
+        UcxBuffer *buffer);
+
 /* when autoextend is enabled, ensure you get the latest pointer to the data */
-#define ucx_buffer_write(data, itemsize, nitems, buffer) \
-    ucx_bufio(data, itemsize, nitems, buffer, 0)
-#define ucx_buffer_read(data, itemsize, nitems, buffer) \
-        ucx_bufio(data, itemsize, nitems, buffer, 1)
+//define ucx_buffer_write(data, itemsize, nitems, buffer) \
+//    ucx_bufio(data, itemsize, nitems, buffer, 0)
+//define ucx_buffer_read(data, itemsize, nitems, buffer) \
+//        ucx_bufio(data, itemsize, nitems, buffer, 1)
 int ucx_buffer_putc(UcxBuffer *b, int c);
 int ucx_buffer_getc(UcxBuffer *b);
 
+
+/*
+ * copies all bytes from s1 to s2
+ * uses the read function r to read from s1 und writes the data using the
+ * write function w to s2
+ * returns the number of bytes copied
+ */
+size_t ucx_buffer_generic_copy(void *s1, void *s2, read_func r, write_func w,
+        size_t bufsize);
+
+
+#define UCX_DEFAULT_BUFFER_SIZE 0x4000000
+
+#define ucx_buffer_copy(s1,s2,r,w) \
+    ucx_buffer_generic_copy(s1, s2, (read_func)r, (write_func)w, \
+    UCX_DEFAULT_BUFFER_SIZE)
+
 #ifdef	__cplusplus
 }
 #endif
--- a/ucx/ucx.h	Sun Nov 04 20:50:12 2012 +0100
+++ b/ucx/ucx.h	Fri Nov 30 13:10:58 2012 +0100
@@ -37,6 +37,12 @@
 /* element,custom data -> copy of element */
 typedef void*(*copy_func)(void*,void*);
 
+/* buffer, element size, element count, stream */
+typedef size_t(*write_func)(const void*, size_t, size_t, void*);
+
+/* buffer, element size, element count, stream */
+typedef size_t(*read_func)(void*, size_t, size_t, void*);
+
 #ifdef	__cplusplus
 }
 #endif

mercurial