Fri, 30 Nov 2012 13:10:58 +0100
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