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