Commit | Line | Data |
---|---|---|
800d4c59 | 1 | /* -*-c-*- |
2 | * | |
800d4c59 | 3 | * Buffer handling |
4 | * | |
5 | * (c) 2001 Straylight/Edgeware | |
6 | */ | |
7 | ||
d4efbcd9 | 8 | /*----- Licensing notice --------------------------------------------------* |
800d4c59 | 9 | * |
9b5ac6ff | 10 | * This file is part of the mLib utilities library. |
800d4c59 | 11 | * |
9b5ac6ff | 12 | * mLib is free software; you can redistribute it and/or modify |
800d4c59 | 13 | * it under the terms of the GNU Library General Public License as |
14 | * published by the Free Software Foundation; either version 2 of the | |
15 | * License, or (at your option) any later version. | |
d4efbcd9 | 16 | * |
9b5ac6ff | 17 | * mLib is distributed in the hope that it will be useful, |
800d4c59 | 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU Library General Public License for more details. | |
d4efbcd9 | 21 | * |
800d4c59 | 22 | * You should have received a copy of the GNU Library General Public |
9b5ac6ff | 23 | * License along with mLib; if not, write to the Free |
800d4c59 | 24 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
25 | * MA 02111-1307, USA. | |
26 | */ | |
27 | ||
28 | /*----- Header files ------------------------------------------------------*/ | |
29 | ||
9b5ac6ff | 30 | #include <assert.h> |
800d4c59 | 31 | #include <string.h> |
32 | ||
800d4c59 | 33 | #include "buf.h" |
0d61a23c | 34 | #include "macros.h" |
800d4c59 | 35 | |
36 | /*----- Main code ---------------------------------------------------------*/ | |
37 | ||
38 | /* --- @buf_init@ --- * | |
39 | * | |
31d0247c | 40 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
800d4c59 | 41 | * @void *p@ = pointer to a buffer |
42 | * @size_t sz@ = size of the buffer | |
43 | * | |
44 | * Returns: --- | |
45 | * | |
46 | * Use: Initializes the buffer block appropriately. | |
47 | */ | |
48 | ||
49 | void buf_init(buf *b, void *p, size_t sz) | |
50 | { | |
51 | b->base = b->p = p; | |
52 | b->limit = b->p + sz; | |
53 | b->f = 0; | |
54 | } | |
55 | ||
c91413e6 | 56 | /* --- @dbuf_create@ --- * |
e63124bc MW |
57 | * |
58 | * Arguments: @dbuf *db@ = pointer to a dynamic buffer block | |
59 | * | |
60 | * Returns: --- | |
61 | * | |
62 | * Use: Initializes a dynamic buffer. The buffer is initially empty, | |
63 | * and ready for writing. | |
64 | */ | |
65 | ||
c91413e6 | 66 | void dbuf_create(dbuf *db) |
e63124bc MW |
67 | { |
68 | db->_b.base = db->_b.p = db->_b.limit = 0; db->_b.f = BF_ALLOC | BF_WRITE; | |
69 | db->a = &arena_stdlib; db->sz = 0; | |
70 | } | |
71 | ||
72 | /* --- @dbuf_reset@ --- * | |
73 | * | |
74 | * Arguments: @dbuf *db@ = pointer to a buffer block | |
75 | * | |
76 | * Returns: --- | |
77 | * | |
78 | * Use: Resets a buffer so that it can be written again. | |
79 | */ | |
80 | ||
31d0247c | 81 | void dbuf_reset(dbuf *db) { DBRESET(db); } |
e63124bc MW |
82 | |
83 | /* --- @dbuf_destroy@ --- * | |
84 | * | |
85 | * Arguments: @dbuf *db@ = pointer to a buffer block | |
86 | * | |
87 | * Returns: --- | |
88 | * | |
89 | * Use: Release all of the resources held by a dynamic buffer. | |
90 | */ | |
91 | ||
92 | void dbuf_destroy(dbuf *db) | |
93 | { | |
94 | if (db->_b.base) x_free(db->a, db->_b.base); | |
c91413e6 | 95 | dbuf_create(db); |
e63124bc MW |
96 | } |
97 | ||
31d0247c | 98 | /* --- @{,d}buf_break@ --- * |
800d4c59 | 99 | * |
31d0247c | 100 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
800d4c59 | 101 | * |
102 | * Returns: Some negative value. | |
103 | * | |
104 | * Use: Marks a buffer as broken. | |
105 | */ | |
106 | ||
107 | int buf_break(buf *b) { b->f |= BF_BROKEN; return (-1); } | |
31d0247c | 108 | int (dbuf_break)(dbuf *db) { return (dbuf_break(db)); } |
800d4c59 | 109 | |
31d0247c | 110 | /* --- @{,d}buf_flip@ --- * |
800d4c59 | 111 | * |
31d0247c | 112 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
800d4c59 | 113 | * |
114 | * Returns: --- | |
115 | * | |
116 | * Use: Flips a buffer so that if you've just been writing to it, | |
117 | * you can now read from the bit you've written. | |
118 | */ | |
119 | ||
31d0247c MW |
120 | void buf_flip(buf *b) { BFLIP(b); } |
121 | void (dbuf_flip)(dbuf *db) { dbuf_flip(db); } | |
800d4c59 | 122 | |
31d0247c | 123 | /* --- @{,d}buf_ensure@ --- * |
800d4c59 | 124 | * |
31d0247c | 125 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
800d4c59 | 126 | * @size_t sz@ = size of data wanted |
127 | * | |
128 | * Returns: Zero if it worked, nonzero if there wasn't enough space. | |
129 | * | |
130 | * Use: Ensures that there are @sz@ bytes still in the buffer. | |
131 | */ | |
132 | ||
133 | int buf_ensure(buf *b, size_t sz) { return (BENSURE(b, sz)); } | |
31d0247c | 134 | int (dbuf_ensure)(dbuf *db, size_t sz) { return (dbuf_ensure(db, sz)); } |
800d4c59 | 135 | |
31d0247c | 136 | /* --- @{,d}buf_tryextend@ --- * |
e63124bc | 137 | * |
31d0247c | 138 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
e63124bc MW |
139 | * @size_t sz@ = size of data wanted |
140 | * | |
141 | * Returns: Zero if it worked, nonzero if the buffer won't grow. | |
142 | * | |
143 | * Use: Extend the buffer so that at least @sz@ bytes are available. | |
144 | * This only works if the buffer is allocated. | |
145 | */ | |
146 | ||
147 | int buf_tryextend(buf *b, size_t sz) | |
148 | { | |
149 | dbuf *db; | |
150 | size_t newsz, len; | |
151 | ||
152 | if (~b->f&(BF_ALLOC | BF_WRITE)) | |
153 | { b->f |= BF_BROKEN; return (-1); } | |
154 | db = (dbuf *)b; | |
155 | len = BLEN(&db->_b); sz += len; | |
156 | if (db->sz >= sz) | |
157 | newsz = db->sz; | |
158 | else { | |
159 | newsz = db->sz ? 2*db->sz : 64; | |
160 | while (newsz < sz) { assert(newsz < ((size_t)-1)/2); newsz *= 2; } | |
161 | if (!db->_b.base) db->_b.base = x_alloc(db->a, newsz); | |
162 | else db->_b.base = x_realloc(db->a, db->_b.base, newsz, db->sz); | |
163 | db->_b.p = db->_b.base + len; db->sz = newsz; | |
164 | } | |
165 | db->_b.limit = db->_b.base + newsz; | |
166 | return (0); | |
167 | } | |
31d0247c MW |
168 | int (dbuf_tryextend)(dbuf *db, size_t sz) |
169 | { return (dbuf_tryextend(db, sz)); } | |
e63124bc | 170 | |
31d0247c | 171 | /* --- @{,d}buf_get@ --- * |
800d4c59 | 172 | * |
31d0247c | 173 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
800d4c59 | 174 | * @size_t sz@ = size of the buffer |
175 | * | |
176 | * Returns: Pointer to the place in the buffer. | |
177 | * | |
178 | * Use: Reserves a space in the buffer of the requested size, and | |
179 | * returns its start address. | |
180 | */ | |
181 | ||
182 | void *buf_get(buf *b, size_t sz) | |
183 | { | |
184 | void *p; | |
185 | if (BENSURE(b, sz)) | |
186 | return (0); | |
187 | p = BCUR(b); | |
188 | BSTEP(b, sz); | |
189 | return (p); | |
190 | } | |
31d0247c MW |
191 | void *(dbuf_get)(dbuf *db, size_t sz) |
192 | { return (dbuf_get(db, sz)); } | |
800d4c59 | 193 | |
31d0247c | 194 | /* --- @{,d}buf_put@ --- * |
800d4c59 | 195 | * |
31d0247c | 196 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
800d4c59 | 197 | * @const void *p@ = pointer to a buffer |
198 | * @size_t sz@ = size of the buffer | |
199 | * | |
200 | * Returns: Zero if it worked, nonzero if there wasn't enough space. | |
201 | * | |
202 | * Use: Fetches data from some place and puts it in the buffer | |
203 | */ | |
204 | ||
205 | int buf_put(buf *b, const void *p, size_t sz) | |
206 | { | |
207 | if (BENSURE(b, sz)) | |
208 | return (-1); | |
209 | memcpy(BCUR(b), p, sz); | |
210 | BSTEP(b, sz); | |
211 | return (0); | |
212 | } | |
31d0247c MW |
213 | int (dbuf_put)(dbuf *db, const void *p, size_t sz) |
214 | { return (dbuf_put(db, p, sz)); } | |
800d4c59 | 215 | |
31d0247c | 216 | /* --- @{,d}buf_getbyte@ --- * |
800d4c59 | 217 | * |
31d0247c | 218 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
800d4c59 | 219 | * |
220 | * Returns: A byte, or less than zero if there wasn't a byte there. | |
221 | * | |
222 | * Use: Gets a single byte from a buffer. | |
223 | */ | |
224 | ||
225 | int buf_getbyte(buf *b) | |
226 | { | |
227 | if (BENSURE(b, 1)) | |
228 | return (-1); | |
229 | return (*b->p++); | |
230 | } | |
31d0247c MW |
231 | int (dbuf_getbyte)(dbuf *db) |
232 | { return (dbuf_getbyte(db)); } | |
800d4c59 | 233 | |
31d0247c | 234 | /* --- @{,d}buf_putbyte@ --- * |
800d4c59 | 235 | * |
31d0247c | 236 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
800d4c59 | 237 | * @int ch@ = byte to write |
238 | * | |
239 | * Returns: Zero if OK, nonzero if there wasn't enough space. | |
240 | * | |
241 | * Use: Puts a single byte in a buffer. | |
242 | */ | |
243 | ||
244 | int buf_putbyte(buf *b, int ch) | |
245 | { | |
246 | if (BENSURE(b, 1)) | |
247 | return (-1); | |
248 | *b->p++ = ch; | |
249 | return (0); | |
250 | } | |
31d0247c MW |
251 | int (dbuf_putbyte)(dbuf *db, int ch) |
252 | { return (dbuf_putbyte(db, ch)); } | |
800d4c59 | 253 | |
31d0247c | 254 | /* --- @{,d}buf_getu{8,{16,24,32,64}{,l,b}}@ --- * |
800d4c59 | 255 | * |
31d0247c | 256 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
9b5ac6ff | 257 | * @uintSZ *w@ = where to put the word |
800d4c59 | 258 | * |
259 | * Returns: Zero if OK, or nonzero if there wasn't a word there. | |
260 | * | |
9b5ac6ff | 261 | * Use: Gets a word of appropriate size and order from a buffer. |
800d4c59 | 262 | */ |
263 | ||
9b5ac6ff | 264 | #define BUF_GETU_(n, W, w) \ |
265 | int buf_getu##w(buf *b, uint##n *ww) \ | |
266 | { \ | |
267 | if (BENSURE(b, SZ_##W)) return (-1); \ | |
268 | *ww = LOAD##W(b->p); \ | |
269 | BSTEP(b, SZ_##W); \ | |
270 | return (0); \ | |
31d0247c MW |
271 | } \ |
272 | int (dbuf_getu##w)(dbuf *db, uint##n *ww) \ | |
273 | { return (dbuf_getu##w(db, ww)); } | |
9b5ac6ff | 274 | DOUINTCONV(BUF_GETU_) |
800d4c59 | 275 | |
31d0247c | 276 | /* --- @{,d}buf_getk64{,l,b}@ --- * |
b64eb60f | 277 | * |
31d0247c | 278 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
b64eb60f MW |
279 | * @kludge64 *w@ = where to put the word |
280 | * | |
281 | * Returns: Zero if OK, or nonzero if there wasn't a word there. | |
282 | * | |
283 | * Use: Gets a word of appropriate size and order from a buffer. | |
284 | */ | |
285 | ||
286 | int buf_getk64(buf *b, kludge64 *w) | |
287 | { | |
288 | if (BENSURE(b, 8)) return (-1); | |
289 | LOAD64_(*w, b->p); BSTEP(b, 8); return (0); | |
290 | } | |
291 | ||
292 | int buf_getk64l(buf *b, kludge64 *w) | |
293 | { | |
294 | if (BENSURE(b, 8)) return (-1); | |
295 | LOAD64_L_(*w, b->p); BSTEP(b, 8); return (0); | |
296 | } | |
297 | ||
298 | int buf_getk64b(buf *b, kludge64 *w) | |
299 | { | |
300 | if (BENSURE(b, 8)) return (-1); | |
301 | LOAD64_B_(*w, b->p); BSTEP(b, 8); return (0); | |
302 | } | |
303 | ||
31d0247c MW |
304 | int (dbuf_getk64)(dbuf *db, kludge64 *w) { return (dbuf_getk64(db, w)); } |
305 | int (dbuf_getk64l)(dbuf *db, kludge64 *w) { return (dbuf_getk64l(db, w)); } | |
306 | int (dbuf_getk64b)(dbuf *db, kludge64 *w) { return (dbuf_getk64b(db, w)); } | |
307 | ||
308 | /* --- @{,d}buf_putu{8,{16,24,32,64}{,l,b}}@ --- * | |
800d4c59 | 309 | * |
31d0247c | 310 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
9b5ac6ff | 311 | * @uintSZ w@ = word to write |
800d4c59 | 312 | * |
9b5ac6ff | 313 | * Returns: Zero if OK, or nonzero if there wasn't enough space |
800d4c59 | 314 | * |
9b5ac6ff | 315 | * Use: Puts a word into a buffer with appropriate size and order. |
800d4c59 | 316 | */ |
317 | ||
9b5ac6ff | 318 | #define BUF_PUTU_(n, W, w) \ |
319 | int buf_putu##w(buf *b, uint##n ww) \ | |
320 | { \ | |
321 | if (BENSURE(b, SZ_##W)) return (-1); \ | |
322 | STORE##W(b->p, ww); \ | |
323 | BSTEP(b, SZ_##W); \ | |
324 | return (0); \ | |
31d0247c MW |
325 | } \ |
326 | int (dbuf_putu##w)(dbuf *db, uint##n ww) \ | |
327 | { return (dbuf_putu##w(db, ww)); } | |
9b5ac6ff | 328 | DOUINTCONV(BUF_PUTU_) |
800d4c59 | 329 | |
31d0247c | 330 | /* --- @{,d}buf_putk64{,l,b}@ --- * |
b64eb60f | 331 | * |
31d0247c | 332 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
b64eb60f MW |
333 | * @kludge64 w@ = word to write |
334 | * | |
335 | * Returns: Zero if OK, or nonzero if there wasn't enough space | |
336 | * | |
337 | * Use: Gets a word of appropriate size and order from a buffer. | |
338 | */ | |
339 | ||
340 | int buf_putk64(buf *b, kludge64 w) | |
341 | { | |
342 | if (BENSURE(b, 8)) return (-1); | |
343 | STORE64_(b->p, w); BSTEP(b, 8); return (0); | |
344 | } | |
345 | ||
346 | int buf_putk64l(buf *b, kludge64 w) | |
347 | { | |
348 | if (BENSURE(b, 8)) return (-1); | |
349 | STORE64_L_(b->p, w); BSTEP(b, 8); return (0); | |
350 | } | |
351 | ||
352 | int buf_putk64b(buf *b, kludge64 w) | |
353 | { | |
354 | if (BENSURE(b, 8)) return (-1); | |
355 | STORE64_B_(b->p, w); BSTEP(b, 8); return (0); | |
356 | } | |
357 | ||
31d0247c MW |
358 | int (dbuf_putk64)(dbuf *db, kludge64 w) { return (dbuf_putk64(db, w)); } |
359 | int (dbuf_putk64l)(dbuf *db, kludge64 w) { return (dbuf_putk64l(db, w)); } | |
360 | int (dbuf_putk64b)(dbuf *db, kludge64 w) { return (dbuf_putk64b(db, w)); } | |
361 | ||
800d4c59 | 362 | /* --- @findz@ --- * |
363 | * | |
31d0247c | 364 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
800d4c59 | 365 | * @size_t *nn@ = where to put the length |
366 | * | |
367 | * Returns: Zero if OK, nonzero if there wasn't a null byte to be found. | |
368 | * | |
95491579 MW |
369 | * Use: Finds a terminating null byte. The length includes this |
370 | * terminator. | |
800d4c59 | 371 | */ |
372 | ||
373 | static int findz(buf *b, size_t *nn) | |
374 | { | |
375 | octet *p; | |
376 | ||
a4589237 | 377 | if ((p = memchr(BCUR(b), 0, BLEFT(b))) == 0) { |
800d4c59 | 378 | buf_break(b); |
379 | return (-1); | |
380 | } | |
95491579 | 381 | *nn = p - BCUR(b) + 1; |
800d4c59 | 382 | return (0); |
383 | } | |
384 | ||
31d0247c | 385 | /* --- @{,d}buf_getmem{8,{16,24,32,64}{,l,b},z} --- * |
800d4c59 | 386 | * |
31d0247c | 387 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
800d4c59 | 388 | * @size_t *nn@ = where to put the length |
389 | * | |
390 | * Returns: Pointer to the buffer data, or null. | |
391 | * | |
9b5ac6ff | 392 | * Use: Gets a chunk of memory from a buffer. The suffix is the |
393 | * width and byte order of the length; @z@ means null- | |
394 | * terminated. | |
800d4c59 | 395 | */ |
396 | ||
9b5ac6ff | 397 | #define BUF_GETMEM_(n, W, w) \ |
398 | void *buf_getmem##w(buf *b, size_t *nn) \ | |
399 | { \ | |
400 | uint##n sz; \ | |
a4589237 | 401 | if (buf_getu##w(b, &sz)) return (0); \ |
f868c432 | 402 | if (BENSURE(b, sz)) return (0); \ |
9b5ac6ff | 403 | *nn = sz; \ |
404 | return (buf_get(b, sz)); \ | |
31d0247c MW |
405 | } \ |
406 | void *(dbuf_getmem##w)(dbuf *db, size_t *nn) \ | |
407 | { return (dbuf_getmem##w(db, nn)); } | |
9b5ac6ff | 408 | DOUINTCONV(BUF_GETMEM_) |
800d4c59 | 409 | |
800d4c59 | 410 | void *buf_getmemz(buf *b, size_t *nn) |
411 | { | |
412 | if (findz(b, nn)) return (0); | |
413 | return (buf_get(b, *nn)); | |
414 | } | |
31d0247c MW |
415 | void *(dbuf_getmemz)(dbuf *db, size_t *nn) |
416 | { return (dbuf_getmemz(db, nn)); } | |
800d4c59 | 417 | |
e63124bc MW |
418 | #ifndef HAVE_UINT64 |
419 | ||
420 | static void *getmem_k64(buf *b, size_t *nn_out, kludge64 k) | |
421 | { | |
422 | kludge64 szmax; | |
423 | size_t n; | |
424 | ||
425 | ASSIGN64(szmax, (size_t)-1); | |
426 | if (CMP64(k, >, szmax)) { buf_break(b); return (-1); } | |
427 | n = GET64(size_t, k); *nn_out = n; return (buf_get(b, n)); | |
428 | } | |
429 | ||
430 | void *buf_getmem64(buf *b, size_t *nn) | |
431 | { | |
432 | kludge64 k; | |
433 | ||
434 | if (buf_getk64(b, &k)) return (-1); | |
435 | return (getmem_k64(b, nn, k)); | |
436 | } | |
437 | ||
31d0247c | 438 | void *buf_getmem64l(buf *b, size_t *nn) |
e63124bc MW |
439 | { |
440 | kludge64 k; | |
441 | ||
31d0247c | 442 | if (buf_getk64l(b, &k)) return (-1); |
e63124bc MW |
443 | return (getmem_k64(b, nn, k)); |
444 | } | |
445 | ||
31d0247c | 446 | void *buf_getmem64b(buf *b, size_t *nn) |
e63124bc MW |
447 | { |
448 | kludge64 k; | |
449 | ||
31d0247c | 450 | if (buf_getk64b(b, &k)) return (-1); |
e63124bc MW |
451 | return (getmem_k64(b, nn, k)); |
452 | } | |
453 | ||
31d0247c MW |
454 | void *(dbuf_getmem64)(dbuf *db, size_t *nn) |
455 | { return (dbuf_getmem64(db, nn)); } | |
456 | void *(dbuf_getmem64l)(dbuf *db, size_t *nn) | |
457 | { return (dbuf_getmem64l(db, nn)); } | |
458 | void *(dbuf_getmem64b)(dbuf *db, size_t *nn) | |
459 | { return (dbuf_getmem64b(db, nn)); } | |
460 | ||
e63124bc MW |
461 | #endif |
462 | ||
31d0247c | 463 | /* --- @{,d}buf_putmem{8,{16,24,32,64}{,l,b},z} --- * |
800d4c59 | 464 | * |
31d0247c | 465 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
800d4c59 | 466 | * @const void *p@ = pointer to data to write |
467 | * @size_t n@ = length to write | |
468 | * | |
469 | * Returns: Zero if OK, nonzero if there wasn't enough space. | |
470 | * | |
9b5ac6ff | 471 | * Use: Writes a chunk of data to a buffer. The suffix is the |
472 | * width and byte order of the length; @z@ means null- | |
473 | * terminated. | |
800d4c59 | 474 | */ |
475 | ||
9b5ac6ff | 476 | #define BUF_PUTMEM_(n, W, w) \ |
477 | int buf_putmem##w(buf *b, const void *p, size_t sz) \ | |
478 | { \ | |
0d61a23c MW |
479 | MUFFLE_WARNINGS_STMT \ |
480 | (CLANG_WARNING("-Wtautological-constant-out-of-range-compare"), \ | |
481 | { assert(sz <= MASK##W); }); \ | |
a4589237 | 482 | if (buf_putu##w(b, sz) || buf_put(b, p, sz)) \ |
9b5ac6ff | 483 | return (-1); \ |
484 | return (0); \ | |
31d0247c MW |
485 | } \ |
486 | int (dbuf_putmem##w)(dbuf *db, const void *p, size_t sz) \ | |
487 | { return (dbuf_putmem##w(db, p, sz)); } | |
9b5ac6ff | 488 | DOUINTCONV(BUF_PUTMEM_) |
800d4c59 | 489 | |
e63124bc MW |
490 | #ifndef HAVE_UINT64 |
491 | ||
492 | void *buf_putmem64(buf *b, const void *p, size_t n) | |
493 | { | |
494 | kludge64 k; | |
495 | ||
496 | ASSIGN64(k, n); if (buf_putk64(b, k) || buf_put(b, p, n)) return (-1); | |
497 | return (0); | |
498 | } | |
499 | ||
31d0247c | 500 | void *buf_putmem64l(buf *b, const void *p, size_t n) |
e63124bc MW |
501 | { |
502 | kludge64 k; | |
503 | ||
31d0247c | 504 | ASSIGN64(k, n); if (buf_putk64l(b, k) || buf_put(b, p, n)) return (-1); |
e63124bc MW |
505 | return (0); |
506 | } | |
507 | ||
31d0247c | 508 | void *buf_putmem64b(buf *b, const void *p, size_t n) |
e63124bc MW |
509 | { |
510 | kludge64 k; | |
511 | ||
31d0247c | 512 | ASSIGN64(k, n); if (buf_putk64b(b, k) || buf_put(b, p, n)) return (-1); |
e63124bc MW |
513 | return (0); |
514 | } | |
515 | ||
31d0247c MW |
516 | int (dbuf_putmem64)(dbuf *db, const void *p, size_t n) |
517 | { return (dbuf_putmem64(db, p, n)); } | |
518 | int (dbuf_putmem64l)(dbuf *db, const void *p, size_t n) | |
519 | { return (dbuf_putmem64l(db, p, n)); } | |
520 | int (dbuf_putmem64b)(dbuf *db, const void *p, size_t n) | |
521 | { return (dbuf_putmem64b(db, p, n)); } | |
522 | ||
e63124bc MW |
523 | #endif |
524 | ||
800d4c59 | 525 | int buf_putmemz(buf *b, const void *p, size_t n) |
526 | { | |
527 | octet *q; | |
528 | ||
529 | assert(!memchr(p, 0, n)); | |
530 | if ((q = buf_get(b, n + 1)) == 0) | |
531 | return (-1); | |
532 | memcpy(q, p, n); | |
533 | q[n] = 0; | |
534 | return (0); | |
535 | } | |
31d0247c MW |
536 | int (dbuf_putmemz)(dbuf *db, const void *p, size_t n) |
537 | { return (dbuf_putmemz(db, p, n)); } | |
800d4c59 | 538 | |
31d0247c | 539 | /* --- @{,d}buf_getbuf{8,{16,24,32,64}{,l,b},z} --- * |
800d4c59 | 540 | * |
31d0247c | 541 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
800d4c59 | 542 | * @buf *bb@ = where to put the result |
543 | * | |
544 | * Returns: Zero if it worked, nonzero if there wasn't enough space. | |
545 | * | |
546 | * Use: Gets a block of data from a buffer, and writes its bounds to | |
9b5ac6ff | 547 | * another buffer. |
800d4c59 | 548 | */ |
549 | ||
9b5ac6ff | 550 | #define BUF_GETBUF_(n, W, w) \ |
551 | int buf_getbuf##w(buf *b, buf *bb) \ | |
552 | { \ | |
553 | void *p; \ | |
554 | size_t sz; \ | |
800d4c59 | 555 | \ |
9b5ac6ff | 556 | if ((p = buf_getmem##w(b, &sz)) == 0) \ |
557 | return (-1); \ | |
558 | buf_init(bb, p, sz); \ | |
559 | return (0); \ | |
31d0247c MW |
560 | } \ |
561 | int (dbuf_getbuf##w)(dbuf *db, buf *bb) \ | |
562 | { return (dbuf_getbuf##w(db, bb)); } | |
9b5ac6ff | 563 | BUF_DOSUFFIXES(BUF_GETBUF_) |
800d4c59 | 564 | |
31d0247c | 565 | /* --- @{,d}buf_putbuf{8,{16,24,32,64}{,l,b},z} --- * |
800d4c59 | 566 | * |
31d0247c | 567 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
9b5ac6ff | 568 | * @buf *bb@ = buffer to write |
800d4c59 | 569 | * |
570 | * Returns: Zero if it worked, nonzero if there wasn't enough space. | |
571 | * | |
9b5ac6ff | 572 | * Use: Puts the contents of a buffer to a buffer. |
800d4c59 | 573 | */ |
574 | ||
9b5ac6ff | 575 | #define BUF_PUTBUF_(n, W, w) \ |
576 | int buf_putbuf##w(buf *b, buf *bb) \ | |
31d0247c MW |
577 | { return (buf_putmem##w(b, BBASE(bb), BLEN(bb))); } \ |
578 | int (dbuf_putbuf##w)(dbuf *db, buf *bb) \ | |
579 | { return (dbuf_putbuf##w(db, bb)); } | |
9b5ac6ff | 580 | BUF_DOSUFFIXES(BUF_PUTBUF_) |
800d4c59 | 581 | |
31d0247c | 582 | /* --- @{,d}buf_putstr{8,{16,24,32,64}{,l,b},z} --- * |
800d4c59 | 583 | * |
31d0247c | 584 | * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block |
9b5ac6ff | 585 | * @const char *p@ = string to write |
800d4c59 | 586 | * |
587 | * Returns: Zero if it worked, nonzero if there wasn't enough space. | |
588 | * | |
9b5ac6ff | 589 | * Use: Puts a null-terminated string to a buffer. |
800d4c59 | 590 | */ |
591 | ||
9b5ac6ff | 592 | #define BUF_PUTSTR_(n, W, w) \ |
593 | int buf_putstr##w(buf *b, const char *p) \ | |
31d0247c MW |
594 | { return (buf_putmem##w(b, p, strlen(p))); } \ |
595 | int (dbuf_putstr##w)(dbuf *db, const char *p) \ | |
596 | { return (dbuf_putstr##w(db, p)); } | |
9b5ac6ff | 597 | BUF_DOSUFFIXES(BUF_PUTSTR_) |
800d4c59 | 598 | |
599 | /*----- That's all, folks -------------------------------------------------*/ |