chiark / gitweb /
f3c2e7f569b717f8a3d08c17fbfaca3fb4eb0700
[mLib] / struct / buf.3.in
1 .\" -*-nroff-*-
2 .\"
3 .\" Manual for buffer handling
4 .\"
5 .\" (c) 2005, 2007, 2009, 2017, 2023, 2024 Straylight/Edgeware
6 .\"
7 .
8 .\"----- Licensing notice ---------------------------------------------------
9 .\"
10 .\" This file is part of the mLib utilities library.
11 .\"
12 .\" mLib is free software: you can redistribute it and/or modify it under
13 .\" the terms of the GNU Library General Public License as published by
14 .\" the Free Software Foundation; either version 2 of the License, or (at
15 .\" your option) any later version.
16 .\"
17 .\" mLib is distributed in the hope that it will be useful, but WITHOUT
18 .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 .\" FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
20 .\" License for more details.
21 .\"
22 .\" You should have received a copy of the GNU Library General Public
23 .\" License along with mLib.  If not, write to the Free Software
24 .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 .\" USA.
26 .
27 .\"--------------------------------------------------------------------------
28 .so ../defs.man \" @@@PRE@@@
29 .
30 .\"--------------------------------------------------------------------------
31 .TH buf 3mLib "23 September 2005" "Straylight/Edgeware" "mLib utilities library"
32 .\" @BBASE
33 .\" @BLIM
34 .\" @BCUR
35 .\" @BSZ
36 .\" @BLEN
37 .\" @BLEFT
38 .\" @BSTEP
39 .\" @BBAD
40 .\" @BOK
41 .\" @BENSURE
42 .
43 .\" @DBBASE
44 .\" @DBLIM
45 .\" @DBCUR
46 .\" @DBSZ
47 .\" @DBLEN
48 .\" @DBLEFT
49 .\" @DBSTEP
50 .\" @DBBAD
51 .\" @DBOK
52 .\" @DBENSURE
53 .
54 .\" @buf_init
55 .
56 .\" @dbuf_create
57 .\" @dbuf_reset
58 .\" @dbuf_destroy
59 .\" @DBCREATE
60 .\" @DBRESET
61 .\" @DBDESTROY
62 .\" @DBUF_INIT
63 .\" @DBUF_BUF
64 .
65 .\" @buf_break
66 .\" @buf_flip
67 .\" @buf_ensure
68 .\" @buf_tryextend
69 .\" @buf_get
70 .\" @buf_put
71 .\" @buf_fill
72 .\" @dbuf_break
73 .\" @dbuf_flip
74 .\" @dbuf_ensure
75 .\" @dbuf_tryextend
76 .\" @dbuf_get
77 .\" @dbuf_put
78 .\" @dbuf_fill
79 .
80 .\" @buf_alignskip
81 .\" @buf_alignfill
82 .\" @dbuf_alignskip
83 .\" @dbuf_alignfill
84 .
85 .\" @buf_getbyte
86 .\" @buf_putbyte
87 .\" @dbuf_getbyte
88 .\" @dbuf_putbyte
89 .
90 .\" @buf_putstrf
91 .\" @buf_vputstrf
92 .\" @dbuf_putstrf
93 .\" @dbuf_vputstrf
94 .\" @buf_printops
95 .
96 .\" @buf_getu8
97 .\" @buf_getu16
98 .\" @buf_getu16b
99 .\" @buf_getu16l
100 .\" @buf_getu24
101 .\" @buf_getu24b
102 .\" @buf_getu24l
103 .\" @buf_getu32
104 .\" @buf_getu32b
105 .\" @buf_getu32l
106 .\" @buf_getu64
107 .\" @buf_getu64b
108 .\" @buf_getu64l
109 .\" @buf_getk64
110 .\" @buf_getk64b
111 .\" @buf_getk64l
112 .\" @dbuf_getu8
113 .\" @dbuf_getu16
114 .\" @dbuf_getu16b
115 .\" @dbuf_getu16l
116 .\" @dbuf_getu24
117 .\" @dbuf_getu24b
118 .\" @dbuf_getu24l
119 .\" @dbuf_getu32
120 .\" @dbuf_getu32b
121 .\" @dbuf_getu32l
122 .\" @dbuf_getu64
123 .\" @dbuf_getu64b
124 .\" @dbuf_getu64l
125 .\" @dbuf_getk64
126 .\" @dbuf_getk64b
127 .\" @dbuf_getk64l
128 .
129 .\" @buf_putu8
130 .\" @buf_putu16
131 .\" @buf_putu16b
132 .\" @buf_putu16l
133 .\" @buf_putu24
134 .\" @buf_putu24b
135 .\" @buf_putu24l
136 .\" @buf_putu32
137 .\" @buf_putu32b
138 .\" @buf_putu32l
139 .\" @buf_putu64
140 .\" @buf_putu64b
141 .\" @buf_putu64l
142 .\" @buf_putk64
143 .\" @buf_putk64b
144 .\" @buf_putk64l
145 .\" @dbuf_putu8
146 .\" @dbuf_putu16
147 .\" @dbuf_putu16b
148 .\" @dbuf_putu16l
149 .\" @dbuf_putu24
150 .\" @dbuf_putu24b
151 .\" @dbuf_putu24l
152 .\" @dbuf_putu32
153 .\" @dbuf_putu32b
154 .\" @dbuf_putu32l
155 .\" @dbuf_putu64
156 .\" @dbuf_putu64b
157 .\" @dbuf_putu64l
158 .\" @dbuf_putk64
159 .\" @dbuf_putk64b
160 .\" @dbuf_putk64l
161 .
162 .\" @buf_getf32
163 .\" @buf_getf32l
164 .\" @buf_getf32b
165 .\" @buf_putf32
166 .\" @buf_putf32l
167 .\" @buf_putf32b
168 .\" @buf_getf64
169 .\" @buf_getf64l
170 .\" @buf_getf64b
171 .\" @buf_putf64
172 .\" @buf_putf64l
173 .\" @buf_putf64b
174 .\" @dbuf_getf32
175 .\" @dbuf_getf32l
176 .\" @dbuf_getf32b
177 .\" @dbuf_putf32
178 .\" @dbuf_putf32l
179 .\" @dbuf_putf32b
180 .\" @dbuf_getf64
181 .\" @dbuf_getf64l
182 .\" @dbuf_getf64b
183 .\" @dbuf_putf64
184 .\" @dbuf_putf64l
185 .\" @dbuf_putf64b
186 .
187 .\" @buf_getbuf8
188 .\" @buf_getbuf16
189 .\" @buf_getbuf16b
190 .\" @buf_getbuf16l
191 .\" @buf_getbuf24
192 .\" @buf_getbuf24b
193 .\" @buf_getbuf24l
194 .\" @buf_getbuf32
195 .\" @buf_getbuf32b
196 .\" @buf_getbuf32l
197 .\" @buf_getbuf64
198 .\" @buf_getbuf64b
199 .\" @buf_getbuf64l
200 .\" @buf_getbufz
201 .\" @dbuf_getbuf8
202 .\" @dbuf_getbuf16
203 .\" @dbuf_getbuf16b
204 .\" @dbuf_getbuf16l
205 .\" @dbuf_getbuf24
206 .\" @dbuf_getbuf24b
207 .\" @dbuf_getbuf24l
208 .\" @dbuf_getbuf32
209 .\" @dbuf_getbuf32b
210 .\" @dbuf_getbuf32l
211 .\" @dbuf_getbuf64
212 .\" @dbuf_getbuf64b
213 .\" @dbuf_getbuf64l
214 .\" @dbuf_getbufz
215 .
216 .\" @buf_putbuf8
217 .\" @buf_putbuf16
218 .\" @buf_putbuf16b
219 .\" @buf_putbuf16l
220 .\" @buf_putbuf24
221 .\" @buf_putbuf24b
222 .\" @buf_putbuf24l
223 .\" @buf_putbuf32
224 .\" @buf_putbuf32b
225 .\" @buf_putbuf32l
226 .\" @buf_putbuf64
227 .\" @buf_putbuf64b
228 .\" @buf_putbuf64l
229 .\" @buf_putbufz
230 .\" @dbuf_putbuf8
231 .\" @dbuf_putbuf16
232 .\" @dbuf_putbuf16b
233 .\" @dbuf_putbuf16l
234 .\" @dbuf_putbuf24
235 .\" @dbuf_putbuf24b
236 .\" @dbuf_putbuf24l
237 .\" @dbuf_putbuf32
238 .\" @dbuf_putbuf32b
239 .\" @dbuf_putbuf32l
240 .\" @dbuf_putbuf64
241 .\" @dbuf_putbuf64b
242 .\" @dbuf_putbuf64l
243 .\" @dbuf_putbufz
244 .
245 .\" @buf_getmem8
246 .\" @buf_getmem16
247 .\" @buf_getmem16b
248 .\" @buf_getmem16l
249 .\" @buf_getmem24
250 .\" @buf_getmem24b
251 .\" @buf_getmem24l
252 .\" @buf_getmem32
253 .\" @buf_getmem32b
254 .\" @buf_getmem32l
255 .\" @buf_getmem64
256 .\" @buf_getmem64b
257 .\" @buf_getmem64l
258 .\" @buf_getmemz
259 .\" @dbuf_getmem8
260 .\" @dbuf_getmem16
261 .\" @dbuf_getmem16b
262 .\" @dbuf_getmem16l
263 .\" @dbuf_getmem24
264 .\" @dbuf_getmem24b
265 .\" @dbuf_getmem24l
266 .\" @dbuf_getmem32
267 .\" @dbuf_getmem32b
268 .\" @dbuf_getmem32l
269 .\" @dbuf_getmem64
270 .\" @dbuf_getmem64b
271 .\" @dbuf_getmem64l
272 .\" @dbuf_getmemz
273 .
274 .\" @buf_putmem8
275 .\" @buf_putmem16
276 .\" @buf_putmem16b
277 .\" @buf_putmem16l
278 .\" @buf_putmem24
279 .\" @buf_putmem24b
280 .\" @buf_putmem24l
281 .\" @buf_putmem32
282 .\" @buf_putmem32b
283 .\" @buf_putmem32l
284 .\" @buf_putmem64
285 .\" @buf_putmem64b
286 .\" @buf_putmem64l
287 .\" @buf_putmemz
288 .\" @dbuf_putmem8
289 .\" @dbuf_putmem16
290 .\" @dbuf_putmem16b
291 .\" @dbuf_putmem16l
292 .\" @dbuf_putmem24
293 .\" @dbuf_putmem24b
294 .\" @dbuf_putmem24l
295 .\" @dbuf_putmem32
296 .\" @dbuf_putmem32b
297 .\" @dbuf_putmem32l
298 .\" @dbuf_putmem64
299 .\" @dbuf_putmem64b
300 .\" @dbuf_putmem64l
301 .\" @dbuf_putmemz
302 .
303 .\" @buf_putstr8
304 .\" @buf_putstr16
305 .\" @buf_putstr16b
306 .\" @buf_putstr16l
307 .\" @buf_putstr24
308 .\" @buf_putstr24b
309 .\" @buf_putstr24l
310 .\" @buf_putstr32
311 .\" @buf_putstr32b
312 .\" @buf_putstr32l
313 .\" @buf_putstr64
314 .\" @buf_putstr64b
315 .\" @buf_putstr64l
316 .\" @buf_putstrz
317 .\" @dbuf_putstr8
318 .\" @dbuf_putstr16
319 .\" @dbuf_putstr16b
320 .\" @dbuf_putstr16l
321 .\" @dbuf_putstr24
322 .\" @dbuf_putstr24b
323 .\" @dbuf_putstr24l
324 .\" @dbuf_putstr32
325 .\" @dbuf_putstr32b
326 .\" @dbuf_putstr32l
327 .\" @dbuf_putstr64
328 .\" @dbuf_putstr64b
329 .\" @dbuf_putstr64l
330 .\" @dbuf_putstrz
331 .
332 .\" @buf_getdstr8
333 .\" @buf_getdstr16
334 .\" @buf_getdstr16b
335 .\" @buf_getdstr16l
336 .\" @buf_getdstr24
337 .\" @buf_getdstr24b
338 .\" @buf_getdstr24l
339 .\" @buf_getdstr32
340 .\" @buf_getdstr32b
341 .\" @buf_getdstr32l
342 .\" @buf_getdstr64
343 .\" @buf_getdstr64b
344 .\" @buf_getdstr64l
345 .\" @buf_getdstrz
346 .\" @dbuf_getdstr8
347 .\" @dbuf_getdstr16
348 .\" @dbuf_getdstr16b
349 .\" @dbuf_getdstr16l
350 .\" @dbuf_getdstr24
351 .\" @dbuf_getdstr24b
352 .\" @dbuf_getdstr24l
353 .\" @dbuf_getdstr32
354 .\" @dbuf_getdstr32b
355 .\" @dbuf_getdstr32l
356 .\" @dbuf_getdstr64
357 .\" @dbuf_getdstr64b
358 .\" @dbuf_getdstr64l
359 .\" @dbuf_getdstrz
360 .
361 .\" @buf_putdstr8
362 .\" @buf_putdstr16
363 .\" @buf_putdstr16b
364 .\" @buf_putdstr16l
365 .\" @buf_putdstr24
366 .\" @buf_putdstr24b
367 .\" @buf_putdstr24l
368 .\" @buf_putdstr32
369 .\" @buf_putdstr32b
370 .\" @buf_putdstr32l
371 .\" @buf_putdstr64
372 .\" @buf_putdstr64b
373 .\" @buf_putdstr64l
374 .\" @buf_putdstrz
375 .\" @dbuf_putdstr8
376 .\" @dbuf_putdstr16
377 .\" @dbuf_putdstr16b
378 .\" @dbuf_putdstr16l
379 .\" @dbuf_putdstr24
380 .\" @dbuf_putdstr24b
381 .\" @dbuf_putdstr24l
382 .\" @dbuf_putdstr32
383 .\" @dbuf_putdstr32b
384 .\" @dbuf_putdstr32l
385 .\" @dbuf_putdstr64
386 .\" @dbuf_putdstr64b
387 .\" @dbuf_putdstr64l
388 .\" @dbuf_putdstrz
389 .
390 .\" @buf_putstrf8
391 .\" @buf_putstrf16
392 .\" @buf_putstrf16b
393 .\" @buf_putstrf16l
394 .\" @buf_putstrf24
395 .\" @buf_putstrf24b
396 .\" @buf_putstrf24l
397 .\" @buf_putstrf32
398 .\" @buf_putstrf32b
399 .\" @buf_putstrf32l
400 .\" @buf_putstrf64
401 .\" @buf_putstrf64b
402 .\" @buf_putstrf64l
403 .\" @buf_putstrfz
404 .\" @buf_vputstrf8
405 .\" @buf_vputstrf16
406 .\" @buf_vputstrf16b
407 .\" @buf_vputstrf16l
408 .\" @buf_vputstrf24
409 .\" @buf_vputstrf24b
410 .\" @buf_vputstrf24l
411 .\" @buf_vputstrf32
412 .\" @buf_vputstrf32b
413 .\" @buf_vputstrf32l
414 .\" @buf_vputstrf64
415 .\" @buf_vputstrf64b
416 .\" @buf_vputstrf64l
417 .\" @buf_vputstrfz
418 .\" @dbuf_putstrf8
419 .\" @dbuf_putstrf16
420 .\" @dbuf_putstrf16b
421 .\" @dbuf_putstrf16l
422 .\" @dbuf_putstrf24
423 .\" @dbuf_putstrf24b
424 .\" @dbuf_putstrf24l
425 .\" @dbuf_putstrf32
426 .\" @dbuf_putstrf32b
427 .\" @dbuf_putstrf32l
428 .\" @dbuf_putstrf64
429 .\" @dbuf_putstrf64b
430 .\" @dbuf_putstrf64l
431 .\" @dbuf_putstrfz
432 .\" @dbuf_vputstrf8
433 .\" @dbuf_vputstrf16
434 .\" @dbuf_vputstrf16b
435 .\" @dbuf_vputstrf16l
436 .\" @dbuf_vputstrf24
437 .\" @dbuf_vputstrf24b
438 .\" @dbuf_vputstrf24l
439 .\" @dbuf_vputstrf32
440 .\" @dbuf_vputstrf32b
441 .\" @dbuf_vputstrf32l
442 .\" @dbuf_vputstrf64
443 .\" @dbuf_vputstrf64b
444 .\" @dbuf_vputstrf64l
445 .\" @dbuf_vputstrfz
446 .
447 .\" @BUF_ENCLOSETAG
448 .\" @BUF_ENCLOSEITAG
449 .\" @BUF_ENCLOSEKTAG
450 .\" @BUF_ENCLOSEZTAG
451 .\" @BUF_ENCLOSE8
452 .\" @BUF_ENCLOSE16
453 .\" @BUF_ENCLOSE16_L
454 .\" @BUF_ENCLOSE16_B
455 .\" @BUF_ENCLOSE24
456 .\" @BUF_ENCLOSE24_L
457 .\" @BUF_ENCLOSE24_B
458 .\" @BUF_ENCLOSE32
459 .\" @BUF_ENCLOSE32_L
460 .\" @BUF_ENCLOSE32_B
461 .\" @BUF_ENCLOSE64
462 .\" @BUF_ENCLOSE64_L
463 .\" @BUF_ENCLOSE64_B
464 .\" @BUF_ENCLOSEZ
465 .\" @DBUF_ENCLOSETAG
466 .\" @DBUF_ENCLOSEITAG
467 .\" @DBUF_ENCLOSEKTAG
468 .\" @DBUF_ENCLOSEZTAG
469 .\" @DBUF_ENCLOSE8
470 .\" @DBUF_ENCLOSE16
471 .\" @DBUF_ENCLOSE16_L
472 .\" @DBUF_ENCLOSE16_B
473 .\" @DBUF_ENCLOSE24
474 .\" @DBUF_ENCLOSE24_L
475 .\" @DBUF_ENCLOSE24_B
476 .\" @DBUF_ENCLOSE32
477 .\" @DBUF_ENCLOSE32_L
478 .\" @DBUF_ENCLOSE32_B
479 .\" @DBUF_ENCLOSE64
480 .\" @DBUF_ENCLOSE64_L
481 .\" @DBUF_ENCLOSE64_B
482 .\" @DBUF_ENCLOSEZ
483 .
484 .\"--------------------------------------------------------------------------
485 .SH NAME
486 buf \- reading and writing stuff in buffers
487 .
488 .\"--------------------------------------------------------------------------
489 .SH SYNOPSIS
490 .
491 .nf
492 .B "#include <mLib/dstr.h>"
493 .PP
494 .B "typedef struct { ...\& } buf;"
495 .B "typedef struct { ...\& } dbuf;"
496 .PP
497 .BI "void buf_init(buf *" b ", void *" p ", size_t " sz );
498 .BI "void dbuf_create(dbuf *" db );
499 .BI "void dbuf_reset(dbuf *" db );
500 .BI "void dbuf_destroy(dbuf *" db );
501 .BI "buf *DBUF_BUF(dbuf *" db );
502 .BI "void DBCREATE(dbuf *" db );
503 .BI "void DBRESET(dbuf *" db );
504 .BI "void DBDESTROY(dbuf *" db );
505 .B "#define DBUF_INIT ..."
506 .PP
507 .fi
508 All of the following functions and macros exist in two variants:
509 one with a name beginning
510 .BR buf_ ,
511 .BR B ,
512 or
513 .BR BUF_ ,
514 and taking a first argument of type
515 .BR "buf *" ;
516 and a corresponding similarly named version with name beginning instead
517 .BR dbuf_ ,
518 .BR DB ,
519 or
520 .BR DBUF_ ,
521 and taking a first argument of type
522 .BR "dbuf *" .
523 .nf
524 .PP
525 .BI "void buf_flip(buf *" b );
526 .BI "octet *BBASE(buf *" b );
527 .BI "octet *BLIM(buf *" b );
528 .BI "octet *BCUR(buf *" b );
529 .BI "ptrdiff_t BSZ(buf *" b );
530 .BI "ptrdiff_t BLEN(buf *" b );
531 .BI "ptrdiff_t BLEFT(buf *" b );
532 .BI "void BFLIP(buf *" b );
533 .PP
534 .BI "int buf_break(buf *" b );
535 .BI "int BBREAK(buf *" b );
536 .BI "int BBAD(buf *" b );
537 .BI "int BOK(buf *" b );
538 .PP
539 .BI "int buf_ensure(buf *" b ", size_t " sz );
540 .BI "int buf_tryextend(buf *" b ", size_t " sz );
541 .BI "int BENSURE(buf *" b ", size_t " sz );
542 .BI "octet *BSTEP(buf *" b ", size_t " sz );
543 .PP
544 .BI "void *buf_get(buf *" b ", size_t " sz );
545 .BI "int buf_put(buf *" b ", const void *" p ", size_t " sz );
546 .BI "int buf_fill(buf *" b ", int " ch ", size_t " sz );
547 .PP
548 .BI "int buf_alignskip(buf *" b ", size_t " m ", size_t " a );
549 .BI "int buf_alignfill(buf *" b ", int " ch ", size_t " m ", size_t " a );
550 .PP
551 .BI "int buf_getbyte(buf *" b );
552 .BI "int buf_putbyte(buf *" b ", int " ch );
553 .PP
554 .BI "int buf_putstr(buf *" b ", const char *" p ", ...);"
555 .BI "int buf_vputstr(buf *" b ", const char *" p ", va_list *" ap );
556 .PP
557 .fi
558 For
559 .I suff
560 in
561 .BR 8 ,
562 .BR 16 ,
563 .BR 16l ,
564 .BR 16b ,
565 .BR 24 ,
566 .BR 24l ,
567 .BR 24b ,
568 .BR 32 ,
569 .BR 32l ,
570 and
571 .BR 32b ,
572 and, if a 64-bit integer type is available,
573 .BR 64 ,
574 .BR 64l ,
575 and
576 .BR 64b :
577 .nf
578 .BI "int buf_putu" suff "(buf *" b ", uint" suff " " w );
579 .BI "int buf_getu" suff "(buf *" b ", uint" suff " *" w );
580 .PP
581 .fi
582 For
583 .I suff
584 in
585 .BR 64 ,
586 .BR 64l ,
587 and
588 .BR 64b :
589 .nf
590 .BI "int buf_putk" suff "(buf *" b ", kludge64 " w );
591 .BI "int buf_getk" suff "(buf *" b ", kludge64 *" w );
592 .PP
593 .BI "int buf_getf32(buf *" b ", float " x );
594 .BI "int buf_getf32l(buf *" b ", float " x );
595 .BI "int buf_getf32b(buf *" b ", float " x );
596 .BI "int buf_getf64(buf *" b ", double " x );
597 .BI "int buf_getf64l(buf *" b ", double " x );
598 .BI "int buf_getf64b(buf *" b ", double " x );
599 .BI "int buf_putf32(buf *" b ", float *" x_out );
600 .BI "int buf_putf32l(buf *" b ", float *" x_out );
601 .BI "int buf_putf32b(buf *" b ", float *" x_out );
602 .BI "int buf_putf64(buf *" b ", double *" x_out );
603 .BI "int buf_putf64l(buf *" b ", double *" x_out );
604 .BI "int buf_putf64b(buf *" b ", double *" x_out );
605 .PP
606 .ta 2n
607 .BI "BUF_ENCLOSETAG(" tag ", buf *" b ", size_t " mk ", " check ", " poke ", size_t " lensz )
608 .I "    body"
609 .BI "BUF_ENCLOSEITAG(" tag ", buf *" b ", size_t " mk ", " W )
610 .I "    body"
611 .BI "BUF_ENCLOSEKTAG(" tag ", buf *" b ", size_t " mk ", " W )
612 .I "    body"
613 .BI "BUF_ENCLOSEZTAG(" tag ", buf *" b )
614 .I "    body"
615 .PP
616 .fi
617 For
618 .I suff
619 in
620 .BR 8 ,
621 .BR 16 ,
622 .BR 16_L ,
623 .BR 16_B ,
624 .BR 24 ,
625 .BR 24_L ,
626 .BR 24_B ,
627 .BR 32 ,
628 .BR 32_L ,
629 .BR 32_B ,
630 .BR 64 ,
631 .BR 64_L ,
632 and
633 .BR 64_B ,
634 .nf
635 .ta 2n
636 .BI "BUF_ENCLOSE" suff "(buf *" b ", size_t " mk )
637 .I "    body"
638 .PP
639 .BI "BUF_ENCLOSEZ(buf *" b )
640 .I "    body"
641 .PP
642 .fi
643 For
644 .I suff
645 in
646 .BR 8 ,
647 .BR 16 ,
648 .BR 16l ,
649 .BR 16b ,
650 .BR 24 ,
651 .BR 24l ,
652 .BR 24b ,
653 .BR 32 ,
654 .BR 32l ,
655 .BR 32b ,
656 .BR 64 ,
657 .BR 64l ,
658 .BR 64b ,
659 and
660 .BR z :
661 .nf
662 .BI "int buf_putstr" suff "(buf *" b ", const char *" p );
663 .BI "int buf_putstr" suff "(buf *" b ", const char *" p ", ...);"
664 .BI "int buf_vputstr" suff "(buf *" b ", const char *" p ", va_list *" ap );
665 .BI "int buf_putdstr" suff "(buf *" b ", dstr *" d );
666 .BI "int buf_getdstr" suff "(buf *" b ", dstr *" d );
667 .BI "int buf_putbuf" suff "(buf *" b ", buf *" bb );
668 .BI "int buf_getbuf" suff "(buf *" b ", buf *" bb );
669 .BI "int buf_putmem" suff "(buf *" b ", const void *" p ", size_t " sz );
670 .BI "void *buf_getmem" suff "(buf *" b ", size_t *" sz );
671 .PP
672 .fi
673 For
674 .I suff
675 in
676 .BR 64 ,
677 .BR 64l ,
678 and
679 .BR 64b :
680 .nf
681 .BI "int buf_putf" suff "(buf *" b ", double " x );
682 .BI "int buf_getf" suff "(buf *" b ", double *" x );
683 .fi
684 .
685 .\"--------------------------------------------------------------------------
686 .SH DESCRIPTION
687 The
688 .B buf
689 interface allows relatively convenient reading and writing of structured
690 binary data from and to fixed-size memory buffers.  It's useful for
691 formatting and parsing down network data packets, for example.
692 .
693 .SS "Buffer basics"
694 A buffer has three important pointers associated with it:
695 .TP
696 .I base
697 The base address of the buffer.
698 .TP
699 .I limit
700 Just past the last usable byte in the buffer
701 .TP
702 .I current
703 The position in the buffer at which the next read or write will occur.
704 .PP
705 A buffer is created using the
706 .B buf_init
707 function.  You must pass it the buffer base address and size, and a
708 pointer to a
709 .B buf
710 structure to fill in.  It doesn't allocate any memory, so you don't need
711 to dispose of the
712 .B buf
713 structure in any way before forgetting about it.
714 .PP
715 A collection of macros is provided for finding the positions of the
716 various interesting pointers known about a buffer, and the sizes of the
717 regions of memory they imply.
718 .TP
719 .B BBASE
720 The buffer's
721 .I base
722 pointer.
723 .TP
724 .B BLIM
725 The buffer's
726 .I limit
727 pointer.
728 .TP
729 .B BCUR
730 The buffer's
731 .I current
732 pointer.
733 .TP
734 .B BSZ
735 The size of the buffer; i.e.,
736 .I limit
737 \-
738 .IR base .
739 .TP
740 .B BLEN
741 The length of data in the buffer (if writing) or the amount of data
742 read (if reading); i.e.,
743 .I current
744 \-
745 .IR base .
746 .TP
747 .B BLEFT
748 The amount of space left in the buffer (if writing) or the amount of
749 data yet to read (if reading); i.e.,
750 .I limit
751 \-
752 .IR current .
753 .PP
754 The function
755 .B buf_flip
756 takes a buffer which has been used for writing, and makes it suitable
757 for reading.  This turns out to be useful when building packets in
758 multi-layered networking software.  Its precise behaviour is to preserve
759 .IR base ,
760 to set
761 .I limit
762 to
763 .IR current ,
764 and to set
765 .I current
766 to
767 .IR base .
768 There is a macro version,
769 .BR BFLIP ,
770 which does the same thing,
771 but it may evaluate its buffer argument multiple times.
772 .PP
773 A buffer can be
774 .IR broken ,
775 to indicate that it has overflowed or that its contents are otherwise
776 invalid.  The various buffer access functions described below all fail
777 on a broken buffer, and any errors they encounter cause the buffer to
778 become broken.  Most simple programs which only use the supplied buffer
779 access functions can avoid the tedium of error-checking every function
780 call and just check the brokenness state at the end of their run.
781 .PP
782 The function
783 .B buf_break
784 or its
785 macro equivalent
786 .B BBREAK
787 will break a buffer:
788 the function returns \-1 as a possible, but minor, convenience;
789 the macro expands to a statement and cannot return a value.
790 The macro
791 .B BBAD
792 reports true (nonzero) if its buffer argument is broken, or false (zero)
793 otherwise; its counterpart
794 .B BOK
795 reports true if the buffer is OK, and false if it is broken.
796 .
797 .SS "Low-level buffer access"
798 Access to the data in the buffer is usually sequential.  The
799 .B BENSURE
800 macro (or the equivalent
801 .B buf_ensure
802 function) checks that the buffer is OK and that there is enough space
803 remaining in the buffer for
804 .I sz
805 bytes: if so, it returns zero; otherwise it breaks the buffer and
806 returns \-1.
807 .PP
808 The
809 .B BSTEP
810 macro advances the buffer's
811 .I current
812 pointer by
813 .I sz
814 bytes.  It does no bounds checking.  Together with
815 .BR BENSURE ,
816 this provides sequential access to the buffer's contents.
817 .PP
818 The
819 .B buf_get
820 function is the basis of most buffer access functions, whether for
821 reading or writing.  If the buffer is OK, and there are
822 .I sz
823 or more bytes remaining, it steps the buffer's
824 .I current
825 pointer by
826 .I sz
827 and returns the
828 .I original
829 (pre-stepping)
830 .I current
831 pointer; otherwise it breaks the buffer if necessary, and returns a null
832 pointer.
833 .PP
834 The
835 .B buf_put
836 function writes
837 .I sz
838 bytes of data starting at
839 .I p
840 to the buffer.  If it succeeded, it returns 0; otherwise it returns \-1.
841 .PP
842 The
843 .B buf_fill
844 function writes
845 .I sz
846 copies of the byte
847 .I ch
848 to the buffer, as if by calling
849 .BR memset (3).
850 If it succeeds, it returns 0; otherwise it returns \-1.
851 .PP
852 The
853 .B buf_alignskip
854 function advances the buffer's position as little as possible,
855 so as to cause the position to be
856 .I a
857 bytes more than a multiple of
858 .IR m .
859 If
860 .I m
861 is zero then nothing is done.
862 The buffer contents are not altered.
863 The related
864 .B buf_alignfill
865 function is similar, except that it advances the buffer position by writing
866 copies of the byte
867 .IR ch ,
868 as if by calling
869 .BR memset (3).
870 Use
871 .B buf_alignskip
872 for input and
873 .B buf_alignfill
874 for output.
875 .
876 .SS "Formatted buffer access"
877 The function
878 .B buf_getbyte
879 returns the next byte from a buffer as a nonnegative integer, or \-1 on
880 error.  The function
881 .B buf_putbyte
882 writes its argument to a buffer, and returns 0 on succes; it returns \-1
883 if it failed.
884 .PP
885 Many of the remaining functions deal with integer formatting and buffer
886 lengths.  The functions support 8-, 16-, 24- and 32-bit integers, in
887 big- or little-endian order; on platforms with 64-bit integers, these
888 are supported too.  The functions' names carry a suffix which is the
889 width in bits of the integers they deal with and an optional
890 .RB ` l '
891 for little- or
892 .RB ` b '
893 for big-endian byte order.  (The variant with no letter uses big-endian
894 order.  Use of these variants tends to mean `I don't really care, but be
895 consistent,' and is not recommended if you have an externally-defined
896 spec you're meant to be compatible with.)
897 .PP
898 The function
899 .BI buf_getu suff
900 reads an integer.  On success, it stores the integer it read at the
901 address
902 .I w
903 given, and returns zero; on failure, it returns \-1.  The function
904 .BI buf_putu suff
905 write an integer.  It returns zero on success or \-1 on failure.
906 .PP
907 For (portability to) platforms without 64-bit integers, the functions
908 .B buf_getk64
909 and
910 .B buf_putk64
911 (and
912 .RB ` l '-
913 and
914 .RB ` b '-suffixed
915 variants) perform the necessary functionality, but acting on the
916 .B kludge64
917 type; see
918 .BR bits (3).
919 .PP
920 The functions
921 .BR buf_getf32 ,
922 .BR buf_getf32l ,
923 and
924 .BR buf_getf32b ,
925 and
926 .BR buf_getf64 ,
927 .BR buf_getf64l ,
928 and
929 .BR buf_getf64b ,
930 read floating-point values
931 in IEEE\ 754 Binary32 and Binary64 format
932 from the buffer;
933 as usual, the suffix indicates the format and byte ordering convention.
934 On success, they store the result in
935 .BI *x
936 and return zero;
937 on failure, they break the buffer and return zero.
938 The functions
939 .BR buf_putf32 ,
940 .BR buf_putf32l ,
941 and
942 .BR buf_putf32b ,
943 and
944 .BR buf_putf64 ,
945 .BR buf_putf64l ,
946 and
947 .BR buf_putf64b
948 write floating-point numbers
949 in IEEE\ 754 Binary32 and Binary64 format
950 from the buffer.
951 On success, they return zero; on failure, they return \-1.
952 Note that these functions use IEEE\ 754 format
953 even if this is not the platform-native floating-point representation:
954 they use the
955 .BR fltfmt (3)
956 functions to do their work.
957 Specifically,
958 they use the
959 .B FLTRND_NEAREVEN
960 rounding convention,
961 and they ignore
962 .BR FLTERR_INEXACT ,
963 .BR FLTERR_UFLOW ,
964 and
965 .B FLTERR_OFLOW
966 errors,
967 and fail on
968 .B FLTERR_INVAL
969 and
970 .B FLTERR_REPR
971 errors.
972 If more subtle control over error handling is necessary,
973 use the
974 .BR fltfmt (3)
975 functions directly.
976 .PP
977 The function
978 .B buf_putstrf
979 processes a
980 .BR printf (3)-like
981 format string and arguments,
982 writing the output to the buffer.
983 The function
984 .B buf_vputstrf
985 does the same,
986 except that it reads arguments from a
987 .B va_list
988 captured argument tail,
989 leaving the tail ready to read the next unprocessed argument.
990 Both functions return the number of bytes written on success
991 or \-1 on failure.
992 Note that these functions apply no length framing or termination.
993 They are implemented using
994 .BR gprintf (3);
995 the output operations table is exposed as
996 .BR buf_printops ;
997 the functions expect the output pointer to be the address of the output
998 .BR buf .
999 .PP
1000 Functions which deal with block lengths assume the length is prefixed to
1001 the data, and don't include themselves.  They come in all of the integer
1002 size variants, including 64-bits even on platforms without 64-bit integers;
1003 they also have an additional
1004 .RB ` z '
1005 variant, which deals with zero-terminated data.  No checks are done on
1006 writing that the data written contains no zero bytes.
1007 .PP
1008 The function
1009 .BI buf_getmem suff
1010 fetches a block of data.  On success, it returns its base address and
1011 stores its length at the given address; on failure, it returns null.
1012 The function
1013 .BI buf_putmem suff
1014 writes a block of data; it return zero on success or \-1 on failure.
1015 .PP
1016 The functon
1017 .BI buf_getbuf suff
1018 fetches a block of data and makes a second buffer point to it, i.e.,
1019 setting its
1020 .I base
1021 and
1022 .I current
1023 pointers to the start of the block and its
1024 .I limit
1025 pointer to just past the end.  No copying of bulk data is performed.
1026 The function
1027 .BI buf_putbuf suff
1028 writes the contents of a buffer (i.e., between its
1029 .I base
1030 and
1031 .I current
1032 pointers).  The function
1033 .BI buf_getdstr suff
1034 fetches a block of data and append it to a dynamic string (see
1035 .BR dstr (3)).
1036 The function
1037 .BI buf_putdstr suff
1038 writes the contents of a dynamic string to a buffer.  Finally, the
1039 function
1040 .BI buf_putstr suff
1041 writes a standard C null-terminated string to a buffer.  All these
1042 functions return zero on success or \-1 on failure.
1043 .PP
1044 The function
1045 .BI buf_putstrf suff
1046 processes a
1047 .BR printf (3)-like
1048 format string and arguments,
1049 writing the output to the buffer.
1050 The function
1051 .BI buf_vputstrf suff
1052 does the same,
1053 except that it reads arguments from a
1054 .B va_list
1055 captured argument tail,
1056 leaving the tail ready to read the next unprocessed argument.
1057 Both functions return the number of bytes written on success
1058 or \-1 on failure.
1059 These functions add framing around the output:
1060 either a length prefix, or a trailing zero byte.
1061 .PP
1062 The
1063 .BI BUF_ENCLOSE suff
1064 macros are syntactically statement heads.
1065 (Notice that these macros use
1066 .RB ` _L '
1067 and
1068 .RB ` _B '
1069 suffixes for little- and big-endian byte order.)
1070 They leave space in the buffer for appropriate length framing,
1071 and execute the following
1072 .I body
1073 statement
1074 (which, of course, can be a compound statement enclosed in braces).
1075 When the
1076 .I body
1077 completes, the macro fills in space
1078 with the length of material written by the
1079 .IR body .
1080 The
1081 .I mk
1082 argument should be a variable of type
1083 .B size_t
1084 which will be overwritten by the macro.
1085 If the material is so large that its won't fit in the space
1086 then the buffer is broken.
1087 The
1088 .B BUF_ENCLOSEZ
1089 macro is similar,
1090 except that it just writes a terminating zero byte
1091 after whatever material was written by the
1092 .IR body .
1093 .PP
1094 The
1095 .BR BUF_ENCLOSE ...\&
1096 macros are based on lower-level machinery.
1097 The
1098 .B BUF_ENCLOSEITAG
1099 macro takes an additional argument
1100 .IR W ;
1101 it leaves
1102 .BI SZ_ W
1103 bytes for the length,
1104 checks that the length doesn't exceed
1105 .BI MASK W \fR,
1106 and stores the length using
1107 .BI STORE W \fR;
1108 all of these constants and macros are defined in
1109 .BR <mLib/bits.h> .
1110 The
1111 .B BUF_ENCLOSEKTAG
1112 is similar, except that it uses the
1113 .B kludge64
1114 machinery to handle 64-bit length fields.
1115 The
1116 .B BUF_ENCLOSEZTAG
1117 macro is superficially similar,
1118 but much simpler,
1119 since it all it does is write a zero byte after its
1120 .I body
1121 completes.
1122 All of those macros also take an additional
1123 .I tag
1124 argument
1125 used to scope the internal labels they construct:
1126 see
1127 .BR control (3)
1128 for the details on how this works.
1129 .PP
1130 The
1131 .B BUF_ENCLOSEITAG
1132 and
1133 .B BUF_ENCLOSEKTAG
1134 macros are themselves built from a lower-level macro named
1135 .BR BUF_ENCLOSETAG .
1136 In place of the
1137 .I W
1138 argument, it takes three arguments:
1139 .I check
1140 is an expression which should evaluate true if the length
1141 .B _delta
1142 can be represented;
1143 .I poke
1144 is a macro, invoked as
1145 .IB poke "(unsigned char *" p ", " size_t n ")" \fR,
1146 which should store
1147 .I n
1148 at address
1149 .IR p ,
1150 formatted in whatever way is appropriate;
1151 and
1152 .I lensz
1153 is the amount of space, in bytes, to save for the length.
1154 .
1155 .SS "Dynamic buffers"
1156 The type
1157 .B dbuf
1158 is a
1159 .IR "dynamic buffer" .
1160 It contains a buffer structure,
1161 accessible using the
1162 p.B DBUF_BUF
1163 macro.
1164 The ordinary buffer functions and macros can be used on this buffer,
1165 though, for convenience,
1166 there are similarly named functions and macros
1167 which accept a
1168 .B dbuf
1169 argument directly.
1170 There is
1171 .I "no difference"
1172 between the behaviour of the
1173 .B "buf"
1174 and
1175 .B "dbuf"
1176 functions.
1177 .PP
1178 A dynamic buffer is created by statically initializing it with
1179 .BR DBUF_INIT ,
1180 or by calling
1181 .BR dbuf_create
1182 or its macro equivalent
1183 .BR DBCREATE .
1184 The memory backing a dynamic buffer can be freed by
1185 .BR dbuf_destroy
1186 or the macro equivalent
1187 .BR DBDESTROY ;
1188 these leave the buffer in the state established by initialization:
1189 the buffer holds no resources, but is ready for immediate use.
1190 .PP
1191 A dynamic buffer contains a
1192 .B buf
1193 buffer,
1194 called its
1195 .I underlying
1196 buffer.
1197 The underlying buffer is accessible through the
1198 .B DBUF_BUF
1199 macro.
1200 All of the above functions and macros can be applied
1201 to a dynamic buffer's underlying buffer.
1202 As a convenience,
1203 corresponding to each of the functions and macros described above,
1204 there is a version named with an initial
1205 .RB ` d '
1206 or
1207 .RB ` D '
1208 as appropriate,
1209 which accepts a pointer to a dynamic buffer
1210 rather than an ordinary buffer,
1211 and acts on its underlying buffer.
1212 Note that these functions are in no way special.
1213 A dynamic buffer will grow automatically
1214 in response to either kind of functions.
1215 .PP
1216 A freshly created buffer is in
1217 .I write
1218 mode,
1219 and is empty, with.
1220 In this state, it will automatically extend its backing storage
1221 in response to
1222 .B BENSURE
1223 calls, rather than breaking.
1224 As a result,
1225 an
1226 .I "a priori"
1227 unpredictable amount of data can be written to a dynamic buffer
1228 and it will automatically grow as necessary to accommodate it.
1229 Of course, the
1230 .B BSZ
1231 and
1232 .B BLEFT
1233 queries are somewhat meaningless when applied to dynamic buffers \(en
1234 though perfectly valid.
1235 The critical function for this is
1236 .B buf_tryextend
1237 (also accessible as
1238 .BR dbuf_tryextend )
1239 which attempts to arrange that at least
1240 .I sz
1241 unused bytes are available in the buffer \(en
1242 i.e., that
1243 .B BLEFT
1244 would return at least
1245 .IR sz .
1246 If it succeeds, it returns zero;
1247 it will fail if the buffer is not in write mode,
1248 or if the buffer is not dynamic,
1249 in which case it returns \-1.
1250 It is unlikely that applications will call this function directly.
1251 .PP
1252 The
1253 .B buf_flip
1254 (or its macro equivalent)
1255 switches the buffer to
1256 .I read
1257 mode,
1258 in addition to its usual behaviour of
1259 setting the buffer's limit to its current position
1260 and its current position to its base.
1261 In read mode, a dynamic buffer will no longer grow dynamically,
1262 as one would expect.
1263 .PP
1264 The
1265 .B dbuf_reset
1266 function,
1267 and its macro equivalent
1268 .B DBRESET
1269 (which may evaluate its argument multiple times)
1270 will return a dynamic buffer to write mode,
1271 and also restore its current position to its base and
1272 clear its broken flag.
1273 .
1274 .\"--------------------------------------------------------------------------
1275 .SH "SEE ALSO"
1276 .
1277 .BR bits (3),
1278 .BR control (3),
1279 .BR dstr (3),
1280 .BR fltfmt (3),
1281 .BR gprintf (3),
1282 .BR mLib (3).
1283 .
1284 .\"--------------------------------------------------------------------------
1285 .SH AUTHOR
1286 .
1287 Mark Wooding, <mdw@distorted.org.uk>
1288 .
1289 .\"----- That's all, folks --------------------------------------------------