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