# HG changeset patch # User Mike Becker # Date 1349855697 -7200 # Node ID abae4669fba7d4b455fc5c55f11e8e48e38249b6 # Parent c80c910fe1918d01d270aa62dc2941dbdb1b5cec renamed UcxMemstream to UcxBuffer diff -r c80c910fe191 -r abae4669fba7 test/Makefile --- a/test/Makefile Wed Oct 10 09:34:13 2012 +0200 +++ b/test/Makefile Wed Oct 10 09:54:57 2012 +0200 @@ -35,7 +35,7 @@ SRC += map_tests.c SRC += string_tests.c SRC += logging_tests.c -SRC += memstream_tests.c +SRC += buffer_tests.c OBJ = $(SRC:%.c=../build/%.$(OBJ_EXT)) diff -r c80c910fe191 -r abae4669fba7 test/buffer_tests.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/buffer_tests.c Wed Oct 10 09:54:57 2012 +0200 @@ -0,0 +1,186 @@ +/* + * + */ + +#include "buffer_tests.h" + +UCX_TEST_IMPLEMENT(test_ucx_buffer_seektell) { + char *buffer = malloc(16); + memset(buffer, 32, 7); + buffer[7] = 0; + + UcxBuffer *b = ucx_buffer_new(buffer, 16); + int r; + + UCX_TEST_BEGIN + + r = ucx_buffer_seek(b, 5, SEEK_SET); + UCX_TEST_ASSERT(r == 0, "seek SET+5 failed"); + UCX_TEST_ASSERT(ucx_buffer_tell(b) == 5, "seek SET+5 set wrong position"); + + r = ucx_buffer_seek(b, 20, SEEK_SET); + UCX_TEST_ASSERT(r != 0, "seek beyond bounds shall fail"); + UCX_TEST_ASSERT(ucx_buffer_tell(b) == 5, + "failed seek shall leave pos unchanged"); + + r = ucx_buffer_seek(b, 5, SEEK_CUR); + UCX_TEST_ASSERT(r == 0, "seek CUR+5 failed"); + UCX_TEST_ASSERT(ucx_buffer_tell(b) == 10, "seek CUR+5 set wrong position"); + + r = ucx_buffer_seek(b, 10, SEEK_CUR); + UCX_TEST_ASSERT(r != 0, "seek CUR beyond bounds shall fail"); + UCX_TEST_ASSERT(ucx_buffer_tell(b) == 10, + "failed seek shall leave pos unchanged"); + + r = ucx_buffer_seek(b, -5, SEEK_END); + UCX_TEST_ASSERT(r == 0, "seek END-5 failed"); + UCX_TEST_ASSERT(ucx_buffer_tell(b) == 2, "seek END-5 set wrong position"); + + r = ucx_buffer_seek(b, -10, SEEK_END); + UCX_TEST_ASSERT(r != 0, "seek END beyond bounds shall fail"); + UCX_TEST_ASSERT(ucx_buffer_tell(b) == 2, + "failed seek shall leave pos unchanged"); + + UCX_TEST_END + + ucx_buffer_free(b); + free(buffer); +} + +UCX_TEST_IMPLEMENT(test_ucx_buffer_putc) { + char *buffer = malloc(16); + memset(buffer, 32, 16); + + UcxBuffer *b = ucx_buffer_new(buffer, 16); + int r; + + UCX_TEST_BEGIN + + ucx_buffer_putc(b, 48); ucx_buffer_putc(b, 48); ucx_buffer_putc(b, 48); + UCX_TEST_ASSERT(ucx_buffer_tell(b) == 3, "pos wrong after first 3 puts"); + ucx_buffer_seek(b, 10, SEEK_CUR); + ucx_buffer_putc(b, 48); ucx_buffer_putc(b, 48); ucx_buffer_putc(b, 48); + UCX_TEST_ASSERT(ucx_buffer_tell(b) == 16, "pos wrong after last 3 puts"); + UCX_TEST_ASSERT(ucx_buffer_eof(b), "eof not set"); + UCX_TEST_ASSERT(ucx_buffer_putc(b, 48) == EOF, "put shall return EOF on memof"); + UCX_TEST_ASSERT(memcmp(buffer, "000 000", 16) == 0, + "buffer contains incorrect content"); + + UCX_TEST_END + + ucx_buffer_free(b); + free(buffer); +} + +UCX_TEST_IMPLEMENT(test_ucx_buffer_getc) { + char *buffer = malloc(16); + memset(buffer, 32, 8); + for (int i = 8; i < 16 ; i++) { + buffer[i] = 40+i; + } + + UcxBuffer *b = ucx_buffer_new(buffer, 16); + int r; + + UCX_TEST_BEGIN + + char rb[16]; + for (int i = 0 ; i < 16 ; i++) { + UCX_TEST_ASSERT(ucx_buffer_tell(b) == i, "pos wrong during read loop"); + UCX_TEST_ASSERT(!ucx_buffer_eof(b), + "EOF shall not be set during read loop"); + rb[i] = ucx_buffer_getc(b); + } + UCX_TEST_ASSERT(ucx_buffer_tell(b) == 16, "pos wrong after read loop"); + UCX_TEST_ASSERT(ucx_buffer_eof(b), "EOF not set"); + UCX_TEST_ASSERT(memcmp(rb, " 01234567", 16) == 0, + "read data incorrect"); + + UCX_TEST_END + + ucx_buffer_free(b); + free(buffer); +} + +UCX_TEST_IMPLEMENT(test_ucx_buffer_write) { + char *buffer = malloc(16); + memset(buffer, 32, 8); + for (int i = 8; i < 16 ; i++) { + buffer[i] = 40+i; + } + + UcxBuffer *b = ucx_buffer_new(buffer, 16); + int r; + + UCX_TEST_BEGIN + + char* teststring = "this is way too much"; + r = ucx_buffer_write(teststring, 1, 20, b); + UCX_TEST_ASSERT(r == 16, "string not correctly trimed"); + UCX_TEST_ASSERT(memcmp(buffer, teststring, 16) == 0, + "buffer data incorrect"); + UCX_TEST_ASSERT(ucx_buffer_eof(b), "eof shall be set"); + + ucx_buffer_seek(b, 8, SEEK_SET); + r = ucx_buffer_write("not", 1, 3, b); + UCX_TEST_ASSERT(r == 3, "three bytes should be replace"); + UCX_TEST_ASSERT(memcmp(buffer, "this is not too much", 16) == 0, + "modified buffer is incorrect"); + + char* threebytestring = " t h r e e "; + memset(buffer, 49, 16); + ucx_buffer_seek(b, 0, SEEK_SET); + r = ucx_buffer_write(threebytestring, 3, 6, b); + UCX_TEST_ASSERT(r == 15, "three byte string not correctly trimed"); + UCX_TEST_ASSERT(ucx_buffer_tell(b) == 15, + "position after write of three byte string incorrect"); + UCX_TEST_ASSERT(!ucx_buffer_eof(b), "eof shall not be set"); + UCX_TEST_ASSERT(memcmp(buffer, " t h r e e1", 16) == 0, + "bufer is incorrect after three byte string has been written"); + + UCX_TEST_END + + ucx_buffer_free(b); + free(buffer); +} + +UCX_TEST_IMPLEMENT(test_ucx_buffer_read) { + char *buffer = malloc(16); + memset(buffer, 56, 8); + for (int i = 8; i < 16 ; i++) { + buffer[i] = 40+i; + } + + UcxBuffer *b = ucx_buffer_new(buffer, 16); + int r; + + UCX_TEST_BEGIN + + char rb[16]; + memset(rb, 32, 16); + + ucx_buffer_seek(b, 8, SEEK_SET); + r = ucx_buffer_read(rb, 1, 16, b); + UCX_TEST_ASSERT(r == 8, "read did not stop at buffer end"); + UCX_TEST_ASSERT(memcmp(rb, "01234567 ", 16) == 0, + "buffer incorrect after first read"); + UCX_TEST_ASSERT(ucx_buffer_eof(b), "eof shall be set"); + + ucx_buffer_seek(b, 0, SEEK_SET); + r = ucx_buffer_read(rb+8, 1, 8, b); + UCX_TEST_ASSERT(r == 8, "read did not read the specified amount of bytes"); + UCX_TEST_ASSERT(memcmp(rb, "0123456788888888", 16) == 0, + "buffer incorrect after second read"); + + ucx_buffer_seek(b, 0, SEEK_SET); + r = ucx_buffer_read(rb, 3, 6, b); + UCX_TEST_ASSERT(r == 15, + "three byte read did not read the desired amount of bytes"); + UCX_TEST_ASSERT(memcmp(rb, "8888888801234568", 16) == 0, + "buffer incorrect after three byte read"); + + UCX_TEST_END + + ucx_buffer_free(b); + free(buffer); +} diff -r c80c910fe191 -r abae4669fba7 test/buffer_tests.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/buffer_tests.h Wed Oct 10 09:54:57 2012 +0200 @@ -0,0 +1,28 @@ +/* + * + */ + +#ifndef MEMSTREAM_TEST_H +#define MEMSTREAM_TEST_H + +#include "ucx/test.h" +#include "ucx/buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* assume open and close to be correct */ + +UCX_TEST_DECLARE(test_ucx_buffer_seektell); +UCX_TEST_DECLARE(test_ucx_buffer_putc); +UCX_TEST_DECLARE(test_ucx_buffer_getc); +UCX_TEST_DECLARE(test_ucx_buffer_write); +UCX_TEST_DECLARE(test_ucx_buffer_read); + +#ifdef __cplusplus +} +#endif + +#endif /* MEMSTREAM_TEST_H */ + diff -r c80c910fe191 -r abae4669fba7 test/main.c --- a/test/main.c Wed Oct 10 09:34:13 2012 +0200 +++ b/test/main.c Wed Oct 10 09:54:57 2012 +0200 @@ -39,7 +39,7 @@ #include "string_tests.h" #include "mpool_tests.h" #include "map_tests.h" -#include "memstream_tests.h" +#include "buffer_tests.h" int cmp_string(void* o1, void* o2, void* data) { return strcmp((char*)o1, (char*)o2); @@ -164,11 +164,11 @@ ucx_test_register(suite, test_sstrsplit); /* UcxMemstream Tests */ - ucx_test_register(suite, test_ucx_memseektell); - ucx_test_register(suite, test_ucx_memputc); - ucx_test_register(suite, test_ucx_memgetc); - ucx_test_register(suite, test_ucx_memwrite); - ucx_test_register(suite, test_ucx_memread); + ucx_test_register(suite, test_ucx_buffer_seektell); + ucx_test_register(suite, test_ucx_buffer_putc); + ucx_test_register(suite, test_ucx_buffer_getc); + ucx_test_register(suite, test_ucx_buffer_write); + ucx_test_register(suite, test_ucx_buffer_read); ucx_test_run(suite, stdout); fflush(stdout); diff -r c80c910fe191 -r abae4669fba7 test/memstream_tests.c --- a/test/memstream_tests.c Wed Oct 10 09:34:13 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -/* - * - */ - -#include "memstream_tests.h" - -UCX_TEST_IMPLEMENT(test_ucx_memseektell) { - char *buffer = malloc(16); - memset(buffer, 32, 7); - buffer[7] = 0; - - UcxMemstream *m = ucx_memopen(buffer, 16); - int r; - - UCX_TEST_BEGIN - - r = ucx_memseek(m, 5, SEEK_SET); - UCX_TEST_ASSERT(r == 0, "seek SET+5 failed"); - UCX_TEST_ASSERT(ucx_memtell(m) == 5, "seek SET+5 set wrong position"); - - r = ucx_memseek(m, 20, SEEK_SET); - UCX_TEST_ASSERT(r != 0, "seek beyond bounds shall fail"); - UCX_TEST_ASSERT(ucx_memtell(m) == 5, - "failed seek shall leave pos unchanged"); - - r = ucx_memseek(m, 5, SEEK_CUR); - UCX_TEST_ASSERT(r == 0, "seek CUR+5 failed"); - UCX_TEST_ASSERT(ucx_memtell(m) == 10, "seek CUR+5 set wrong position"); - - r = ucx_memseek(m, 10, SEEK_CUR); - UCX_TEST_ASSERT(r != 0, "seek CUR beyond bounds shall fail"); - UCX_TEST_ASSERT(ucx_memtell(m) == 10, - "failed seek shall leave pos unchanged"); - - r = ucx_memseek(m, -5, SEEK_END); - UCX_TEST_ASSERT(r == 0, "seek END-5 failed"); - UCX_TEST_ASSERT(ucx_memtell(m) == 2, "seek END-5 set wrong position"); - - r = ucx_memseek(m, -10, SEEK_END); - UCX_TEST_ASSERT(r != 0, "seek END beyond bounds shall fail"); - UCX_TEST_ASSERT(ucx_memtell(m) == 2, - "failed seek shall leave pos unchanged"); - - UCX_TEST_END - - ucx_memclose(m); - free(buffer); -} - -UCX_TEST_IMPLEMENT(test_ucx_memputc) { - char *buffer = malloc(16); - memset(buffer, 32, 16); - - UcxMemstream *m = ucx_memopen(buffer, 16); - int r; - - UCX_TEST_BEGIN - - ucx_memputc(m, 48); ucx_memputc(m, 48); ucx_memputc(m, 48); - UCX_TEST_ASSERT(ucx_memtell(m) == 3, "pos wrong after first 3 puts"); - ucx_memseek(m, 10, SEEK_CUR); - ucx_memputc(m, 48); ucx_memputc(m, 48); ucx_memputc(m, 48); - UCX_TEST_ASSERT(ucx_memtell(m) == 16, "pos wrong after last 3 puts"); - UCX_TEST_ASSERT(ucx_memeof(m), "eof not set"); - UCX_TEST_ASSERT(ucx_memputc(m, 48) == EOF, "put shall return EOF on memof"); - UCX_TEST_ASSERT(memcmp(buffer, "000 000", 16) == 0, - "buffer contains incorrect content"); - - UCX_TEST_END - - ucx_memclose(m); - free(buffer); -} - -UCX_TEST_IMPLEMENT(test_ucx_memgetc) { - char *buffer = malloc(16); - memset(buffer, 32, 8); - for (int i = 8; i < 16 ; i++) { - buffer[i] = 40+i; - } - - UcxMemstream *m = ucx_memopen(buffer, 16); - int r; - - UCX_TEST_BEGIN - - char rb[16]; - for (int i = 0 ; i < 16 ; i++) { - UCX_TEST_ASSERT(ucx_memtell(m) == i, "pos wrong during read loop"); - UCX_TEST_ASSERT(!ucx_memeof(m), - "EOF shall not be set during read loop"); - rb[i] = ucx_memgetc(m); - } - UCX_TEST_ASSERT(ucx_memtell(m) == 16, "pos wrong after read loop"); - UCX_TEST_ASSERT(ucx_memeof(m), "EOF not set"); - UCX_TEST_ASSERT(memcmp(rb, " 01234567", 16) == 0, - "read data incorrect"); - - UCX_TEST_END - - ucx_memclose(m); - free(buffer); -} - -UCX_TEST_IMPLEMENT(test_ucx_memwrite) { - char *buffer = malloc(16); - memset(buffer, 32, 8); - for (int i = 8; i < 16 ; i++) { - buffer[i] = 40+i; - } - - UcxMemstream *m = ucx_memopen(buffer, 16); - int r; - - UCX_TEST_BEGIN - - char* teststring = "this is way too much"; - r = ucx_memwrite(teststring, 1, 20, m); - UCX_TEST_ASSERT(r == 16, "string not correctly trimed"); - UCX_TEST_ASSERT(memcmp(buffer, teststring, 16) == 0, - "buffer data incorrect"); - UCX_TEST_ASSERT(ucx_memeof(m), "eof shall be set"); - - ucx_memseek(m, 8, SEEK_SET); - r = ucx_memwrite("not", 1, 3, m); - UCX_TEST_ASSERT(r == 3, "three bytes should be replace"); - UCX_TEST_ASSERT(memcmp(buffer, "this is not too much", 16) == 0, - "modified buffer is incorrect"); - - char* threebytestring = " t h r e e "; - memset(buffer, 49, 16); - ucx_memseek(m, 0, SEEK_SET); - r = ucx_memwrite(threebytestring, 3, 6, m); - UCX_TEST_ASSERT(r == 15, "three byte string not correctly trimed"); - UCX_TEST_ASSERT(ucx_memtell(m) == 15, - "position after write of three byte string incorrect"); - UCX_TEST_ASSERT(!ucx_memeof(m), "eof shall not be set"); - UCX_TEST_ASSERT(memcmp(buffer, " t h r e e1", 16) == 0, - "bufer is incorrect after three byte string has been written"); - - UCX_TEST_END - - ucx_memclose(m); - free(buffer); -} - -UCX_TEST_IMPLEMENT(test_ucx_memread) { - char *buffer = malloc(16); - memset(buffer, 56, 8); - for (int i = 8; i < 16 ; i++) { - buffer[i] = 40+i; - } - - UcxMemstream *m = ucx_memopen(buffer, 16); - int r; - - UCX_TEST_BEGIN - - char rb[16]; - memset(rb, 32, 16); - - ucx_memseek(m, 8, SEEK_SET); - r = ucx_memread(rb, 1, 16, m); - UCX_TEST_ASSERT(r == 8, "read did not stop at buffer end"); - UCX_TEST_ASSERT(memcmp(rb, "01234567 ", 16) == 0, - "buffer incorrect after first read"); - UCX_TEST_ASSERT(ucx_memeof(m), "eof shall be set"); - - ucx_memseek(m, 0, SEEK_SET); - r = ucx_memread(rb+8, 1, 8, m); - UCX_TEST_ASSERT(r == 8, "read did not read the specified amount of bytes"); - UCX_TEST_ASSERT(memcmp(rb, "0123456788888888", 16) == 0, - "buffer incorrect after second read"); - - ucx_memseek(m, 0, SEEK_SET); - r = ucx_memread(rb, 3, 6, m); - UCX_TEST_ASSERT(r == 15, - "three byte read did not read the desired amount of bytes"); - UCX_TEST_ASSERT(memcmp(rb, "8888888801234568", 16) == 0, - "buffer incorrect after three byte read"); - - UCX_TEST_END - - ucx_memclose(m); - free(buffer); -} diff -r c80c910fe191 -r abae4669fba7 test/memstream_tests.h --- a/test/memstream_tests.h Wed Oct 10 09:34:13 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - * - */ - -#ifndef MEMSTREAM_TEST_H -#define MEMSTREAM_TEST_H - -#include "ucx/test.h" -#include "ucx/memstream.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* assume open and close to be correct */ - -UCX_TEST_DECLARE(test_ucx_memseektell); -UCX_TEST_DECLARE(test_ucx_memputc); -UCX_TEST_DECLARE(test_ucx_memgetc); -UCX_TEST_DECLARE(test_ucx_memwrite); -UCX_TEST_DECLARE(test_ucx_memread); - -#ifdef __cplusplus -} -#endif - -#endif /* MEMSTREAM_TEST_H */ - diff -r c80c910fe191 -r abae4669fba7 ucx/Makefile --- a/ucx/Makefile Wed Oct 10 09:34:13 2012 +0200 +++ b/ucx/Makefile Wed Oct 10 09:54:57 2012 +0200 @@ -37,7 +37,7 @@ SRC += test.c SRC += allocator.c SRC += logging.c -SRC += memstream.c +SRC += buffer.c OBJ = $(SRC:%.c=../build/%.$(OBJ_EXT)) diff -r c80c910fe191 -r abae4669fba7 ucx/buffer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/buffer.c Wed Oct 10 09:54:57 2012 +0200 @@ -0,0 +1,118 @@ +#include "buffer.h" +#include +#include +#include + +struct UcxBuffer { + void *space; + off_t pos; + size_t length; + _Bool autofree; +}; + +UcxBuffer *ucx_buffer_new(void *space, size_t length) { + UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer)); + if (buffer) { + if (!space) { + buffer->space = malloc(length); + if (!buffer->space) { + free(buffer); + return NULL; + } + memset(buffer->space, 0, length); + buffer->autofree = 1; + } else { + buffer->space = space; + buffer->autofree = 0; + } + buffer->length = length; + + buffer->pos = 0; + } + + return buffer; +} + +void ucx_buffer_free(UcxBuffer *buffer) { + if (buffer->autofree) { + free(buffer->space); + } + free(buffer); +} + +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 = strlen(buffer->space); + break; + } + + npos += offset; + + if (npos < 0 || npos > buffer->length) { + return -1; + } else { + buffer->pos = npos; + return 0; + } + +} + +int ucx_buffer_eof(UcxBuffer *buffer) { + return buffer->pos >= buffer->length; +} + +size_t ucx_buffer_tell(UcxBuffer *buffer) { + return buffer->pos; +} + +size_t ucx_bufio(void* d, size_t s, size_t n, UcxBuffer *b, _Bool read) { + size_t len; + if (b->pos + s*n > b->length) { + len = b->length - b->pos; + if (s > 1) len -= len%s; + } else { + len = s*n; + } + + if (len == 0) { + return 0; + } + + if (read) { + memcpy(d, (char*)b->space+b->pos, len); + } else { + memcpy((char*)b->space+b->pos, d, len); + } + b->pos += len; + + return len; +} + +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; + } +} + +int ucx_buffer_getc(UcxBuffer *buffer) { + if (ucx_buffer_eof(buffer)) { + return EOF; + } else { + int c = ((char*)(buffer->space))[buffer->pos]; + buffer->pos++; + return c; + } +} diff -r c80c910fe191 -r abae4669fba7 ucx/buffer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/buffer.h Wed Oct 10 09:54:57 2012 +0200 @@ -0,0 +1,52 @@ +#ifndef BUFFER_H +#define BUFFER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* the user shall not modify values */ +typedef struct UcxBuffer UcxBuffer; + +UcxBuffer *ucx_buffer_new(void *space, size_t length); +void ucx_buffer_free(UcxBuffer* buffer); + +/* + * Moves the position of the buffer to a new position relative to whence. + * + * SEEK_SET marks the start of the buffer + * SEEK_CUR marks the current position + * SEEK_END marks the first 0-byte in the buffer + * + * ucx_memseek returns 0 on success and -1 if the new position is beyond the + * bounds of the allocated buffer. In that case the position of the buffer + * remains unchanged. + * + */ +int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence); +size_t ucx_buffer_tell(UcxBuffer *buffer); + +/* + * returns non-zero, iff the current buffer position has exceeded the last + * available byte of the underlying buffer + * + */ +int ucx_buffer_eof(UcxBuffer *buffer); + +size_t ucx_bufio(void *d, size_t s, size_t n, UcxBuffer* b, _Bool read); +#define ucx_buffer_write(data, itemsize, nitems, buffer) \ + ucx_bufio(data, itemsize, nitems, buffer, 0) +#define ucx_buffer_read(data, itemsize, nitems, buffer) \ + ucx_bufio(data, itemsize, nitems, buffer, 1) +int ucx_buffer_putc(UcxBuffer *b, int c); +int ucx_buffer_getc(UcxBuffer *b); + +#ifdef __cplusplus +} +#endif + +#endif /* BUFFER_H */ + diff -r c80c910fe191 -r abae4669fba7 ucx/memstream.c --- a/ucx/memstream.c Wed Oct 10 09:34:13 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -#include "memstream.h" -#include -#include -#include - -struct UcxMemstream { - void *space; - off_t pos; - size_t length; - _Bool autofree; -}; - -UcxMemstream *ucx_memopen(void *space, size_t length) { - UcxMemstream *stream = (UcxMemstream*) malloc(sizeof(UcxMemstream)); - if (stream) { - if (!space) { - stream->space = malloc(length); - if (!stream->space) { - free(stream); - return NULL; - } - memset(stream->space, 0, length); - stream->autofree = 1; - } else { - stream->space = space; - stream->autofree = 0; - } - stream->length = length; - - stream->pos = 0; - } - - return stream; -} - -void ucx_memclose(UcxMemstream *stream) { - if (stream->autofree) { - free(stream->space); - } - free(stream); -} - -int ucx_memseek(UcxMemstream *stream, off_t offset, int whence) { - off_t npos; - switch (whence) { - case SEEK_SET: - npos = 0; - break; - case SEEK_CUR: - npos = stream->pos; - break; - case SEEK_END: - npos = strlen(stream->space); - break; - } - - npos += offset; - - if (npos < 0 || npos > stream->length) { - return -1; - } else { - stream->pos = npos; - return 0; - } - -} - -int ucx_memeof(UcxMemstream *stream) { - return stream->pos >= stream->length; -} - -size_t ucx_memtell(UcxMemstream *stream) { - return stream->pos; -} - -size_t ucx_memio(void* d, size_t s, size_t n, UcxMemstream *m, _Bool read) { - size_t len; - if (m->pos + s*n > m->length) { - len = m->length - m->pos; - if (s > 1) len -= len%s; - } else { - len = s*n; - } - - if (len == 0) { - return 0; - } - - if (read) { - memcpy(d, (char*)m->space+m->pos, len); - } else { - memcpy((char*)m->space+m->pos, d, len); - } - m->pos += len; - - return len; -} - -int ucx_memputc(UcxMemstream *stream, int c) { - if (ucx_memeof(stream)) { - return EOF; - } else { - c &= 0xFF; - ((char*)(stream->space))[stream->pos] = (char) c; - stream->pos++; - return c; - } -} - -int ucx_memgetc(UcxMemstream *stream) { - if (ucx_memeof(stream)) { - return EOF; - } else { - int c = ((char*)(stream->space))[stream->pos]; - stream->pos++; - return c; - } -} diff -r c80c910fe191 -r abae4669fba7 ucx/memstream.h --- a/ucx/memstream.h Wed Oct 10 09:34:13 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -#ifndef MEMSTREAM_H -#define MEMSTREAM_H - -#include - -/* as fmemopen is a C extension we provide our cross plattform stuff here */ - -#ifdef __cplusplus -extern "C" { -#endif - - -/* as FILE is opaque, we don't do evil hacks but provide an alternative */ -typedef struct UcxMemstream UcxMemstream; - -UcxMemstream *ucx_memopen(void *space, size_t length); -void ucx_memclose(UcxMemstream* stream); - -/* - * Moves the position of the stream to a new position relative to whence. - * - * SEEK_SET marks the start of the buffer - * SEEK_CUR marks the current position - * SEEK_END marks the first 0-byte in the buffer - * - * ucx_memseek returns 0 on success and -1 if the new position is beyond the - * bounds of the allocated buffer. In that case the position of the stream - * remains unchanged. - * - */ -int ucx_memseek(UcxMemstream *stream, off_t offset, int whence); -size_t ucx_memtell(UcxMemstream *stream); - -/* - * returns non-zero, iff the current stream position has exceeded the last - * available byte of the underlying buffer - * - */ -int ucx_memeof(UcxMemstream *stream); - -/* memwrite, memread, memputc and memreadc shall not generate overflows */ -size_t ucx_memio(void *d, size_t s, size_t n, UcxMemstream* m, _Bool read); -#define ucx_memwrite(data, itemsize, nitems, memstream) \ - ucx_memio(data, itemsize, nitems, memstream, 0) -#define ucx_memread(data, itemsize, nitems, memstream) \ - ucx_memio(data, itemsize, nitems, memstream, 1) -int ucx_memputc(UcxMemstream *stream, int c); -int ucx_memgetc(UcxMemstream *stream); - -#ifdef __cplusplus -} -#endif - -#endif /* MEMSTREAM_H */ -