Tue, 09 Oct 2012 16:46:29 +0200
some fixes
1 #include "memstream.h"
2 #include <stdarg.h>
3 #include <stdlib.h>
4 #include <string.h>
6 struct UcxMemstream {
7 void *space;
8 off_t pos;
9 size_t length;
10 _Bool autofree;
11 };
13 UcxMemstream *ucx_memopen(void *space, size_t length) {
14 UcxMemstream *stream = (UcxMemstream*) malloc(sizeof(UcxMemstream));
15 if (stream) {
16 if (!space) {
17 stream->space = malloc(length);
18 if (!stream->space) {
19 free(stream);
20 return NULL;
21 }
22 memset(stream->space, 0, length);
23 stream->autofree = 1;
24 } else {
25 stream->space = space;
26 stream->autofree = 0;
27 }
28 stream->length = length;
30 stream->pos = 0;
31 }
33 return stream;
34 }
36 void ucx_memclose(UcxMemstream *stream) {
37 if (stream->autofree) {
38 free(stream->space);
39 }
40 free(stream);
41 }
43 int ucx_memseek(UcxMemstream *stream, off_t offset, int whence) {
44 off_t npos;
45 switch (whence) {
46 case SEEK_SET:
47 npos = 0;
48 break;
49 case SEEK_CUR:
50 npos = stream->pos;
51 break;
52 case SEEK_END:
53 npos = strlen(stream->space);
54 break;
55 }
57 npos += offset;
59 if (npos < 0 || npos > stream->length) {
60 return -1;
61 } else {
62 stream->pos = npos;
63 return 0;
64 }
66 }
68 int ucx_memeof(UcxMemstream *stream) {
69 return stream->pos >= stream->length;
70 }
72 int ucx_memoverflow(UcxMemstream *stream) {
73 return stream->pos > stream->length;
74 }
76 size_t ucx_memtell(UcxMemstream *stream) {
77 return stream->pos;
78 }
80 size_t ucx_memio(void* d, size_t s, size_t n, UcxMemstream *m, _Bool read) {
81 size_t len;
82 if (m->pos + s*n > m->length) {
83 if (ucx_memoverflow(m)) {
84 len = 0;
85 } else {
86 len = m->length - m->pos;
87 if (s > 1) len -= len%s;
88 }
89 } else {
90 len = s*n;
91 }
93 if (len == 0) {
94 return 0;
95 }
97 if (read) {
98 memcpy(d, (char*)m->space+m->pos, len);
99 } else {
100 memcpy((char*)m->space+m->pos, d, len);
101 }
102 m->pos += len;
104 return len;
105 }
107 int ucx_memputc(UcxMemstream *stream, int c) {
108 if (ucx_memeof(stream)) {
109 return EOF;
110 } else {
111 c &= 0xFF;
112 ((char*)(stream->space))[stream->pos] = (char) c;
113 stream->pos++;
114 return c;
115 }
116 }
118 int ucx_memgetc(UcxMemstream *stream) {
119 if (ucx_memeof(stream)) {
120 return EOF;
121 } else {
122 int c = ((char*)(stream->space))[stream->pos];
123 stream->pos++;
124 return c;
125 }
126 }
128 int ucx_memprintf(UcxMemstream *stream, const char* format, ...) {
129 va_list v;
130 va_start(v, format);
131 int r = vsprintf((char*)stream->space+stream->pos, format, v);
132 va_end(v);
134 stream->pos += r;
136 return r;
137 }
139 int ucx_memscanf(UcxMemstream *stream, const char* format, ...) {
141 /* TODO: vsscanf returns the number of fields read,
142 * we need the number of bytes */
144 va_list v;
145 va_start(v, format);
146 int r = vsscanf((char*)stream->space+stream->pos, format, v);
147 va_end(v);
149 stream->pos += r;
151 return r;
152 }