diff -r 0f94d369bb02 -r 1bcaac272cdf ucx/buffer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/buffer.c Fri Nov 30 21:18:13 2012 +0100 @@ -0,0 +1,204 @@ +#include "buffer.h" +#include +#include +#include + +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(size); + if (!buffer->space) { + free(buffer); + return NULL; + } + memset(buffer->space, 0, size); + buffer->flags |= UCX_BUFFER_AUTOFREE; + } else { + buffer->space = space; + } + buffer->capacity = size; + buffer->size = 0; + + buffer->pos = 0; + } + + return buffer; +} + +void ucx_buffer_free(UcxBuffer *buffer) { + if ((buffer->flags & UCX_BUFFER_AUTOFREE) == UCX_BUFFER_AUTOFREE) { + free(buffer->space); + } + free(buffer); +} + +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; + } + if (start+length > src->size) { + return NULL; + } + + 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, src->space+start, length); + } + return dst; +} + +int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence) { + off_t npos; + switch (whence) { + case SEEK_SET: + npos = 0; + break; + case SEEK_CUR: + npos = buffer->pos; + break; + case SEEK_END: + npos = buffer->size; + break; + } + + npos += offset; + + if (npos < 0 || npos > buffer->size) { + return -1; + } else { + buffer->pos = npos; + return 0; + } + +} + +int ucx_buffer_eof(UcxBuffer *buffer) { + return buffer->pos >= buffer->size; +} + +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 = 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; +} + +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; + } + + 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(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 = 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; +}