ucx/memstream.c

changeset 60
abae4669fba7
parent 58
733f22fca61a
equal deleted inserted replaced
59:c80c910fe191 60:abae4669fba7
1 #include "memstream.h"
2 #include <stdarg.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 struct UcxMemstream {
7 void *space;
8 off_t pos;
9 size_t length;
10 _Bool autofree;
11 };
12
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;
29
30 stream->pos = 0;
31 }
32
33 return stream;
34 }
35
36 void ucx_memclose(UcxMemstream *stream) {
37 if (stream->autofree) {
38 free(stream->space);
39 }
40 free(stream);
41 }
42
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 }
56
57 npos += offset;
58
59 if (npos < 0 || npos > stream->length) {
60 return -1;
61 } else {
62 stream->pos = npos;
63 return 0;
64 }
65
66 }
67
68 int ucx_memeof(UcxMemstream *stream) {
69 return stream->pos >= stream->length;
70 }
71
72 size_t ucx_memtell(UcxMemstream *stream) {
73 return stream->pos;
74 }
75
76 size_t ucx_memio(void* d, size_t s, size_t n, UcxMemstream *m, _Bool read) {
77 size_t len;
78 if (m->pos + s*n > m->length) {
79 len = m->length - m->pos;
80 if (s > 1) len -= len%s;
81 } else {
82 len = s*n;
83 }
84
85 if (len == 0) {
86 return 0;
87 }
88
89 if (read) {
90 memcpy(d, (char*)m->space+m->pos, len);
91 } else {
92 memcpy((char*)m->space+m->pos, d, len);
93 }
94 m->pos += len;
95
96 return len;
97 }
98
99 int ucx_memputc(UcxMemstream *stream, int c) {
100 if (ucx_memeof(stream)) {
101 return EOF;
102 } else {
103 c &= 0xFF;
104 ((char*)(stream->space))[stream->pos] = (char) c;
105 stream->pos++;
106 return c;
107 }
108 }
109
110 int ucx_memgetc(UcxMemstream *stream) {
111 if (ucx_memeof(stream)) {
112 return EOF;
113 } else {
114 int c = ((char*)(stream->space))[stream->pos];
115 stream->pos++;
116 return c;
117 }
118 }

mercurial