ucx/buffer.c

changeset 76
655020a30e77
parent 69
fb59270b1de3
child 78
af355652f271
equal deleted inserted replaced
75:990734f548ef 76:655020a30e77
1 #include "buffer.h" 1 #include "buffer.h"
2 #include <stdarg.h> 2 #include <stdarg.h>
3 #include <stdlib.h> 3 #include <stdlib.h>
4 #include <string.h> 4 #include <string.h>
5 5
6 UcxBuffer *ucx_buffer_new(void *space, size_t length, int flags) { 6 UcxBuffer *ucx_buffer_new(void *space, size_t size, int flags) {
7 UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer)); 7 UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer));
8 if (buffer) { 8 if (buffer) {
9 buffer->flags = flags; 9 buffer->flags = flags;
10 if (!space) { 10 if (!space) {
11 buffer->space = malloc(length); 11 buffer->space = malloc(size);
12 if (!buffer->space) { 12 if (!buffer->space) {
13 free(buffer); 13 free(buffer);
14 return NULL; 14 return NULL;
15 } 15 }
16 memset(buffer->space, 0, length); 16 memset(buffer->space, 0, size);
17 buffer->flags |= UCX_BUFFER_AUTOFREE; 17 buffer->flags |= UCX_BUFFER_AUTOFREE;
18 } else { 18 } else {
19 buffer->space = space; 19 buffer->space = space;
20 } 20 }
21 buffer->size = length; 21 buffer->capacity = size;
22 buffer->size = 0;
22 23
23 buffer->pos = 0; 24 buffer->pos = 0;
24 } 25 }
25 26
26 return buffer; 27 return buffer;
31 free(buffer->space); 32 free(buffer->space);
32 } 33 }
33 free(buffer); 34 free(buffer);
34 } 35 }
35 36
36 UcxBuffer *restrict ucx_buffer_extract( 37 UcxBuffer* ucx_buffer_extract(
37 UcxBuffer *restrict src, size_t start, size_t length, int flags) { 38 UcxBuffer *src, size_t start, size_t length, int flags) {
39 if(src->size == 0) {
40 return NULL;
41 }
38 if (length == 0) { 42 if (length == 0) {
39 length = src->size - start; 43 length = src->size - start;
40 } 44 }
41 if (start+length > src->size) { 45 if (start+length > src->size) {
42 return NULL; 46 return NULL;
43 } 47 }
44 48
45 UcxBuffer *restrict dst = (UcxBuffer*) malloc(sizeof(UcxBuffer)); 49 UcxBuffer *dst = (UcxBuffer*) malloc(sizeof(UcxBuffer));
46 if (dst) { 50 if (dst) {
47 dst->space = malloc(length); 51 dst->space = malloc(length);
48 if (!dst->space) { 52 if (!dst->space) {
49 free(dst); 53 free(dst);
50 return NULL; 54 return NULL;
51 } 55 }
56 dst->capacity = length;
52 dst->size = length; 57 dst->size = length;
53 dst->flags = flags | UCX_BUFFER_AUTOFREE; 58 dst->flags = flags | UCX_BUFFER_AUTOFREE;
54 dst->pos = 0; 59 dst->pos = 0;
55 memcpy(dst->space, (char*)src->space+start, length); 60 memcpy(dst->space, src->space+start, length);
56 } 61 }
57 return dst; 62 return dst;
58 } 63 }
59 64
60 int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence) { 65 int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence) {
65 break; 70 break;
66 case SEEK_CUR: 71 case SEEK_CUR:
67 npos = buffer->pos; 72 npos = buffer->pos;
68 break; 73 break;
69 case SEEK_END: 74 case SEEK_END:
70 npos = strlen((const char*) buffer->space); 75 npos = buffer->size;
71 break; 76 break;
72 } 77 }
73 78
74 npos += offset; 79 npos += offset;
75 80
76 if (npos < 0 || npos > buffer->size) { 81 if (npos < 0 || npos > buffer->size) {
77 return -1; 82 return -1;
78 } else { 83 } else {
79 buffer->pos = npos; 84 buffer->pos = npos;
80 return 0; 85 return 0;
84 89
85 int ucx_buffer_eof(UcxBuffer *buffer) { 90 int ucx_buffer_eof(UcxBuffer *buffer) {
86 return buffer->pos >= buffer->size; 91 return buffer->pos >= buffer->size;
87 } 92 }
88 93
89 size_t ucx_bufio(void* d, size_t s, size_t n, UcxBuffer *b, _Bool read) { 94 int ucx_buffer_extend(UcxBuffer *buffer, size_t len) {
90 size_t len = s*n; 95 size_t newcap = buffer->capacity;
91 if (b->pos + len > b->size) { 96 while (buffer->pos + len > newcap) newcap <<= 1;
92 if ((b->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) { 97
93 size_t newsize = b->size; 98 char *newspace = realloc(buffer->space, newcap);
94 while (b->pos + len > newsize) newsize <<= 1; 99 if (newspace) {
95 void *newspace = realloc(b->space, newsize); 100 memset(newspace+buffer->size, 0, newcap-buffer->size);
96 if (newspace) { 101 buffer->space = newspace;
97 memset((char*)newspace+b->size, 0, newsize-b->size); 102 buffer->capacity = newcap;
98 b->space = newspace; 103 } else {
99 b->size = newsize; 104 return -1;
100 } else { 105 }
101 len = -1; 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;
102 } 117 }
103 } else { 118 } else {
104 len = b->size - b->pos; 119 len = buffer->capacity - buffer->pos;
105 if (s > 1) len -= len%s; 120 if (size > 1) len -= len%size;
106 } 121 }
107 } 122 }
108 123
109 if (len <= 0) { 124 if (len <= 0) {
110 return len; 125 return len;
111 } 126 }
112 127
113 if (read) { 128 memcpy(buffer->space + buffer->pos, ptr, len);
114 memcpy(d, (char*)b->space+b->pos, len); 129 buffer->pos += len;
115 } else { 130 if(buffer->pos > buffer->size) {
116 memcpy((char*)b->space+b->pos, d, len); 131 buffer->size = buffer->pos;
117 } 132 }
118 b->pos += len; 133
119 134 return len / size;
120 return len; 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;
121 } 153 }
122 154
123 int ucx_buffer_putc(UcxBuffer *buffer, int c) { 155 int ucx_buffer_putc(UcxBuffer *buffer, int c) {
124 if (ucx_buffer_eof(buffer)) { 156 if(buffer->pos >= buffer->capacity) {
125 return EOF; 157 if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
126 } else { 158 if(ucx_buffer_extend(buffer, 1)) {
127 c &= 0xFF; 159 return EOF;
128 ((char*)(buffer->space))[buffer->pos] = (char) c; 160 }
129 buffer->pos++; 161 } else {
130 return c; 162 return EOF;
131 } 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;
132 } 173 }
133 174
134 int ucx_buffer_getc(UcxBuffer *buffer) { 175 int ucx_buffer_getc(UcxBuffer *buffer) {
135 if (ucx_buffer_eof(buffer)) { 176 if (ucx_buffer_eof(buffer)) {
136 return EOF; 177 return EOF;
137 } else { 178 } else {
138 int c = ((char*)(buffer->space))[buffer->pos]; 179 int c = buffer->space[buffer->pos];
139 buffer->pos++; 180 buffer->pos++;
140 return c; 181 return c;
141 } 182 }
142 } 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