1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ucx/memstream.c Tue Oct 09 15:02:40 2012 +0200 1.3 @@ -0,0 +1,152 @@ 1.4 +#include "memstream.h" 1.5 +#include <stdarg.h> 1.6 +#include <stdlib.h> 1.7 +#include <string.h> 1.8 + 1.9 +struct _UcxMemstream { 1.10 + void *space; 1.11 + size_t pos; 1.12 + size_t length; 1.13 + _Bool autofree; 1.14 +}; 1.15 + 1.16 +UcxMemstream *ucx_memopen(void* space, size_t length) { 1.17 + UcxMemstream *stream = (UcxMemstream*) malloc(sizeof(UcxMemstream)); 1.18 + if (stream) { 1.19 + if (!space) { 1.20 + stream->space = malloc(length); 1.21 + if (!stream->space) { 1.22 + free(stream); 1.23 + return NULL; 1.24 + } 1.25 + memset(stream->space, 0, length); 1.26 + stream->autofree = 1; 1.27 + } else { 1.28 + stream->space = space; 1.29 + stream->autofree = 0; 1.30 + } 1.31 + stream->length = length; 1.32 + 1.33 + stream->pos = 0; 1.34 + } 1.35 + 1.36 + return stream; 1.37 +} 1.38 + 1.39 +void ucx_memclose(UcxMemstream *stream) { 1.40 + if (stream->autofree) { 1.41 + free(stream->space); 1.42 + } 1.43 + free(stream); 1.44 +} 1.45 + 1.46 +int ucx_memseek(UcxMemstream *stream, long offset, int whence) { 1.47 + size_t npos; 1.48 + switch (whence) { 1.49 + case SEEK_SET: 1.50 + npos = 0; 1.51 + break; 1.52 + case SEEK_CUR: 1.53 + npos = stream->pos; 1.54 + break; 1.55 + case SEEK_END: 1.56 + npos = strlen(stream->space); 1.57 + break; 1.58 + } 1.59 + 1.60 + npos += offset; 1.61 + 1.62 + if (npos < 0 || npos > stream->length) { 1.63 + return -1; 1.64 + } else { 1.65 + stream->pos = npos; 1.66 + return 0; 1.67 + } 1.68 + 1.69 +} 1.70 + 1.71 +int ucx_memeof(UcxMemstream *stream) { 1.72 + return stream->pos >= stream->length; 1.73 +} 1.74 + 1.75 +int ucx_memoverflow(UcxMemstream *stream) { 1.76 + return stream->pos > stream->length; 1.77 +} 1.78 + 1.79 +size_t ucx_memtell(UcxMemstream *stream) { 1.80 + return stream->pos; 1.81 +} 1.82 + 1.83 +size_t ucx_memio(void* d, size_t s, size_t n, UcxMemstream *m, _Bool read) { 1.84 + size_t len; 1.85 + if (m->pos + s*n > m->length) { 1.86 + if (ucx_memoverflow(m)) { 1.87 + len = 0; 1.88 + } else { 1.89 + len = m->length - m->pos; 1.90 + if (s > 1) len -= len%s; 1.91 + } 1.92 + } else { 1.93 + len = s*n; 1.94 + } 1.95 + 1.96 + if (len == 0) { 1.97 + return 0; 1.98 + } 1.99 + 1.100 + if (read) { 1.101 + memcpy(d, m->space+m->pos, len); 1.102 + } else { 1.103 + memcpy(m->space+m->pos, d, len); 1.104 + } 1.105 + m->pos += len; 1.106 + 1.107 + return len; 1.108 +} 1.109 + 1.110 +int ucx_memputc(UcxMemstream *stream, int c) { 1.111 + if (ucx_memeof(stream)) { 1.112 + return EOF; 1.113 + } else { 1.114 + c &= 0xFF; 1.115 + ((char*)(stream->space))[stream->pos] = (char) c; 1.116 + stream->pos++; 1.117 + return c; 1.118 + } 1.119 +} 1.120 + 1.121 +int ucx_memgetc(UcxMemstream *stream) { 1.122 + if (ucx_memeof(stream)) { 1.123 + return EOF; 1.124 + } else { 1.125 + int c = ((char*)(stream->space))[stream->pos]; 1.126 + stream->pos++; 1.127 + return c; 1.128 + } 1.129 +} 1.130 + 1.131 +int ucx_memprintf(UcxMemstream *stream, const char* format, ...) { 1.132 + va_list v; 1.133 + va_start(v, format); 1.134 + int r = vsprintf(stream->space+stream->pos, format, v); 1.135 + va_end(v); 1.136 + 1.137 + stream->pos += r; 1.138 + 1.139 + return r; 1.140 +} 1.141 + 1.142 +int ucx_memscanf(UcxMemstream *stream, const char* format, ...) { 1.143 + 1.144 + /* TODO: vsscanf returns the number of fields read, 1.145 + * we need the number of bytes */ 1.146 + 1.147 + va_list v; 1.148 + va_start(v, format); 1.149 + int r = vsscanf(stream->space+stream->pos, format, v); 1.150 + va_end(v); 1.151 + 1.152 + stream->pos += r; 1.153 + 1.154 + return r; 1.155 +}