Tue, 09 Oct 2012 15:02:40 +0200
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 +