diff -r 990734f548ef -r 655020a30e77 ucx/buffer.c --- 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 #include -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; +}