added autoextend feature to buffer

Wed, 10 Oct 2012 14:18:06 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 10 Oct 2012 14:18:06 +0200
changeset 64
16590c9c497c
parent 63
1d3500806565
child 65
7b2f2cab6348

added autoextend feature to buffer

and we celebrate the 50th test case

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
ucx/buffer.c file | annotate | diff | comparison | revisions
ucx/buffer.h file | annotate | diff | comparison | revisions
     1.1 --- a/test/buffer_tests.c	Wed Oct 10 13:58:51 2012 +0200
     1.2 +++ b/test/buffer_tests.c	Wed Oct 10 14:18:06 2012 +0200
     1.3 @@ -145,6 +145,30 @@
     1.4      free(buffer);
     1.5  }
     1.6  
     1.7 +UCX_TEST_IMPLEMENT(test_ucx_buffer_write_ax) {
     1.8 +    char *buffer = malloc(4);
     1.9 +
    1.10 +    UcxBuffer *b = ucx_buffer_new(buffer, 16,
    1.11 +            UCX_BUFFER_AUTOEXTEND | UCX_BUFFER_AUTOFREE);
    1.12 +    int r;
    1.13 +
    1.14 +    UCX_TEST_BEGIN
    1.15 +
    1.16 +    char* teststring = "this is way too much";
    1.17 +    r = ucx_buffer_write(teststring, 1, 20, b);
    1.18 +    buffer = b->space; /* autoextend is enabled, so we MUST retrieve pointer */
    1.19 +    UCX_TEST_ASSERT(r == 20, "not all characters written");
    1.20 +    UCX_TEST_ASSERT(b->size == 32, "buffer not properly extended");
    1.21 +    UCX_TEST_ASSERT(b->pos == 20, "position incorrect");
    1.22 +    UCX_TEST_ASSERT(memcmp(buffer,
    1.23 +            "this is way too much\0\0\0\0\0\0\0\0\0\0\0\0", 32) == 0,
    1.24 +            "incorrect buffer content");
    1.25 +
    1.26 +    UCX_TEST_END
    1.27 +
    1.28 +    ucx_buffer_free(b);
    1.29 +}
    1.30 +
    1.31  UCX_TEST_IMPLEMENT(test_ucx_buffer_read) {
    1.32      char *buffer = malloc(16);
    1.33      memset(buffer, 56, 8);
     2.1 --- a/test/buffer_tests.h	Wed Oct 10 13:58:51 2012 +0200
     2.2 +++ b/test/buffer_tests.h	Wed Oct 10 14:18:06 2012 +0200
     2.3 @@ -18,6 +18,7 @@
     2.4  UCX_TEST_DECLARE(test_ucx_buffer_putc);
     2.5  UCX_TEST_DECLARE(test_ucx_buffer_getc);
     2.6  UCX_TEST_DECLARE(test_ucx_buffer_write);
     2.7 +UCX_TEST_DECLARE(test_ucx_buffer_write_ax);
     2.8  UCX_TEST_DECLARE(test_ucx_buffer_read);
     2.9  UCX_TEST_DECLARE(test_ucx_buffer_extract);
    2.10  
     3.1 --- a/test/main.c	Wed Oct 10 13:58:51 2012 +0200
     3.2 +++ b/test/main.c	Wed Oct 10 14:18:06 2012 +0200
     3.3 @@ -168,6 +168,7 @@
     3.4          ucx_test_register(suite, test_ucx_buffer_putc);
     3.5          ucx_test_register(suite, test_ucx_buffer_getc);
     3.6          ucx_test_register(suite, test_ucx_buffer_write);
     3.7 +        ucx_test_register(suite, test_ucx_buffer_write_ax);
     3.8          ucx_test_register(suite, test_ucx_buffer_read);
     3.9          ucx_test_register(suite, test_ucx_buffer_extract);
    3.10  
     4.1 --- a/ucx/buffer.c	Wed Oct 10 13:58:51 2012 +0200
     4.2 +++ b/ucx/buffer.c	Wed Oct 10 14:18:06 2012 +0200
     4.3 @@ -87,16 +87,27 @@
     4.4  }
     4.5  
     4.6  size_t ucx_bufio(void* d, size_t s, size_t n, UcxBuffer *b, _Bool read) {
     4.7 -    size_t len;
     4.8 -    if (b->pos + s*n > b->size) {
     4.9 -        len = b->size - b->pos;
    4.10 -        if (s > 1) len -= len%s;
    4.11 -    } else {
    4.12 -        len = s*n;
    4.13 +    size_t len = s*n;
    4.14 +    if (b->pos + len > b->size) {
    4.15 +        if ((b->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
    4.16 +            size_t newsize = b->size;
    4.17 +            while (b->pos + len > newsize) newsize <<= 1;
    4.18 +            void *newspace = realloc(b->space, newsize);
    4.19 +            if (newspace) {
    4.20 +                memset((char*)newspace+b->size, 0, newsize-b->size);
    4.21 +                b->space = newspace;
    4.22 +                b->size = newsize;
    4.23 +            } else {
    4.24 +                len = -1;
    4.25 +            }
    4.26 +        } else {
    4.27 +            len = b->size - b->pos;
    4.28 +            if (s > 1) len -= len%s;
    4.29 +        }
    4.30      }
    4.31  
    4.32 -    if (len == 0) {
    4.33 -        return 0;
    4.34 +    if (len <= 0) {
    4.35 +        return len;
    4.36      }
    4.37  
    4.38      if (read) {
     5.1 --- a/ucx/buffer.h	Wed Oct 10 13:58:51 2012 +0200
     5.2 +++ b/ucx/buffer.h	Wed Oct 10 14:18:06 2012 +0200
     5.3 @@ -10,9 +10,10 @@
     5.4  
     5.5  #define UCX_BUFFER_DEFAULT      0x00
     5.6  #define UCX_BUFFER_AUTOFREE     0x01
     5.7 +/* the buffer may automatically double its size on write operations */
     5.8  #define UCX_BUFFER_AUTOEXTEND   0x02
     5.9  
    5.10 -/* the user shall not modify values, but can get an up to date space pointer */
    5.11 +/* the user shall not modify values, but may get the latest pointer */
    5.12  typedef struct {
    5.13      void *space;
    5.14      size_t pos;
    5.15 @@ -56,6 +57,7 @@
    5.16  int ucx_buffer_eof(UcxBuffer *buffer);
    5.17  
    5.18  size_t ucx_bufio(void *d, size_t s, size_t n, UcxBuffer* b, _Bool read);
    5.19 +/* when autoextend is enabled, ensure you get the latest pointer to the data */
    5.20  #define ucx_buffer_write(data, itemsize, nitems, buffer) \
    5.21      ucx_bufio(data, itemsize, nitems, buffer, 0)
    5.22  #define ucx_buffer_read(data, itemsize, nitems, buffer) \

mercurial