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
     1.1 --- a/test/buffer_tests.c	Sun Nov 04 20:50:12 2012 +0100
     1.2 +++ b/test/buffer_tests.c	Fri Nov 30 13:10:58 2012 +0100
     1.3 @@ -5,11 +5,8 @@
     1.4  #include "buffer_tests.h"
     1.5  
     1.6  UCX_TEST_IMPLEMENT(test_ucx_buffer_seektell) {
     1.7 -    char *buffer = (char*) malloc(16);
     1.8 -    memset(buffer, 32, 7);
     1.9 -    buffer[7] = 0;
    1.10 -
    1.11 -    UcxBuffer *b = ucx_buffer_new(buffer, 16, UCX_BUFFER_DEFAULT);
    1.12 +    UcxBuffer *b = ucx_buffer_new(NULL, 32, UCX_BUFFER_DEFAULT);
    1.13 +    b->size = 16; // less than capacity
    1.14      int r;
    1.15  
    1.16      UCX_TEST_BEGIN
    1.17 @@ -34,43 +31,81 @@
    1.18  
    1.19      r = ucx_buffer_seek(b, -5, SEEK_END);
    1.20      UCX_TEST_ASSERT(r == 0, "seek END-5 failed");
    1.21 -    UCX_TEST_ASSERT(b->pos == 2, "seek END-5 set wrong position");
    1.22 +    UCX_TEST_ASSERT(b->pos == 11, "seek END-5 set wrong position");
    1.23  
    1.24 -    r = ucx_buffer_seek(b, -10, SEEK_END);
    1.25 +    r = ucx_buffer_seek(b, -20, SEEK_END);
    1.26      UCX_TEST_ASSERT(r != 0, "seek END beyond bounds shall fail");
    1.27 -    UCX_TEST_ASSERT(b->pos == 2,
    1.28 +    UCX_TEST_ASSERT(b->pos == 11,
    1.29              "failed seek shall leave pos unchanged");
    1.30  
    1.31      UCX_TEST_END
    1.32  
    1.33      ucx_buffer_free(b);
    1.34 +}
    1.35 +
    1.36 +UCX_TEST_IMPLEMENT(test_ucx_buffer_putc) {
    1.37 +    char *buffer = (char*) malloc(16);
    1.38 +    memset(buffer, 32, 16);
    1.39 +
    1.40 +    UcxBuffer *b = ucx_buffer_new(buffer, 16, UCX_BUFFER_DEFAULT);
    1.41 +    b->size = b->capacity;
    1.42 +    int r;
    1.43 +
    1.44 +    UCX_TEST_BEGIN
    1.45 +
    1.46 +    ucx_buffer_putc(b, '0');
    1.47 +    ucx_buffer_putc(b, '0');
    1.48 +    ucx_buffer_putc(b, '0');
    1.49 +    
    1.50 +    UCX_TEST_ASSERT(b->pos == 3, "pos wrong after first 3 puts");
    1.51 +    ucx_buffer_seek(b, 10, SEEK_CUR);
    1.52 +    
    1.53 +    ucx_buffer_putc(b, '0');
    1.54 +    ucx_buffer_putc(b, '0');
    1.55 +    ucx_buffer_putc(b, '0');
    1.56 +    
    1.57 +    UCX_TEST_ASSERT(b->pos == 16, "pos wrong after last 3 puts");
    1.58 +    UCX_TEST_ASSERT(ucx_buffer_eof(b), "eof not set");
    1.59 +    UCX_TEST_ASSERT(ucx_buffer_putc(b, 48) == EOF,
    1.60 +            "put shall return EOF when buffer is full");
    1.61 +    
    1.62 +    ucx_buffer_seek(b, 3, SEEK_SET);
    1.63 +    ucx_buffer_putc(b, 'a');
    1.64 +    ucx_buffer_putc(b, 'b');
    1.65 +    ucx_buffer_putc(b, 'c');
    1.66 +    
    1.67 +    UCX_TEST_ASSERT(b->size == 16, "wrong size after seek and puts");
    1.68 +    UCX_TEST_ASSERT(memcmp(buffer, "000abc       000", 16) == 0,
    1.69 +            "buffer contains incorrect content");
    1.70 +
    1.71 +    UCX_TEST_END
    1.72 +
    1.73 +    ucx_buffer_free(b);
    1.74      free(buffer);
    1.75  }
    1.76  
    1.77 -UCX_TEST_IMPLEMENT(test_ucx_buffer_putc) {
    1.78 -    char *buffer = (char*) malloc(16);
    1.79 -    memset(buffer, 32, 16);
    1.80 -
    1.81 -    UcxBuffer *b = ucx_buffer_new(buffer, 16, UCX_BUFFER_DEFAULT);
    1.82 -    int r;
    1.83 -
    1.84 +UCX_TEST_IMPLEMENT(test_ucx_buffer_putc_ax) {
    1.85 +    UcxBuffer *b = ucx_buffer_new(NULL, 2, UCX_BUFFER_AUTOEXTEND);
    1.86 +    
    1.87      UCX_TEST_BEGIN
    1.88 -
    1.89 -    ucx_buffer_putc(b, 48); ucx_buffer_putc(b, 48); ucx_buffer_putc(b, 48);
    1.90 -    UCX_TEST_ASSERT(b->pos == 3, "pos wrong after first 3 puts");
    1.91 -    ucx_buffer_seek(b, 10, SEEK_CUR);
    1.92 -    ucx_buffer_putc(b, 48); ucx_buffer_putc(b, 48); ucx_buffer_putc(b, 48);
    1.93 -    UCX_TEST_ASSERT(b->pos == 16, "pos wrong after last 3 puts");
    1.94 -    UCX_TEST_ASSERT(ucx_buffer_eof(b), "eof not set");
    1.95 -    UCX_TEST_ASSERT(ucx_buffer_putc(b, 48) == EOF,
    1.96 -            "put shall return EOF when buffer is full");
    1.97 -    UCX_TEST_ASSERT(memcmp(buffer, "000          000", 16) == 0,
    1.98 -            "buffer contains incorrect content");
    1.99 -
   1.100 +    
   1.101 +    ucx_buffer_putc(b, '0');
   1.102 +    ucx_buffer_putc(b, '1');
   1.103 +    
   1.104 +    UCX_TEST_ASSERT(b->pos == 2, "pos wrong after first 2 puts");
   1.105 +    UCX_TEST_ASSERT(b->capacity == 2, "buffer erroneously extended");
   1.106 +    
   1.107 +    ucx_buffer_putc(b, 'a');
   1.108 +    
   1.109 +    UCX_TEST_ASSERT(b->pos == 3, "pos wrong after 1 put");
   1.110 +    UCX_TEST_ASSERT(b->capacity == 4, "buffer not properly extended");
   1.111 +    UCX_TEST_ASSERT(b->size == 3, "wrong buffer size");
   1.112 +    
   1.113 +    UCX_TEST_ASSERT(b->space[2] == 'a', "wrong content");
   1.114 +    
   1.115      UCX_TEST_END
   1.116 -
   1.117 -    ucx_buffer_free(b);
   1.118 -    free(buffer);
   1.119 +    
   1.120 +    
   1.121  }
   1.122  
   1.123  UCX_TEST_IMPLEMENT(test_ucx_buffer_getc) {
   1.124 @@ -81,6 +116,7 @@
   1.125      }
   1.126  
   1.127      UcxBuffer *b = ucx_buffer_new(buffer, 16, UCX_BUFFER_DEFAULT);
   1.128 +    b->size = b->capacity;
   1.129      int r;
   1.130  
   1.131      UCX_TEST_BEGIN
   1.132 @@ -132,7 +168,7 @@
   1.133      memset(buffer, 49, 16);
   1.134      ucx_buffer_seek(b, 0, SEEK_SET);
   1.135      r = ucx_buffer_write((void*)threebytestring, 3, 6, b);
   1.136 -    UCX_TEST_ASSERT(r == 15, "three byte string not correctly trimed");
   1.137 +    UCX_TEST_ASSERT(r == 5, "three byte string not correctly trimed");
   1.138      UCX_TEST_ASSERT(b->pos == 15,
   1.139              "position after write of three byte string incorrect");
   1.140      UCX_TEST_ASSERT(!ucx_buffer_eof(b), "eof shall not be set");
   1.141 @@ -146,7 +182,7 @@
   1.142  }
   1.143  
   1.144  UCX_TEST_IMPLEMENT(test_ucx_buffer_write_ax) {
   1.145 -    char *buffer = (char*) malloc(4);
   1.146 +    char *buffer = (char*) malloc(16);
   1.147  
   1.148      UcxBuffer *b = ucx_buffer_new(buffer, 16,
   1.149              UCX_BUFFER_AUTOEXTEND | UCX_BUFFER_AUTOFREE);
   1.150 @@ -158,7 +194,7 @@
   1.151      r = ucx_buffer_write((void*)teststring, 1, 20, b);
   1.152      buffer = (char*) b->space; /*autoextend enabled, we MUST retrieve pointer*/
   1.153      UCX_TEST_ASSERT(r == 20, "not all characters written");
   1.154 -    UCX_TEST_ASSERT(b->size == 32, "buffer not properly extended");
   1.155 +    UCX_TEST_ASSERT(b->capacity == 32, "buffer not properly extended");
   1.156      UCX_TEST_ASSERT(b->pos == 20, "position incorrect");
   1.157      UCX_TEST_ASSERT(memcmp(buffer,
   1.158              "this is way too much\0\0\0\0\0\0\0\0\0\0\0\0", 32) == 0,
   1.159 @@ -170,54 +206,53 @@
   1.160  }
   1.161  
   1.162  UCX_TEST_IMPLEMENT(test_ucx_buffer_read) {
   1.163 -    char *buffer = (char*) malloc(16);
   1.164 -    memset(buffer, 56, 8);
   1.165 -    for (int i = 8; i < 16 ; i++) {
   1.166 -        buffer[i] = 40+i;
   1.167 -    }
   1.168 -
   1.169 -    UcxBuffer *b = ucx_buffer_new(buffer, 16, UCX_BUFFER_DEFAULT);
   1.170 +    UcxBuffer *b = ucx_buffer_new(NULL, 8, UCX_BUFFER_AUTOFREE);
   1.171 +    
   1.172 +    char buf[32];
   1.173 +    memset(buf, 'X', 32);
   1.174      int r;
   1.175 -
   1.176 +    
   1.177      UCX_TEST_BEGIN
   1.178 -
   1.179 -    char rb[16];
   1.180 -    memset(rb, 32, 16);
   1.181 -
   1.182 -    ucx_buffer_seek(b, 8, SEEK_SET);
   1.183 -    r = ucx_buffer_read(rb, 1, 16, b);
   1.184 -    UCX_TEST_ASSERT(r == 8, "read did not stop at buffer end");
   1.185 -    UCX_TEST_ASSERT(memcmp(rb, "01234567        ", 16) == 0,
   1.186 +    
   1.187 +    ucx_buffer_write("01234567", 1, 8, b);
   1.188 +    UCX_TEST_ASSERT(b->pos == 8, "buffer not correctly filled");
   1.189 +    b->pos = 0;
   1.190 +    
   1.191 +    r = ucx_buffer_read(buf, 1, 2, b);
   1.192 +    UCX_TEST_ASSERT(r == 2, "wrong number of bytes read");
   1.193 +    UCX_TEST_ASSERT(buf[0] == '0' && buf[1] == '1' && buf[2] == 'X',
   1.194              "buffer incorrect after first read");
   1.195 -    UCX_TEST_ASSERT(ucx_buffer_eof(b), "eof shall be set");
   1.196 -
   1.197 +    
   1.198 +    r = ucx_buffer_read(buf + 2, 1, 8, b);
   1.199 +    UCX_TEST_ASSERT(r == 6, "wrong number of bytes read(2)");
   1.200 +    UCX_TEST_ASSERT(memcmp(buf, "01234567XX", 10) == 0,
   1.201 +            "buffer incorrect after second read");
   1.202 +    
   1.203 +    memset(buf, 'X', 32);
   1.204      ucx_buffer_seek(b, 0, SEEK_SET);
   1.205 -    r = ucx_buffer_read(rb+8, 1, 8, b);
   1.206 -    UCX_TEST_ASSERT(r == 8, "read did not read the specified amount of bytes");
   1.207 -    UCX_TEST_ASSERT(memcmp(rb, "0123456788888888", 16) == 0,
   1.208 -                "buffer incorrect after second read");
   1.209 -
   1.210 -    ucx_buffer_seek(b, 0, SEEK_SET);
   1.211 -    r = ucx_buffer_read(rb, 3, 6, b);
   1.212 -    UCX_TEST_ASSERT(r == 15,
   1.213 -            "three byte read did not read the desired amount of bytes");
   1.214 -    UCX_TEST_ASSERT(memcmp(rb, "8888888801234568", 16) == 0,
   1.215 -                    "buffer incorrect after three byte read");
   1.216 -
   1.217 +    r = ucx_buffer_read(buf, 3, 3, b);
   1.218 +    
   1.219 +    UCX_TEST_ASSERT(r == 2, "wrong number of blocks read");
   1.220 +    UCX_TEST_ASSERT(memcmp(buf, "012345XX", 8) == 0,
   1.221 +            "buffer incorrect after three byte read");
   1.222 +    
   1.223 +    
   1.224      UCX_TEST_END
   1.225 -
   1.226 -    ucx_buffer_free(b);
   1.227 -    free(buffer);
   1.228 +    
   1.229 +    
   1.230  }
   1.231  
   1.232  UCX_TEST_IMPLEMENT(test_ucx_buffer_extract) {
   1.233      char *buffer = (char*) malloc(16);
   1.234      strcpy(buffer, "this is a test!");
   1.235  
   1.236 -    UcxBuffer *src = ucx_buffer_new(buffer, 16, UCX_BUFFER_AUTOFREE),
   1.237 -            *dst = ucx_buffer_extract(src, 5, 5, UCX_BUFFER_DEFAULT);
   1.238 +    UcxBuffer *src = ucx_buffer_new(buffer, 16, UCX_BUFFER_AUTOFREE);
   1.239 +    src->size = 15;
   1.240 +    UcxBuffer *dst = ucx_buffer_extract(src, 5, 5, UCX_BUFFER_DEFAULT);
   1.241  
   1.242      UCX_TEST_BEGIN
   1.243 +    UCX_TEST_ASSERT(dst != NULL, "ucx_buffer_extract returned NULL");
   1.244 +            
   1.245      UCX_TEST_ASSERT((dst->flags & UCX_BUFFER_AUTOFREE) == UCX_BUFFER_AUTOFREE,
   1.246              "autofree flag shall be enforced");
   1.247      UCX_TEST_ASSERT(dst->size == 5, "wrong size for new buffer");
   1.248 @@ -234,3 +269,48 @@
   1.249      ucx_buffer_free(dst);
   1.250      ucx_buffer_free(src);
   1.251  }
   1.252 +
   1.253 +UCX_TEST_IMPLEMENT(test_ucx_buffer_generic_copy) {
   1.254 +    UcxBuffer *b1 = ucx_buffer_new(NULL, 64, UCX_BUFFER_DEFAULT);
   1.255 +    UcxBuffer *b2 = ucx_buffer_new(NULL, 2, UCX_BUFFER_AUTOEXTEND);
   1.256 +    
   1.257 +    UCX_TEST_BEGIN
   1.258 +    
   1.259 +    ucx_buffer_write("01234567", 1, 8, b1);
   1.260 +    ucx_buffer_write("abcdefgh", 1, 8, b1);
   1.261 +    UCX_TEST_ASSERT(b1->size == 16, "failed to fill buffer b1");
   1.262 +    ucx_buffer_seek(b1, 0, SEEK_SET);
   1.263 +    
   1.264 +    size_t ncp = ucx_buffer_copy(b1, b2, ucx_buffer_read, ucx_buffer_write);
   1.265 +    UCX_TEST_ASSERT(ncp == 16, "wrong number of copied bytes");
   1.266 +    UCX_TEST_ASSERT(b2->size == 16, "b2 has wrong size");
   1.267 +    UCX_TEST_ASSERT(memcmp(b1->space, b2->space, 16) == 0,
   1.268 +            "b1 and b2 have not the same content");
   1.269 +    
   1.270 +    memset(b2->space, 0, b2->capacity);
   1.271 +    b2->pos = 0;
   1.272 +    b2->size = 0;
   1.273 +    ucx_buffer_seek(b1, 0, SEEK_SET);
   1.274 +    
   1.275 +    FILE *file = tmpfile();
   1.276 +    UCX_TEST_ASSERT(file, "test file cannot be opened, test aborted");
   1.277 +    
   1.278 +    ncp = ucx_buffer_copy(b1, file, ucx_buffer_read, fwrite);
   1.279 +    UCX_TEST_ASSERT(ncp == 16, "copied wrong number of bytes to file");
   1.280 +    
   1.281 +    fseek(file, 0, SEEK_SET);
   1.282 +    
   1.283 +    ncp = ucx_buffer_copy(file, b2, fread, ucx_buffer_write);
   1.284 +    UCX_TEST_ASSERT(ncp == 16, "copied wrong number of bytes from file");
   1.285 +    
   1.286 +    UCX_TEST_ASSERT(memcmp(b1->space, b2->space, 16) == 0,
   1.287 +            "b1 and b2 content mismatch");
   1.288 +    
   1.289 +    fclose(file);
   1.290 +    
   1.291 +    
   1.292 +    UCX_TEST_END
   1.293 +    
   1.294 +    ucx_buffer_free(b1);
   1.295 +    ucx_buffer_free(b2);
   1.296 +}
     2.1 --- a/test/buffer_tests.h	Sun Nov 04 20:50:12 2012 +0100
     2.2 +++ b/test/buffer_tests.h	Fri Nov 30 13:10:58 2012 +0100
     2.3 @@ -16,11 +16,13 @@
     2.4  
     2.5  UCX_TEST_DECLARE(test_ucx_buffer_seektell);
     2.6  UCX_TEST_DECLARE(test_ucx_buffer_putc);
     2.7 +UCX_TEST_DECLARE(test_ucx_buffer_putc_ax);
     2.8  UCX_TEST_DECLARE(test_ucx_buffer_getc);
     2.9  UCX_TEST_DECLARE(test_ucx_buffer_write);
    2.10  UCX_TEST_DECLARE(test_ucx_buffer_write_ax);
    2.11  UCX_TEST_DECLARE(test_ucx_buffer_read);
    2.12  UCX_TEST_DECLARE(test_ucx_buffer_extract);
    2.13 +UCX_TEST_DECLARE(test_ucx_buffer_generic_copy);
    2.14  
    2.15  #ifdef	__cplusplus
    2.16  }
     3.1 --- a/test/main.c	Sun Nov 04 20:50:12 2012 +0100
     3.2 +++ b/test/main.c	Fri Nov 30 13:10:58 2012 +0100
     3.3 @@ -166,11 +166,13 @@
     3.4          /* UcxMemstream Tests */
     3.5          ucx_test_register(suite, test_ucx_buffer_seektell);
     3.6          ucx_test_register(suite, test_ucx_buffer_putc);
     3.7 +        ucx_test_register(suite, test_ucx_buffer_putc_ax);
     3.8          ucx_test_register(suite, test_ucx_buffer_getc);
     3.9          ucx_test_register(suite, test_ucx_buffer_write);
    3.10          ucx_test_register(suite, test_ucx_buffer_write_ax);
    3.11          ucx_test_register(suite, test_ucx_buffer_read);
    3.12          ucx_test_register(suite, test_ucx_buffer_extract);
    3.13 +        ucx_test_register(suite, test_ucx_buffer_generic_copy);
    3.14  
    3.15          ucx_test_run(suite, stdout);
    3.16          fflush(stdout);
     4.1 --- a/test/map_tests.c	Sun Nov 04 20:50:12 2012 +0100
     4.2 +++ b/test/map_tests.c	Fri Nov 30 13:10:58 2012 +0100
     4.3 @@ -266,7 +266,7 @@
     4.4  
     4.5      UCX_TEST_BEGIN
     4.6      FILE *f = tmpfile();
     4.7 -    UCX_TEST_ASSERT(f, "test file cannot be opened, test aborted")
     4.8 +    UCX_TEST_ASSERT(f, "test file cannot be opened, test aborted");
     4.9      int r;
    4.10      r = ucx_map_store_enc(map, f, NULL, NULL);
    4.11      ucx_map_free(map);
     5.1 --- a/ucx/buffer.c	Sun Nov 04 20:50:12 2012 +0100
     5.2 +++ b/ucx/buffer.c	Fri Nov 30 13:10:58 2012 +0100
     5.3 @@ -3,22 +3,23 @@
     5.4  #include <stdlib.h>
     5.5  #include <string.h>
     5.6  
     5.7 -UcxBuffer *ucx_buffer_new(void *space, size_t length, int flags) {
     5.8 +UcxBuffer *ucx_buffer_new(void *space, size_t size, int flags) {
     5.9      UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer));
    5.10      if (buffer) {
    5.11          buffer->flags = flags;
    5.12          if (!space) {
    5.13 -            buffer->space = malloc(length);
    5.14 +            buffer->space = malloc(size);
    5.15              if (!buffer->space) {
    5.16                  free(buffer);
    5.17                  return NULL;
    5.18              }
    5.19 -            memset(buffer->space, 0, length);
    5.20 +            memset(buffer->space, 0, size);
    5.21              buffer->flags |= UCX_BUFFER_AUTOFREE;
    5.22          } else {
    5.23              buffer->space = space;
    5.24          }
    5.25 -        buffer->size = length;
    5.26 +        buffer->capacity = size;
    5.27 +        buffer->size = 0;
    5.28  
    5.29          buffer->pos = 0;
    5.30      }
    5.31 @@ -33,8 +34,11 @@
    5.32      free(buffer);
    5.33  }
    5.34  
    5.35 -UcxBuffer *restrict ucx_buffer_extract(
    5.36 -        UcxBuffer *restrict src, size_t start, size_t length, int flags) {
    5.37 +UcxBuffer* ucx_buffer_extract(
    5.38 +        UcxBuffer *src, size_t start, size_t length, int flags) {
    5.39 +    if(src->size == 0) {
    5.40 +        return NULL;
    5.41 +    }
    5.42      if (length == 0) {
    5.43          length = src->size - start;
    5.44      }
    5.45 @@ -42,17 +46,18 @@
    5.46          return NULL;
    5.47      }
    5.48  
    5.49 -    UcxBuffer *restrict dst = (UcxBuffer*) malloc(sizeof(UcxBuffer));
    5.50 +    UcxBuffer *dst = (UcxBuffer*) malloc(sizeof(UcxBuffer));
    5.51      if (dst) {
    5.52          dst->space = malloc(length);
    5.53          if (!dst->space) {
    5.54              free(dst);
    5.55              return NULL;
    5.56          }
    5.57 +        dst->capacity = length;
    5.58          dst->size = length;
    5.59          dst->flags = flags | UCX_BUFFER_AUTOFREE;
    5.60          dst->pos = 0;
    5.61 -        memcpy(dst->space, (char*)src->space+start, length);
    5.62 +        memcpy(dst->space, src->space+start, length);
    5.63      }
    5.64      return dst;
    5.65  }
    5.66 @@ -67,12 +72,12 @@
    5.67          npos = buffer->pos;
    5.68          break;
    5.69      case SEEK_END:
    5.70 -        npos = strlen((const char*) buffer->space);
    5.71 +        npos = buffer->size;
    5.72          break;
    5.73      }
    5.74  
    5.75      npos += offset;
    5.76 -
    5.77 +    
    5.78      if (npos < 0 || npos > buffer->size) {
    5.79          return -1;
    5.80      } else {
    5.81 @@ -86,57 +91,114 @@
    5.82      return buffer->pos >= buffer->size;
    5.83  }
    5.84  
    5.85 -size_t ucx_bufio(void* d, size_t s, size_t n, UcxBuffer *b, _Bool read) {
    5.86 -    size_t len = s*n;
    5.87 -    if (b->pos + len > b->size) {
    5.88 -        if ((b->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
    5.89 -            size_t newsize = b->size;
    5.90 -            while (b->pos + len > newsize) newsize <<= 1;
    5.91 -            void *newspace = realloc(b->space, newsize);
    5.92 -            if (newspace) {
    5.93 -                memset((char*)newspace+b->size, 0, newsize-b->size);
    5.94 -                b->space = newspace;
    5.95 -                b->size = newsize;
    5.96 -            } else {
    5.97 -                len = -1;
    5.98 +int ucx_buffer_extend(UcxBuffer *buffer, size_t len) {
    5.99 +    size_t newcap = buffer->capacity;
   5.100 +    while (buffer->pos + len > newcap) newcap <<= 1;
   5.101 +    
   5.102 +    char *newspace = realloc(buffer->space, newcap);
   5.103 +    if (newspace) {
   5.104 +        memset(newspace+buffer->size, 0, newcap-buffer->size);
   5.105 +        buffer->space = newspace;
   5.106 +        buffer->capacity = newcap;
   5.107 +    } else {
   5.108 +        return -1;
   5.109 +    }
   5.110 +    
   5.111 +    return 0;
   5.112 +}
   5.113 +
   5.114 +size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems,
   5.115 +        UcxBuffer *buffer) {
   5.116 +    size_t len = size * nitems;
   5.117 +    if (buffer->pos + len > buffer->capacity) {
   5.118 +        if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
   5.119 +            if(ucx_buffer_extend(buffer, len)) {
   5.120 +                return -1;
   5.121              }
   5.122          } else {
   5.123 -            len = b->size - b->pos;
   5.124 -            if (s > 1) len -= len%s;
   5.125 +            len = buffer->capacity - buffer->pos;
   5.126 +            if (size > 1) len -= len%size;
   5.127          }
   5.128      }
   5.129 -
   5.130 +    
   5.131      if (len <= 0) {
   5.132          return len;
   5.133      }
   5.134 +    
   5.135 +    memcpy(buffer->space + buffer->pos, ptr, len);
   5.136 +    buffer->pos += len;
   5.137 +    if(buffer->pos > buffer->size) {
   5.138 +        buffer->size = buffer->pos;
   5.139 +    }
   5.140 +    
   5.141 +    return len / size;
   5.142 +}
   5.143  
   5.144 -    if (read) {
   5.145 -        memcpy(d, (char*)b->space+b->pos, len);
   5.146 -    } else {
   5.147 -        memcpy((char*)b->space+b->pos, d, len);
   5.148 +size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
   5.149 +        UcxBuffer *buffer) {
   5.150 +    size_t len = size * nitems;
   5.151 +    if (buffer->pos + len > buffer->size) {
   5.152 +        len = buffer->size - buffer->pos;
   5.153 +        if (size > 1) len -= len%size;
   5.154      }
   5.155 -    b->pos += len;
   5.156 -
   5.157 -    return len;
   5.158 +    
   5.159 +    if (len <= 0) {
   5.160 +        return len;
   5.161 +    }
   5.162 +    
   5.163 +    memcpy(ptr, buffer->space + buffer->pos, len);
   5.164 +    buffer->pos += len;
   5.165 +    
   5.166 +    return len / size;
   5.167  }
   5.168  
   5.169  int ucx_buffer_putc(UcxBuffer *buffer, int c) {
   5.170 -    if (ucx_buffer_eof(buffer)) {
   5.171 -        return EOF;
   5.172 -    } else {
   5.173 -        c &= 0xFF;
   5.174 -        ((char*)(buffer->space))[buffer->pos] = (char) c;
   5.175 -        buffer->pos++;
   5.176 -        return c;
   5.177 +    if(buffer->pos >= buffer->capacity) {
   5.178 +        if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
   5.179 +            if(ucx_buffer_extend(buffer, 1)) {
   5.180 +                return EOF;
   5.181 +            }
   5.182 +        } else {
   5.183 +            return EOF;
   5.184 +        }
   5.185      }
   5.186 +    
   5.187 +    c &= 0xFF;
   5.188 +    buffer->space[buffer->pos] = (char) c;
   5.189 +    buffer->pos++;
   5.190 +    if(buffer->pos > buffer->size) {
   5.191 +        buffer->size = buffer->pos;
   5.192 +    }
   5.193 +    return c;
   5.194  }
   5.195  
   5.196  int ucx_buffer_getc(UcxBuffer *buffer) {
   5.197      if (ucx_buffer_eof(buffer)) {
   5.198          return EOF;
   5.199      } else {
   5.200 -        int c = ((char*)(buffer->space))[buffer->pos];
   5.201 +        int c = buffer->space[buffer->pos];
   5.202          buffer->pos++;
   5.203          return c;
   5.204      }
   5.205  }
   5.206 +
   5.207 +size_t ucx_buffer_generic_copy(void *s1, void *s2,
   5.208 +        read_func readfnc, write_func writefnc, size_t bufsize) {
   5.209 +    size_t ncp = 0;
   5.210 +    char *buf = malloc(bufsize);
   5.211 +    if(buf == NULL) {
   5.212 +        return 0;
   5.213 +    }
   5.214 +    
   5.215 +    size_t r;
   5.216 +    while((r = readfnc(buf, 1, bufsize, s1)) != 0) {
   5.217 +        r = writefnc(buf, 1, r, s2);
   5.218 +        ncp += r;
   5.219 +        if(r == 0) {
   5.220 +            break;
   5.221 +        }
   5.222 +    }
   5.223 +    
   5.224 +    free(buf);
   5.225 +    return ncp;
   5.226 +}
     6.1 --- a/ucx/buffer.h	Sun Nov 04 20:50:12 2012 +0100
     6.2 +++ b/ucx/buffer.h	Fri Nov 30 13:10:58 2012 +0100
     6.3 @@ -16,14 +16,15 @@
     6.4  
     6.5  /* the user shall not modify values, but may get the latest pointer */
     6.6  typedef struct {
     6.7 -    void *space;
     6.8 +    char *space;
     6.9      size_t pos;
    6.10 +    size_t capacity;
    6.11      size_t size;
    6.12      int flags;
    6.13  } UcxBuffer;
    6.14  
    6.15  /* if space is NULL, new space is allocated and the autofree flag is enforced */
    6.16 -UcxBuffer *ucx_buffer_new(void *space, size_t length, int flags);
    6.17 +UcxBuffer *ucx_buffer_new(void *space, size_t size, int flags);
    6.18  void ucx_buffer_free(UcxBuffer* buffer);
    6.19  
    6.20  /*
    6.21 @@ -31,7 +32,7 @@
    6.22   * if length is zero, the whole remaining buffer shall be extracted
    6.23   * the position of the new buffer is set to zero
    6.24   */
    6.25 -UcxBuffer *restrict ucx_buffer_extract(UcxBuffer *restrict src,
    6.26 +UcxBuffer* ucx_buffer_extract(UcxBuffer *src,
    6.27          size_t start, size_t length, int flags);
    6.28  #define ucx_buffer_clone(src,flags) \
    6.29      ucx_buffer_extract(src, 0, 0, flags)
    6.30 @@ -51,21 +52,46 @@
    6.31  int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence);
    6.32  
    6.33  /*
    6.34 - * returns non-zero, iff the current buffer position has exceeded the last
    6.35 + * returns non-zero, if the current buffer position has exceeded the last
    6.36   * available byte of the underlying buffer
    6.37   *
    6.38   */
    6.39  int ucx_buffer_eof(UcxBuffer *buffer);
    6.40  
    6.41 -size_t ucx_bufio(void *d, size_t s, size_t n, UcxBuffer* b, _Bool read);
    6.42 +
    6.43 +int ucx_buffere_extend(UcxBuffer *buffer, size_t len);
    6.44 +
    6.45 +size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems,
    6.46 +        UcxBuffer *buffer);
    6.47 +
    6.48 +size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
    6.49 +        UcxBuffer *buffer);
    6.50 +
    6.51  /* when autoextend is enabled, ensure you get the latest pointer to the data */
    6.52 -#define ucx_buffer_write(data, itemsize, nitems, buffer) \
    6.53 -    ucx_bufio(data, itemsize, nitems, buffer, 0)
    6.54 -#define ucx_buffer_read(data, itemsize, nitems, buffer) \
    6.55 -        ucx_bufio(data, itemsize, nitems, buffer, 1)
    6.56 +//define ucx_buffer_write(data, itemsize, nitems, buffer) \
    6.57 +//    ucx_bufio(data, itemsize, nitems, buffer, 0)
    6.58 +//define ucx_buffer_read(data, itemsize, nitems, buffer) \
    6.59 +//        ucx_bufio(data, itemsize, nitems, buffer, 1)
    6.60  int ucx_buffer_putc(UcxBuffer *b, int c);
    6.61  int ucx_buffer_getc(UcxBuffer *b);
    6.62  
    6.63 +
    6.64 +/*
    6.65 + * copies all bytes from s1 to s2
    6.66 + * uses the read function r to read from s1 und writes the data using the
    6.67 + * write function w to s2
    6.68 + * returns the number of bytes copied
    6.69 + */
    6.70 +size_t ucx_buffer_generic_copy(void *s1, void *s2, read_func r, write_func w,
    6.71 +        size_t bufsize);
    6.72 +
    6.73 +
    6.74 +#define UCX_DEFAULT_BUFFER_SIZE 0x4000000
    6.75 +
    6.76 +#define ucx_buffer_copy(s1,s2,r,w) \
    6.77 +    ucx_buffer_generic_copy(s1, s2, (read_func)r, (write_func)w, \
    6.78 +    UCX_DEFAULT_BUFFER_SIZE)
    6.79 +
    6.80  #ifdef	__cplusplus
    6.81  }
    6.82  #endif
     7.1 --- a/ucx/ucx.h	Sun Nov 04 20:50:12 2012 +0100
     7.2 +++ b/ucx/ucx.h	Fri Nov 30 13:10:58 2012 +0100
     7.3 @@ -37,6 +37,12 @@
     7.4  /* element,custom data -> copy of element */
     7.5  typedef void*(*copy_func)(void*,void*);
     7.6  
     7.7 +/* buffer, element size, element count, stream */
     7.8 +typedef size_t(*write_func)(const void*, size_t, size_t, void*);
     7.9 +
    7.10 +/* buffer, element size, element count, stream */
    7.11 +typedef size_t(*read_func)(void*, size_t, size_t, void*);
    7.12 +
    7.13  #ifdef	__cplusplus
    7.14  }
    7.15  #endif

mercurial