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