ucx/buffer.c

changeset 1
1bcaac272cdf
child 5
88625853ae74
equal deleted inserted replaced
0:0f94d369bb02 1:1bcaac272cdf
1 #include "buffer.h"
2 #include <stdarg.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 UcxBuffer *ucx_buffer_new(void *space, size_t size, int flags) {
7 UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer));
8 if (buffer) {
9 buffer->flags = flags;
10 if (!space) {
11 buffer->space = malloc(size);
12 if (!buffer->space) {
13 free(buffer);
14 return NULL;
15 }
16 memset(buffer->space, 0, size);
17 buffer->flags |= UCX_BUFFER_AUTOFREE;
18 } else {
19 buffer->space = space;
20 }
21 buffer->capacity = size;
22 buffer->size = 0;
23
24 buffer->pos = 0;
25 }
26
27 return buffer;
28 }
29
30 void ucx_buffer_free(UcxBuffer *buffer) {
31 if ((buffer->flags & UCX_BUFFER_AUTOFREE) == UCX_BUFFER_AUTOFREE) {
32 free(buffer->space);
33 }
34 free(buffer);
35 }
36
37 UcxBuffer* ucx_buffer_extract(
38 UcxBuffer *src, size_t start, size_t length, int flags) {
39 if(src->size == 0) {
40 return NULL;
41 }
42 if (length == 0) {
43 length = src->size - start;
44 }
45 if (start+length > src->size) {
46 return NULL;
47 }
48
49 UcxBuffer *dst = (UcxBuffer*) malloc(sizeof(UcxBuffer));
50 if (dst) {
51 dst->space = malloc(length);
52 if (!dst->space) {
53 free(dst);
54 return NULL;
55 }
56 dst->capacity = length;
57 dst->size = length;
58 dst->flags = flags | UCX_BUFFER_AUTOFREE;
59 dst->pos = 0;
60 memcpy(dst->space, src->space+start, length);
61 }
62 return dst;
63 }
64
65 int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence) {
66 off_t npos;
67 switch (whence) {
68 case SEEK_SET:
69 npos = 0;
70 break;
71 case SEEK_CUR:
72 npos = buffer->pos;
73 break;
74 case SEEK_END:
75 npos = buffer->size;
76 break;
77 }
78
79 npos += offset;
80
81 if (npos < 0 || npos > buffer->size) {
82 return -1;
83 } else {
84 buffer->pos = npos;
85 return 0;
86 }
87
88 }
89
90 int ucx_buffer_eof(UcxBuffer *buffer) {
91 return buffer->pos >= buffer->size;
92 }
93
94 int ucx_buffer_extend(UcxBuffer *buffer, size_t len) {
95 size_t newcap = buffer->capacity;
96 while (buffer->pos + len > newcap) newcap <<= 1;
97
98 char *newspace = realloc(buffer->space, newcap);
99 if (newspace) {
100 memset(newspace+buffer->size, 0, newcap-buffer->size);
101 buffer->space = newspace;
102 buffer->capacity = newcap;
103 } else {
104 return -1;
105 }
106
107 return 0;
108 }
109
110 size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems,
111 UcxBuffer *buffer) {
112 size_t len = size * nitems;
113 if (buffer->pos + len > buffer->capacity) {
114 if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
115 if(ucx_buffer_extend(buffer, len)) {
116 return -1;
117 }
118 } else {
119 len = buffer->capacity - buffer->pos;
120 if (size > 1) len -= len%size;
121 }
122 }
123
124 if (len <= 0) {
125 return len;
126 }
127
128 memcpy(buffer->space + buffer->pos, ptr, len);
129 buffer->pos += len;
130 if(buffer->pos > buffer->size) {
131 buffer->size = buffer->pos;
132 }
133
134 return len / size;
135 }
136
137 size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
138 UcxBuffer *buffer) {
139 size_t len = size * nitems;
140 if (buffer->pos + len > buffer->size) {
141 len = buffer->size - buffer->pos;
142 if (size > 1) len -= len%size;
143 }
144
145 if (len <= 0) {
146 return len;
147 }
148
149 memcpy(ptr, buffer->space + buffer->pos, len);
150 buffer->pos += len;
151
152 return len / size;
153 }
154
155 int ucx_buffer_putc(UcxBuffer *buffer, int c) {
156 if(buffer->pos >= buffer->capacity) {
157 if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
158 if(ucx_buffer_extend(buffer, 1)) {
159 return EOF;
160 }
161 } else {
162 return EOF;
163 }
164 }
165
166 c &= 0xFF;
167 buffer->space[buffer->pos] = (char) c;
168 buffer->pos++;
169 if(buffer->pos > buffer->size) {
170 buffer->size = buffer->pos;
171 }
172 return c;
173 }
174
175 int ucx_buffer_getc(UcxBuffer *buffer) {
176 if (ucx_buffer_eof(buffer)) {
177 return EOF;
178 } else {
179 int c = buffer->space[buffer->pos];
180 buffer->pos++;
181 return c;
182 }
183 }
184
185 size_t ucx_buffer_generic_copy(void *s1, void *s2,
186 read_func readfnc, write_func writefnc, size_t bufsize) {
187 size_t ncp = 0;
188 char *buf = malloc(bufsize);
189 if(buf == NULL) {
190 return 0;
191 }
192
193 size_t r;
194 while((r = readfnc(buf, 1, bufsize, s1)) != 0) {
195 r = writefnc(buf, 1, r, s2);
196 ncp += r;
197 if(r == 0) {
198 break;
199 }
200 }
201
202 free(buf);
203 return ncp;
204 }

mercurial