added memstream to ucx - still little work to do

Tue, 09 Oct 2012 15:02:40 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 09 Oct 2012 15:02:40 +0200
changeset 56
76caac0da4a0
parent 55
180bc6b18fec
child 57
e18157c52985

added memstream to ucx - still little work to do

test/Makefile file | annotate | diff | comparison | revisions
test/main.c file | annotate | diff | comparison | revisions
test/memstream_tests.c file | annotate | diff | comparison | revisions
test/memstream_tests.h file | annotate | diff | comparison | revisions
ucx/Makefile file | annotate | diff | comparison | revisions
ucx/memstream.c file | annotate | diff | comparison | revisions
ucx/memstream.h file | annotate | diff | comparison | revisions
     1.1 --- a/test/Makefile	Tue Oct 09 10:21:18 2012 +0200
     1.2 +++ b/test/Makefile	Tue Oct 09 15:02:40 2012 +0200
     1.3 @@ -35,6 +35,7 @@
     1.4  SRC += map_tests.c
     1.5  SRC += string_tests.c
     1.6  SRC += logging_tests.c
     1.7 +SRC += memstream_tests.c
     1.8  
     1.9  OBJ = $(SRC:%.c=../build/%.$(OBJ_EXT))
    1.10  
     2.1 --- a/test/main.c	Tue Oct 09 10:21:18 2012 +0200
     2.2 +++ b/test/main.c	Tue Oct 09 15:02:40 2012 +0200
     2.3 @@ -39,6 +39,7 @@
     2.4  #include "string_tests.h"
     2.5  #include "mpool_tests.h"
     2.6  #include "map_tests.h"
     2.7 +#include "memstream_tests.h"
     2.8  
     2.9  int cmp_string(void* o1, void* o2, void* data) {
    2.10      return strcmp((char*)o1, (char*)o2);
    2.11 @@ -162,6 +163,15 @@
    2.12          ucx_test_register(suite, test_sstr_len_cat);
    2.13          ucx_test_register(suite, test_sstrsplit);
    2.14  
    2.15 +        /* UcxMemstream Tests */
    2.16 +        ucx_test_register(suite, test_ucx_memseektell);
    2.17 +        ucx_test_register(suite, test_ucx_memputc);
    2.18 +        ucx_test_register(suite, test_ucx_memgetc);
    2.19 +        ucx_test_register(suite, test_ucx_memwrite);
    2.20 +        ucx_test_register(suite, test_ucx_memread);
    2.21 +        ucx_test_register(suite, test_ucx_memprintf);
    2.22 +        ucx_test_register(suite, test_ucx_memscanf);
    2.23 +
    2.24          ucx_test_run(suite, stdout);
    2.25          fflush(stdout);
    2.26          ucx_test_suite_free(suite);
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/memstream_tests.c	Tue Oct 09 15:02:40 2012 +0200
     3.3 @@ -0,0 +1,231 @@
     3.4 +/*
     3.5 + *
     3.6 + */
     3.7 +
     3.8 +#include "memstream_tests.h"
     3.9 +
    3.10 +UCX_TEST_IMPLEMENT(test_ucx_memseektell) {
    3.11 +    char *buffer = malloc(16);
    3.12 +    memset(buffer, 32, 7);
    3.13 +    buffer[7] = 0;
    3.14 +
    3.15 +    UcxMemstream *m = ucx_memopen(buffer, 16);
    3.16 +    int r;
    3.17 +
    3.18 +    UCX_TEST_BEGIN
    3.19 +
    3.20 +    r = ucx_memseek(m, 5, SEEK_SET);
    3.21 +    UCX_TEST_ASSERT(r == 0, "seek SET+5 failed");
    3.22 +    UCX_TEST_ASSERT(ucx_memtell(m) == 5, "seek SET+5 set wrong position");
    3.23 +
    3.24 +    r = ucx_memseek(m, 20, SEEK_SET);
    3.25 +    UCX_TEST_ASSERT(r != 0, "seek beyond bounds shall fail");
    3.26 +    UCX_TEST_ASSERT(ucx_memtell(m) == 5,
    3.27 +            "failed seek shall leave pos unchanged");
    3.28 +
    3.29 +    r = ucx_memseek(m, 5, SEEK_CUR);
    3.30 +    UCX_TEST_ASSERT(r == 0, "seek CUR+5 failed");
    3.31 +    UCX_TEST_ASSERT(ucx_memtell(m) == 10, "seek CUR+5 set wrong position");
    3.32 +
    3.33 +    r = ucx_memseek(m, 10, SEEK_CUR);
    3.34 +    UCX_TEST_ASSERT(r != 0, "seek CUR beyond bounds shall fail");
    3.35 +    UCX_TEST_ASSERT(ucx_memtell(m) == 10,
    3.36 +            "failed seek shall leave pos unchanged");
    3.37 +
    3.38 +    r = ucx_memseek(m, -5, SEEK_END);
    3.39 +    UCX_TEST_ASSERT(r == 0, "seek END-5 failed");
    3.40 +    UCX_TEST_ASSERT(ucx_memtell(m) == 2, "seek END-5 set wrong position");
    3.41 +
    3.42 +    r = ucx_memseek(m, -10, SEEK_END);
    3.43 +    UCX_TEST_ASSERT(r != 0, "seek END beyond bounds shall fail");
    3.44 +    UCX_TEST_ASSERT(ucx_memtell(m) == 2,
    3.45 +            "failed seek shall leave pos unchanged");
    3.46 +
    3.47 +    UCX_TEST_END
    3.48 +
    3.49 +    ucx_memclose(m);
    3.50 +    free(buffer);
    3.51 +}
    3.52 +
    3.53 +UCX_TEST_IMPLEMENT(test_ucx_memputc) {
    3.54 +    char *buffer = malloc(16);
    3.55 +    memset(buffer, 32, 16);
    3.56 +
    3.57 +    UcxMemstream *m = ucx_memopen(buffer, 16);
    3.58 +    int r;
    3.59 +
    3.60 +    UCX_TEST_BEGIN
    3.61 +
    3.62 +    ucx_memputc(m, 48); ucx_memputc(m, 48); ucx_memputc(m, 48);
    3.63 +    UCX_TEST_ASSERT(ucx_memtell(m) == 3, "pos wrong after first 3 puts");
    3.64 +    ucx_memseek(m, 10, SEEK_CUR);
    3.65 +    ucx_memputc(m, 48); ucx_memputc(m, 48); ucx_memputc(m, 48);
    3.66 +    UCX_TEST_ASSERT(ucx_memtell(m) == 16, "pos wrong after last 3 puts");
    3.67 +    UCX_TEST_ASSERT(ucx_memeof(m), "eof not set");
    3.68 +    UCX_TEST_ASSERT(!ucx_memoverflow(m), "overflow shall not be set");
    3.69 +    UCX_TEST_ASSERT(ucx_memputc(m, 48) == EOF, "put shall return EOF on memof");
    3.70 +    UCX_TEST_ASSERT(memcmp(buffer, "000          000", 16) == 0,
    3.71 +            "buffer contains incorrect content");
    3.72 +
    3.73 +    UCX_TEST_END
    3.74 +
    3.75 +    ucx_memclose(m);
    3.76 +    free(buffer);
    3.77 +}
    3.78 +
    3.79 +UCX_TEST_IMPLEMENT(test_ucx_memgetc) {
    3.80 +    char *buffer = malloc(16);
    3.81 +    memset(buffer, 32, 8);
    3.82 +    for (int i = 8; i < 16 ; i++) {
    3.83 +        buffer[i] = 40+i;
    3.84 +    }
    3.85 +
    3.86 +    UcxMemstream *m = ucx_memopen(buffer, 16);
    3.87 +    int r;
    3.88 +
    3.89 +    UCX_TEST_BEGIN
    3.90 +
    3.91 +    char rb[16];
    3.92 +    for (int i = 0 ; i < 16 ; i++) {
    3.93 +        UCX_TEST_ASSERT(ucx_memtell(m) == i, "pos wrong during read loop");
    3.94 +        UCX_TEST_ASSERT(!ucx_memeof(m),
    3.95 +                "EOF shall not be set during read loop");
    3.96 +        rb[i] = ucx_memgetc(m);
    3.97 +    }
    3.98 +    UCX_TEST_ASSERT(ucx_memtell(m) == 16, "pos wrong after read loop");
    3.99 +    UCX_TEST_ASSERT(ucx_memeof(m), "EOF not set");
   3.100 +    UCX_TEST_ASSERT(memcmp(rb, "        01234567", 16) == 0,
   3.101 +            "read data incorrect");
   3.102 +
   3.103 +    UCX_TEST_END
   3.104 +
   3.105 +    ucx_memclose(m);
   3.106 +    free(buffer);
   3.107 +}
   3.108 +
   3.109 +UCX_TEST_IMPLEMENT(test_ucx_memwrite) {
   3.110 +    char *buffer = malloc(16);
   3.111 +    memset(buffer, 32, 8);
   3.112 +    for (int i = 8; i < 16 ; i++) {
   3.113 +        buffer[i] = 40+i;
   3.114 +    }
   3.115 +
   3.116 +    UcxMemstream *m = ucx_memopen(buffer, 16);
   3.117 +    int r;
   3.118 +
   3.119 +    UCX_TEST_BEGIN
   3.120 +
   3.121 +    char* teststring = "this is way too much";
   3.122 +    r = ucx_memwrite(teststring, 1, 20, m);
   3.123 +    UCX_TEST_ASSERT(r == 16, "string not correctly trimed");
   3.124 +    UCX_TEST_ASSERT(memcmp(buffer, teststring, 16) == 0,
   3.125 +            "buffer data incorrect");
   3.126 +    UCX_TEST_ASSERT(ucx_memeof(m), "eof shall be set");
   3.127 +    UCX_TEST_ASSERT(!ucx_memoverflow(m), "no overflow shall be caused");
   3.128 +
   3.129 +    ucx_memseek(m, 8, SEEK_SET);
   3.130 +    r = ucx_memwrite("not", 1, 3, m);
   3.131 +    UCX_TEST_ASSERT(r == 3, "three bytes should be replace");
   3.132 +    UCX_TEST_ASSERT(memcmp(buffer, "this is not too much", 16) == 0,
   3.133 +            "modified buffer is incorrect");
   3.134 +
   3.135 +    char* threebytestring = "  t  h  r  e  e   ";
   3.136 +    memset(buffer, 49, 16);
   3.137 +    ucx_memseek(m, 0, SEEK_SET);
   3.138 +    r = ucx_memwrite(threebytestring, 3, 6, m);
   3.139 +    UCX_TEST_ASSERT(r == 15, "three byte string not correctly trimed");
   3.140 +    UCX_TEST_ASSERT(ucx_memtell(m) == 15,
   3.141 +            "position after write of three byte string incorrect");
   3.142 +    UCX_TEST_ASSERT(!ucx_memeof(m), "eof shall not be set");
   3.143 +    UCX_TEST_ASSERT(memcmp(buffer, "  t  h  r  e  e1", 16) == 0,
   3.144 +                "bufer is incorrect after three byte string has been written");
   3.145 +
   3.146 +    UCX_TEST_END
   3.147 +
   3.148 +    ucx_memclose(m);
   3.149 +    free(buffer);
   3.150 +}
   3.151 +
   3.152 +UCX_TEST_IMPLEMENT(test_ucx_memread) {
   3.153 +    char *buffer = malloc(16);
   3.154 +    memset(buffer, 56, 8);
   3.155 +    for (int i = 8; i < 16 ; i++) {
   3.156 +        buffer[i] = 40+i;
   3.157 +    }
   3.158 +
   3.159 +    UcxMemstream *m = ucx_memopen(buffer, 16);
   3.160 +    int r;
   3.161 +
   3.162 +    UCX_TEST_BEGIN
   3.163 +
   3.164 +    char rb[16];
   3.165 +    memset(rb, 32, 16);
   3.166 +
   3.167 +    ucx_memseek(m, 8, SEEK_SET);
   3.168 +    r = ucx_memread(rb, 1, 16, m);
   3.169 +    UCX_TEST_ASSERT(r == 8, "read did not stop at buffer end");
   3.170 +    UCX_TEST_ASSERT(memcmp(rb, "01234567        ", 16) == 0,
   3.171 +            "buffer incorrect after first read");
   3.172 +    UCX_TEST_ASSERT(ucx_memeof(m), "eof shall be set");
   3.173 +
   3.174 +    ucx_memseek(m, 0, SEEK_SET);
   3.175 +    r = ucx_memread(rb+8, 1, 8, m);
   3.176 +    UCX_TEST_ASSERT(r == 8, "read did not read the specified amount of bytes");
   3.177 +    UCX_TEST_ASSERT(memcmp(rb, "0123456788888888", 16) == 0,
   3.178 +                "buffer incorrect after second read");
   3.179 +
   3.180 +    ucx_memseek(m, 0, SEEK_SET);
   3.181 +    r = ucx_memread(rb, 3, 6, m);
   3.182 +    UCX_TEST_ASSERT(r == 15,
   3.183 +            "three byte read did not read the desired amount of bytes");
   3.184 +    UCX_TEST_ASSERT(memcmp(rb, "8888888801234568", 16) == 0,
   3.185 +                    "buffer incorrect after three byte read");
   3.186 +
   3.187 +    UCX_TEST_END
   3.188 +
   3.189 +    ucx_memclose(m);
   3.190 +    free(buffer);
   3.191 +}
   3.192 +
   3.193 +UCX_TEST_IMPLEMENT(test_ucx_memprintf) {
   3.194 +    char *buffer = malloc(32);
   3.195 +    UcxMemstream *m = ucx_memopen(buffer, 16);
   3.196 +
   3.197 +    UCX_TEST_BEGIN
   3.198 +    int r = ucx_memprintf(m, "number: %d char: %c", 15, '6');
   3.199 +    UCX_TEST_ASSERT(r == 18, "incorrect number of bytes written");
   3.200 +    UCX_TEST_ASSERT(ucx_memoverflow(m), "overflow shall be detected");
   3.201 +    UCX_TEST_ASSERT(memcmp(buffer, "number: 15 char:", 16) == 0,
   3.202 +            "incorrect buffer content");
   3.203 +
   3.204 +    ucx_memseek(m, 0, SEEK_SET);
   3.205 +    ucx_memprintf(m, "a: %d - b: %d", 1, 2);
   3.206 +    UCX_TEST_ASSERT(!ucx_memoverflow(m), "no overflow shall be deteceted");
   3.207 +    UCX_TEST_ASSERT(memcmp(buffer, "a: 1 - b: 2char:", 16),
   3.208 +            "incorrect modified buffer content");
   3.209 +    UCX_TEST_ASSERT(ucx_memtell(m) == 11, "incorrect position");
   3.210 +
   3.211 +    UCX_TEST_END
   3.212 +
   3.213 +    ucx_memclose(m);
   3.214 +    free(buffer);
   3.215 +}
   3.216 +
   3.217 +UCX_TEST_IMPLEMENT(test_ucx_memscanf) {
   3.218 +    char *buffer = "string 3.5 1 stuff";
   3.219 +    UcxMemstream *m = ucx_memopen(buffer, 16);
   3.220 +
   3.221 +    char s[6];
   3.222 +    float f;
   3.223 +    int d;
   3.224 +    UCX_TEST_BEGIN
   3.225 +    int r = ucx_memscanf(m, "%s %f %d", s, &f, &d);
   3.226 +    UCX_TEST_ASSERT(r == 3, "3 arguments shall be read");
   3.227 +    UCX_TEST_ASSERT(strncmp(s, "string", 6) == 0, "incorrect string");
   3.228 +    UCX_TEST_ASSERT(f == 3.5, "incorrect float");
   3.229 +    UCX_TEST_ASSERT(d == 1, "incorrect integer");
   3.230 +    UCX_TEST_ASSERT(ucx_memtell(m) == 12, "incorrect position");
   3.231 +    UCX_TEST_END
   3.232 +
   3.233 +    ucx_memclose(m);
   3.234 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/memstream_tests.h	Tue Oct 09 15:02:40 2012 +0200
     4.3 @@ -0,0 +1,30 @@
     4.4 +/* 
     4.5 + *
     4.6 + */
     4.7 +
     4.8 +#ifndef MEMSTREAM_TEST_H
     4.9 +#define	MEMSTREAM_TEST_H
    4.10 +
    4.11 +#include "ucx/test.h"
    4.12 +#include "ucx/memstream.h"
    4.13 +
    4.14 +#ifdef	__cplusplus
    4.15 +extern "C" {
    4.16 +#endif
    4.17 +
    4.18 +/* assume open and close to be correct */
    4.19 +
    4.20 +UCX_TEST_DECLARE(test_ucx_memseektell)
    4.21 +UCX_TEST_DECLARE(test_ucx_memputc)
    4.22 +UCX_TEST_DECLARE(test_ucx_memgetc)
    4.23 +UCX_TEST_DECLARE(test_ucx_memwrite)
    4.24 +UCX_TEST_DECLARE(test_ucx_memread)
    4.25 +UCX_TEST_DECLARE(test_ucx_memprintf)
    4.26 +UCX_TEST_DECLARE(test_ucx_memscanf)
    4.27 +
    4.28 +#ifdef	__cplusplus
    4.29 +}
    4.30 +#endif
    4.31 +
    4.32 +#endif	/* MEMSTREAM_TEST_H */
    4.33 +
     5.1 --- a/ucx/Makefile	Tue Oct 09 10:21:18 2012 +0200
     5.2 +++ b/ucx/Makefile	Tue Oct 09 15:02:40 2012 +0200
     5.3 @@ -37,6 +37,7 @@
     5.4  SRC += test.c
     5.5  SRC += allocator.c
     5.6  SRC += logging.c
     5.7 +SRC += memstream.c
     5.8  
     5.9  OBJ = $(SRC:%.c=../build/%.$(OBJ_EXT))
    5.10  
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/ucx/memstream.c	Tue Oct 09 15:02:40 2012 +0200
     6.3 @@ -0,0 +1,152 @@
     6.4 +#include "memstream.h"
     6.5 +#include <stdarg.h>
     6.6 +#include <stdlib.h>
     6.7 +#include <string.h>
     6.8 +
     6.9 +struct _UcxMemstream {
    6.10 +    void *space;
    6.11 +    size_t pos;
    6.12 +    size_t length;
    6.13 +    _Bool autofree;
    6.14 +};
    6.15 +
    6.16 +UcxMemstream *ucx_memopen(void* space, size_t length) {
    6.17 +    UcxMemstream *stream = (UcxMemstream*) malloc(sizeof(UcxMemstream));
    6.18 +    if (stream) {
    6.19 +        if (!space) {
    6.20 +            stream->space = malloc(length);
    6.21 +            if (!stream->space) {
    6.22 +                free(stream);
    6.23 +                return NULL;
    6.24 +            }
    6.25 +            memset(stream->space, 0, length);
    6.26 +            stream->autofree = 1;
    6.27 +        } else {
    6.28 +            stream->space = space;
    6.29 +            stream->autofree = 0;
    6.30 +        }
    6.31 +        stream->length = length;
    6.32 +
    6.33 +        stream->pos = 0;
    6.34 +    }
    6.35 +
    6.36 +    return stream;
    6.37 +}
    6.38 +
    6.39 +void ucx_memclose(UcxMemstream *stream) {
    6.40 +    if (stream->autofree) {
    6.41 +        free(stream->space);
    6.42 +    }
    6.43 +    free(stream);
    6.44 +}
    6.45 +
    6.46 +int ucx_memseek(UcxMemstream *stream, long offset, int whence) {
    6.47 +    size_t npos;
    6.48 +    switch (whence) {
    6.49 +    case SEEK_SET:
    6.50 +        npos = 0;
    6.51 +        break;
    6.52 +    case SEEK_CUR:
    6.53 +        npos = stream->pos;
    6.54 +        break;
    6.55 +    case SEEK_END:
    6.56 +        npos = strlen(stream->space);
    6.57 +        break;
    6.58 +    }
    6.59 +
    6.60 +    npos += offset;
    6.61 +
    6.62 +    if (npos < 0 || npos > stream->length) {
    6.63 +        return -1;
    6.64 +    } else {
    6.65 +        stream->pos = npos;
    6.66 +        return 0;
    6.67 +    }
    6.68 +
    6.69 +}
    6.70 +
    6.71 +int ucx_memeof(UcxMemstream *stream) {
    6.72 +    return stream->pos >= stream->length;
    6.73 +}
    6.74 +
    6.75 +int ucx_memoverflow(UcxMemstream *stream) {
    6.76 +    return stream->pos > stream->length;
    6.77 +}
    6.78 +
    6.79 +size_t ucx_memtell(UcxMemstream *stream) {
    6.80 +    return stream->pos;
    6.81 +}
    6.82 +
    6.83 +size_t ucx_memio(void* d, size_t s, size_t n, UcxMemstream *m, _Bool read) {
    6.84 +    size_t len;
    6.85 +    if (m->pos + s*n > m->length) {
    6.86 +        if (ucx_memoverflow(m)) {
    6.87 +            len = 0;
    6.88 +        } else {
    6.89 +            len = m->length - m->pos;
    6.90 +            if (s > 1) len -= len%s;
    6.91 +        }
    6.92 +    } else {
    6.93 +        len = s*n;
    6.94 +    }
    6.95 +
    6.96 +    if (len == 0) {
    6.97 +        return 0;
    6.98 +    }
    6.99 +
   6.100 +    if (read) {
   6.101 +        memcpy(d, m->space+m->pos, len);
   6.102 +    } else {
   6.103 +        memcpy(m->space+m->pos, d, len);
   6.104 +    }
   6.105 +    m->pos += len;
   6.106 +
   6.107 +    return len;
   6.108 +}
   6.109 +
   6.110 +int ucx_memputc(UcxMemstream *stream, int c) {
   6.111 +    if (ucx_memeof(stream)) {
   6.112 +        return EOF;
   6.113 +    } else {
   6.114 +        c &= 0xFF;
   6.115 +        ((char*)(stream->space))[stream->pos] = (char) c;
   6.116 +        stream->pos++;
   6.117 +        return c;
   6.118 +    }
   6.119 +}
   6.120 +
   6.121 +int ucx_memgetc(UcxMemstream *stream) {
   6.122 +    if (ucx_memeof(stream)) {
   6.123 +        return EOF;
   6.124 +    } else {
   6.125 +        int c = ((char*)(stream->space))[stream->pos];
   6.126 +        stream->pos++;
   6.127 +        return c;
   6.128 +    }
   6.129 +}
   6.130 +
   6.131 +int ucx_memprintf(UcxMemstream *stream, const char* format, ...) {
   6.132 +    va_list v;
   6.133 +    va_start(v, format);
   6.134 +    int r = vsprintf(stream->space+stream->pos, format, v);
   6.135 +    va_end(v);
   6.136 +
   6.137 +    stream->pos += r;
   6.138 +
   6.139 +    return r;
   6.140 +}
   6.141 +
   6.142 +int ucx_memscanf(UcxMemstream *stream, const char* format, ...) {
   6.143 +
   6.144 +    /* TODO: vsscanf returns the number of fields read,
   6.145 +     * we need the number of bytes */
   6.146 +
   6.147 +    va_list v;
   6.148 +    va_start(v, format);
   6.149 +    int r = vsscanf(stream->space+stream->pos, format, v);
   6.150 +    va_end(v);
   6.151 +
   6.152 +    stream->pos += r;
   6.153 +
   6.154 +    return r;
   6.155 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/ucx/memstream.h	Tue Oct 09 15:02:40 2012 +0200
     7.3 @@ -0,0 +1,70 @@
     7.4 +#ifndef MEMSTREAM_H
     7.5 +#define	MEMSTREAM_H
     7.6 +
     7.7 +#include <stdio.h>
     7.8 +
     7.9 +/* as fmemopen is a C extension we provide our cross plattform stuff here */
    7.10 +
    7.11 +#ifdef	__cplusplus
    7.12 +extern "C" {
    7.13 +#endif
    7.14 +
    7.15 +
    7.16 +/* as FILE is opaque, we don't do evil hacks but provide an alternative */
    7.17 +struct _UcxMemstream; /* cauz we are mad about it, we make it opaque, too */
    7.18 +typedef struct _UcxMemstream UcxMemstream;
    7.19 +
    7.20 +UcxMemstream *ucx_memopen(void *space, size_t length);
    7.21 +void ucx_memclose(UcxMemstream* stream);
    7.22 +
    7.23 +/*
    7.24 + * Moves the position of the stream to a new position relative to whence.
    7.25 + *
    7.26 + * SEEK_SET marks the start of the buffer
    7.27 + * SEEK_CUR marks the current position
    7.28 + * SEEK_END marks the first 0-byte in the buffer
    7.29 + *
    7.30 + * ucx_memseek returns 0 on success and -1 if the new position is beyond the
    7.31 + * bounds of the allocated buffer. In that case the position of the stream
    7.32 + * remains unchanged.
    7.33 + *
    7.34 + */
    7.35 +int ucx_memseek(UcxMemstream *stream, long offset, int whence);
    7.36 +size_t ucx_memtell(UcxMemstream *stream);
    7.37 +
    7.38 +/*
    7.39 + * returns non-zero, iff the current stream position has exceeded the last
    7.40 + * available byte of the underlying buffer
    7.41 + *
    7.42 + */
    7.43 +int ucx_memeof(UcxMemstream *stream);
    7.44 +/*
    7.45 + * returns non-zero, iff the current stream position has exceeded the length
    7.46 + * of the underlying buffer
    7.47 + *
    7.48 + * in contrast to ucx_memeof this function will return zero, if the current
    7.49 + * position exactly matches the buffer length
    7.50 + *
    7.51 + * this function should be called after any ucx_memprintf/ucx_memscanf call
    7.52 + */
    7.53 +int ucx_memoverflow(UcxMemstream *stream);
    7.54 +
    7.55 +/* memwrite, memread, memputc and memreadc shall not generate overflows */
    7.56 +size_t ucx_memio(void *d, size_t s, size_t n, UcxMemstream* m, _Bool read);
    7.57 +#define ucx_memwrite(data, itemsize, nitems, memstream) \
    7.58 +    ucx_memio(data, itemsize, nitems, memstream, 0)
    7.59 +#define ucx_memread(data, itemsize, nitems, memstream) \
    7.60 +        ucx_memio(data, itemsize, nitems, memstream, 1)
    7.61 +int ucx_memputc(UcxMemstream *stream, int c);
    7.62 +int ucx_memgetc(UcxMemstream *stream);
    7.63 +
    7.64 +/* printf / scanf may generate overflows */
    7.65 +int ucx_memprintf(UcxMemstream *stream, const char* format, ...);
    7.66 +int ucx_memscanf(UcxMemstream *stream, const char* format, ...);
    7.67 +
    7.68 +#ifdef	__cplusplus
    7.69 +}
    7.70 +#endif
    7.71 +
    7.72 +#endif	/* MEMSTREAM_H */
    7.73 +

mercurial