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