]> pd.if.org Git - zpackage/blob - lib/buffer.c
add buffer lib files
[zpackage] / lib / buffer.c
1 #define _POSIX_C_SOURCE 200809L
2
3 #include <string.h>
4 #include <errno.h>
5 #include <stdarg.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8
9 #include "buffer.h"
10
11 void zpm_buffer_init(struct zpm_buffer *buffer) {
12         buffer->buffer = 0;
13         buffer->len = 0;
14         buffer->size = 0;
15         buffer->error = 0;
16 }
17
18 void zpm_buffer_compact(struct zpm_buffer *b) {
19         void *new;
20
21         if (b->error || b->size == b->len) {
22                 return;
23         }
24
25         errno = 0;
26         new = realloc(b->buffer, b->len);
27
28         if (new == NULL) {
29                 b->error = errno;
30                 return;
31         }
32
33         b->buffer = new;
34         return;
35 }
36
37 /* makes sure there's at least need bytes free */
38 void zpm_buffer_expand(struct zpm_buffer *buf, size_t need) {
39         size_t want;
40
41         if (buf->error) {
42                 return;
43         }
44
45         want = buf->len + need;
46
47         if (want <= buf->size) {
48                 return;
49         }
50
51         errno = 0;
52         char *new = realloc(buf->buffer, want);
53         if (new) {
54                 buf->buffer = new;
55                 buf->size = want;
56                 memset(buf->buffer + buf->len, 0, buf->size - buf->len);
57         } else {
58                 buf->error = errno;
59         }
60 }
61
62 void zpm_buffer_free(struct zpm_buffer *buffer) {
63         /* TODO only zero out memory if it's "secure" buffer */
64         if (buffer->buffer && buffer->len) {
65                 memset(buffer->buffer, 0, buffer->len);
66         }
67         free(buffer->buffer);
68         zpm_buffer_init(buffer);
69 }
70
71 void zpm_buffer_set(struct zpm_buffer *buffer, int ch) {
72         /* TODO only zero out memory if it's "secure" buffer */
73         if (buffer->buffer && buffer->size) {
74                 memset(buffer->buffer, ch, buffer->size);
75         }
76 }
77
78 void zpm_buffer_appendvf(struct zpm_buffer *buf, const char *fmt, va_list ap) {
79         int len;
80         va_list ar;
81
82         va_copy(ar, ap);
83         len = vsnprintf(0, 0, fmt, ar);
84         va_end(ar);
85
86         zpm_buffer_expand(buf, len+1);
87         vsprintf(buf->buffer + buf->len, fmt, ap);
88 }
89
90 void zpm_buffer_appendf(struct zpm_buffer *buf, const char *fmt, ...) {
91         va_list ap;
92         int len;
93
94         va_start(ap, fmt);
95         len = vsnprintf(0, 0, fmt, ap);
96         va_end(ap);
97         zpm_buffer_expand(buf, len+1);
98         va_start(ap, fmt);
99         vsprintf(buf->buffer + buf->len, fmt, ap);
100         va_end(ap);
101 }
102
103 void zpm_buffer_append(struct zpm_buffer *buffer, const unsigned char *bytes, size_t n) {
104         zpm_buffer_expand(buffer, n);
105
106         if (buffer->error || !bytes) {
107                 return;
108         }
109
110         memcpy(buffer->buffer + buffer->len, bytes, n);
111         buffer->len += n;
112 }
113
114 void zpm_buffer_append_str(struct zpm_buffer *buf, const char *s) {
115         zpm_buffer_append(buf, (const unsigned char *)s, strlen(s));
116 }
117
118 void zpm_buffer_append16(struct zpm_buffer *buffer, uint16_t n) {
119         zpm_buffer_expand(buffer, 2);
120
121         if (buffer->error) {
122                 return;
123         }
124
125         buffer->buffer[buffer->len++] = (n >> 8) & 0xff;
126         buffer->buffer[buffer->len++] = n & 0xff;
127 }
128
129 void zpm_buffer_append24(struct zpm_buffer *buffer, uint32_t n) {
130         zpm_buffer_expand(buffer, 3);
131
132         if (buffer->error) {
133                 return;
134         }
135
136         buffer->buffer[buffer->len++] = (n >> 16) & 0xff;
137         buffer->buffer[buffer->len++] = (n >> 8) & 0xff;
138         buffer->buffer[buffer->len++] = n & 0xff;
139 }
140
141 void zpm_buffer_append_byte(struct zpm_buffer *buffer, uint8_t n) {
142         zpm_buffer_expand(buffer, 1);
143
144         if (buffer->error) {
145                 return;
146         }
147
148         buffer->buffer[buffer->len++] = n & 0xff;
149 }
150
151 void zpm_buffer_write16(struct zpm_buffer *buffer, uint16_t n, size_t at) {
152         if (at+2 > buffer->size) {
153                 zpm_buffer_expand(buffer, at+2 - buffer->size);
154         }
155
156         if (buffer->error) {
157                 return;
158         }
159
160         buffer->buffer[at] = (n >> 8) & 0xff;
161         buffer->buffer[at+1] = n & 0xff;
162
163         if (at+2 > buffer->len) {
164                 buffer->len = at + 2;
165         }
166 }
167
168 uint16_t zpm_buffer_read16(struct zpm_buffer *buffer, size_t at) {
169         uint16_t res = 0;
170
171         if (buffer->error || at+2 < buffer->len) {
172                 return 0;
173         }
174
175         res = (buffer->buffer[at] << 8) + buffer->buffer[at+1];
176         return res;
177 }
178
179 uint64_t zpm_buffer_readbe(struct zpm_buffer *buffer, int bytes, size_t at) {
180         uint16_t res = 0;
181         int i;
182
183         if (buffer->error || at+bytes < buffer->len) {
184                 return 0;
185         }
186
187         for (i=0; i<bytes; i++) {
188                 res <<= 8;
189                 res += buffer->buffer[at+i];
190         }
191
192         return res;
193 }
194
195 void zpm_buffer_writebe(struct zpm_buffer *buffer, int bytes, size_t at, uint64_t val) {
196         int i;
197         if (at+bytes > buffer->size) {
198                 zpm_buffer_expand(buffer, at+bytes - buffer->size);
199         }
200
201         if (buffer->error) {
202                 return;
203         }
204
205         for (i=bytes-1; i>=0; i--) {
206                 buffer->buffer[at+i] = val & 0xff;
207                 val >>= 8;
208         }
209
210         return;
211 }
212
213 void zpm_buffer_shift(struct zpm_buffer *buffer, size_t n) {
214         if (buffer->error) {
215                 return;
216         }
217
218         if (buffer->len < n) {
219                 n = buffer->len;
220         }
221
222         if (n) {
223                 memmove(buffer->buffer, buffer->buffer + n, buffer->len - n);
224                 memset(buffer->buffer + buffer->len - n, 0, n);
225 #if 0
226                 fprintf(stderr, "memmove(%p, %p, %zu)\n", buffer->buffer,
227                                 buffer->buffer+n, buffer->len - n);
228                 fprintf(stderr, "memset(%p, %d, %zu)\n", buffer->buffer+n,
229                                 0, n);
230 #endif
231
232                 buffer->len -= n;
233         }
234 }
235
236 /* make room at the beginning */
237 void zpm_buffer_unshift(struct zpm_buffer *buffer, size_t n) {
238         zpm_buffer_expand(buffer, n);
239
240         if (buffer->error) {
241                 return;
242         }
243
244         memmove(buffer->buffer + n, buffer->buffer, n);
245         memset(buffer->buffer, 0, n);
246 }
247
248 #if 0
249 uint32_t zpm_buffer_next3(struct zpm_buffer_reader *rb) {
250         uint32_t r;
251
252         r = zpm_buffer_readbe(rb, 3, rb->cursor);
253         rb->cursor += 3;
254         return r;
255 }
256
257 uint16_t zpm_buffer_next2(struct zpm_buffer_reader *rb) {
258         uint16_t r;
259
260         r = zpm_buffer_readbe(rb, 2, rb->cursor);
261         rb->cursor += 2;
262         return r;
263 }
264
265 uint8_t zpm_buffer_next(struct zpm_buffer_reader *rb) {
266         uint16_t r;
267
268         r = zpm_buffer_readbe(rb, 2, rb->cursor);
269         rb->cursor += 2;
270
271 }
272
273 void zpm_buffer_nextn(struct zpm_buffer_reader *rb, unsigned char *b, size_t n) {
274         zpm_buffer_read(rb, b, n, rb->cursor);
275         rb->cursor += n;
276 }
277 #endif