@@@ much mess, mostly manpages
[mLib] / struct / buf.3.in
CommitLineData
9b5ac6ff 1.\" -*-nroff-*-
c4ccbbf9
MW
2.\"
3.\" Manual for buffer handling
4.\"
5.\" (c) 2005, 2007, 2009, 2017, 2023, 2024 Straylight/Edgeware
6.\"
adec5584 7.
c4ccbbf9
MW
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.
adec5584 26.
c4ccbbf9
MW
27.\"--------------------------------------------------------------------------
28.so ../defs.man \" @@@PRE@@@
29.
30.\"--------------------------------------------------------------------------
31.TH buf 3mLib "23 September 2005" "Straylight/Edgeware" "mLib utilities library"
9b5ac6ff 32.\" @BBASE
33.\" @BLIM
34.\" @BCUR
35.\" @BSZ
36.\" @BLEN
37.\" @BLEFT
38.\" @BSTEP
39.\" @BBAD
40.\" @BOK
41.\" @BENSURE
d056fbdf 42.
adec5584
MW
43.\" @DBBASE
44.\" @DBLIM
45.\" @DBCUR
46.\" @DBSZ
47.\" @DBLEN
48.\" @DBLEFT
49.\" @DBSTEP
50.\" @DBBAD
51.\" @DBOK
52.\" @DBENSURE
9b5ac6ff 53.
54.\" @buf_init
adec5584
MW
55.
56.\" @dbuf_create
57.\" @dbuf_reset
58.\" @dbuf_destroy
59.\" @DBCREATE
60.\" @DBRESET
61.\" @DBDESTROY
62.\" @DBUF_INIT
63.\" @DBUF_BUF
64.
9b5ac6ff 65.\" @buf_break
66.\" @buf_flip
67.\" @buf_ensure
adec5584 68.\" @buf_tryextend
9b5ac6ff 69.\" @buf_get
70.\" @buf_put
adec5584
MW
71.\" @dbuf_break
72.\" @dbuf_flip
73.\" @dbuf_ensure
74.\" @dbuf_tryextend
75.\" @dbuf_get
76.\" @dbuf_put
9b5ac6ff 77.
78.\" @buf_getbyte
79.\" @buf_putbyte
adec5584
MW
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
c4ccbbf9 100.\" @buf_printops
9b5ac6ff 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
adec5584
MW
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
9b5ac6ff 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
adec5584
MW
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
9b5ac6ff 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
adec5584
MW
178.\" @buf_getbuf64
179.\" @buf_getbuf64b
180.\" @buf_getbuf64l
9b5ac6ff 181.\" @buf_getbufz
adec5584
MW
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
9b5ac6ff 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
adec5584
MW
207.\" @buf_putbuf64
208.\" @buf_putbuf64b
209.\" @buf_putbuf64l
9b5ac6ff 210.\" @buf_putbufz
adec5584
MW
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
9b5ac6ff 225.
adec5584 226.\" @buf_getmem8
9b5ac6ff 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
adec5584
MW
236.\" @buf_getmem64
237.\" @buf_getmem64b
238.\" @buf_getmem64l
9b5ac6ff 239.\" @buf_getmemz
adec5584
MW
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
9b5ac6ff 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
adec5584
MW
265.\" @buf_putmem64
266.\" @buf_putmem64b
267.\" @buf_putmem64l
9b5ac6ff 268.\" @buf_putmemz
adec5584
MW
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
9b5ac6ff 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
adec5584
MW
294.\" @buf_putstr64
295.\" @buf_putstr64b
296.\" @buf_putstr64l
9b5ac6ff 297.\" @buf_putstrz
adec5584
MW
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
9b5ac6ff 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
adec5584
MW
323.\" @buf_getdstr64
324.\" @buf_getdstr64b
325.\" @buf_getdstr64l
9b5ac6ff 326.\" @buf_getdstrz
adec5584
MW
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
9b5ac6ff 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
adec5584
MW
352.\" @buf_putdstr64
353.\" @buf_putdstr64b
354.\" @buf_putdstr64l
9b5ac6ff 355.\" @buf_putdstrz
adec5584
MW
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.
c4ccbbf9
MW
465.\"--------------------------------------------------------------------------
466.SH NAME
467buf \- reading and writing stuff in buffers
468.
469.\"--------------------------------------------------------------------------
9b5ac6ff 470.SH SYNOPSIS
c4ccbbf9 471.
9b5ac6ff 472.nf
473.B "#include <mLib/dstr.h>"
d056fbdf 474.PP
4729aa69 475.B "typedef struct { ...\& } buf;"
adec5584 476.B "typedef struct { ...\& } dbuf;"
d056fbdf 477.PP
9b5ac6ff 478.BI "void buf_init(buf *" b ", void *" p ", size_t " sz );
adec5584
MW
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 ..."
d056fbdf 487.PP
adec5584
MW
488.fi
489All of the following functions and macros exist in two variants:
490one with a name beginning
491.BR buf_ ,
492.BR B ,
493or
494.BR BUF_ ,
495and taking a first argument of type
496.BR "buf *" ;
497and a corresponding similarly named version with name beginning instead
498.BR dbuf_ ,
499.BR DB ,
500or
501.BR DBUF_ ,
502and taking a first argument of type
503.BR "dbuf *" .
504.nf
d056fbdf 505.PP
9b5ac6ff 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 );
adec5584 513.BI "void BFLIP(buf *" b );
d056fbdf 514.PP
9b5ac6ff 515.BI "int buf_break(buf *" b );
adec5584 516.BI "int BBREAK(buf *" b );
9b5ac6ff 517.BI "int BBAD(buf *" b );
518.BI "int BOK(buf *" b );
d056fbdf 519.PP
9b5ac6ff 520.BI "int buf_ensure(buf *" b ", size_t " sz );
adec5584 521.BI "int buf_tryextend(buf *" b ", size_t " sz );
9b5ac6ff 522.BI "int BENSURE(buf *" b ", size_t " sz );
5c819006 523.BI "octet *BSTEP(buf *" b ", size_t " sz );
d056fbdf 524.PP
9b5ac6ff 525.BI "void *buf_get(buf *" b ", size_t " sz );
526.BI "void *buf_put(buf *" b ", const void *" p ", size_t " sz );
d056fbdf 527.PP
9b5ac6ff 528.BI "int buf_getbyte(buf *" b );
adec5584 529.BI "int buf_putbyte(buf *" b ", int " ch );
d056fbdf 530.PP
adec5584
MW
531.BI "int buf_putstr(buf *" b ", const char *" p ", ...);"
532.BI "int buf_vputstr(buf *" b ", const char *" p ", va_list *" ap );
d056fbdf 533.PP
adec5584
MW
534.fi
535For
536.I suff
537in
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 ,
547and
548.BR 32b ,
549and, if a 64-bit integer type is available,
550.BR 64 ,
551.BR 64l ,
552and
553.BR 64b :
554.nf
9b5ac6ff 555.BI "int buf_putu" suff "(buf *" b ", uint" suff " " w );
adec5584 556.BI "int buf_getu" suff "(buf *" b ", uint" suff " *" w );
d056fbdf 557.PP
adec5584
MW
558.fi
559For
560.I suff
561in
562.BR 64 ,
563.BR 64l ,
564and
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 );
d056fbdf 569.PP
adec5584
MW
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"
d056fbdf 579.PP
adec5584
MW
580.fi
581For
582.I suff
583in
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 ,
596and
597.BR 64_B ,
598.nf
599.ta 2n
600.BI "BUF_ENCLOSE" suff "(buf *" b ", size_t " mk )
601.I " body"
d056fbdf 602.PP
adec5584
MW
603.BI "BUF_ENCLOSEZ(buf *" b )
604.I " body"
d056fbdf 605.PP
adec5584
MW
606.fi
607For
608.I suff
609in
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 ,
623and
624.BR z :
625.nf
9b5ac6ff 626.BI "int buf_putstr" suff "(buf *" b ", const char *" p );
adec5584
MW
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 );
d056fbdf 644.PP
9b5ac6ff 645.fi
adec5584
MW
646For
647.I suff
648in
649.BR 64 ,
650.BR 64l ,
651and
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.
c4ccbbf9 660.\"--------------------------------------------------------------------------
9b5ac6ff 661.SH DESCRIPTION
662The
663.B buf
664interface allows relatively convenient reading and writing of structured
665binary data from and to fixed-size memory buffers. It's useful for
666formatting and parsing down network data packets, for example.
adec5584 667.
9b5ac6ff 668.SS "Buffer basics"
669A buffer has three important pointers associated with it:
670.TP
671.I base
672The base address of the buffer.
673.TP
674.I limit
675Just past the last usable byte in the buffer
676.TP
677.I current
678The position in the buffer at which the next read or write will occur.
679.PP
680A buffer is created using the
681.B buf_init
682function. You must pass it the buffer base address and size, and a
d4efbcd9 683pointer to a
9b5ac6ff 684.B buf
685structure to fill in. It doesn't allocate any memory, so you don't need
686to dispose of the
687.B buf
688structure in any way before forgetting about it.
689.PP
690A collection of macros is provided for finding the positions of the
691various interesting pointers known about a buffer, and the sizes of the
692regions of memory they imply.
693.TP
694.B BBASE
695The buffer's
696.I base
697pointer.
698.TP
699.B BLIM
700The buffer's
701.I limit
702pointer.
703.TP
704.B BCUR
705The buffer's
706.I current
707pointer.
708.TP
709.B BSZ
710The size of the buffer; i.e.,
711.I limit
712\-
713.IR base .
714.TP
715.B BLEN
716The length of data in the buffer (if writing) or the amount of data
d4efbcd9 717read (if reading); i.e.,
9b5ac6ff 718.I current
719\-
720.IR base .
721.TP
722.B BLEFT
723The amount of space left in the buffer (if writing) or the amount of
724data yet to read (if reading); i.e.,
725.I limit
726\-
727.IR current .
728.PP
729The function
730.B buf_flip
731takes a buffer which has been used for writing, and makes it suitable
732for reading. This turns out to be useful when building packets in
d4efbcd9 733multi-layered networking software. Its precise behaviour is to preserve
9b5ac6ff 734.IR base ,
735to set
736.I limit
737to
738.IR current ,
d4efbcd9 739and to set
9b5ac6ff 740.I current
741to
742.IR base .
adec5584
MW
743There is a macro version,
744.BR BFLIP ,
745which does the same thing,
746but it may evaluate its buffer argument multiple times.
9b5ac6ff 747.PP
748A buffer can be
749.IR broken ,
750to indicate that it has overflowed or that its contents are otherwise
751invalid. The various buffer access functions described below all fail
752on a broken buffer, and any errors they encounter cause the buffer to
753become broken. Most simple programs which only use the supplied buffer
754access functions can avoid the tedium of error-checking every function
755call and just check the brokenness state at the end of their run.
756.PP
757The function
758.B buf_break
adec5584
MW
759or its
760macro equivalent
761.B BBREAK
762will break a buffer:
763the function returns \-1 as a possible, but minor, convenience;
764the macro expands to a statement and cannot return a value.
765The macro
9b5ac6ff 766.B BBAD
767reports true (nonzero) if its buffer argument is broken, or false (zero)
768otherwise; its counterpart
769.B BOK
770reports true if the buffer is OK, and false if it is broken.
adec5584 771.
9b5ac6ff 772.SS "Low-level buffer access"
773Access to the data in the buffer is usually sequential. The
774.B BENSURE
775macro (or the equivalent
776.B buf_ensure
777function) checks that the buffer is OK and that there is enough space
778remaining in the buffer for
779.I sz
780bytes: if so, it returns zero; otherwise it breaks the buffer and
781returns \-1.
782.PP
783The
784.B BSTEP
785macro advances the buffer's
786.I current
787pointer by
788.I sz
789bytes. It does no bounds checking. Together with
790.BR BENSURE ,
791this provides sequential access to the buffer's contents.
792.PP
793The
794.B buf_get
795function is the basis of most buffer access functions, whether for
796reading or writing. If the buffer is OK, and there are
797.I sz
798or more bytes remaining, it steps the buffer's
799.I current
800pointer by
801.I sz
d4efbcd9 802and returns the
9b5ac6ff 803.I original
804(pre-stepping)
805.I current
806pointer; otherwise it breaks the buffer if necessary, and returns a null
807pointer.
808.PP
809The
810.B buf_put
d4efbcd9 811function writes
9b5ac6ff 812.I sz
813bytes of data starting at
814.I p
815to the buffer. If it succeeded, it returns 0; otherwise it returns \-1.
adec5584 816.
9b5ac6ff 817.SS "Formatted buffer access"
818The function
819.B buf_getbyte
820returns the next byte from a buffer as a nonnegative integer, or \-1 on
821error. The function
822.B buf_putbyte
823writes its argument to a buffer, and returns 0 on succes; it returns \-1
824if it failed.
825.PP
826Many of the remaining functions deal with integer formatting and buffer
827lengths. The functions support 8-, 16-, 24- and 32-bit integers, in
828big- or little-endian order; on platforms with 64-bit integers, these
829are supported too. The functions' names carry a suffix which is the
830width in bits of the integers they deal with and an optional
831.RB ` l '
832for little- or
833.RB ` b '
834for big-endian byte order. (The variant with no letter uses big-endian
835order. Use of these variants tends to mean `I don't really care, but be
836consistent,' and is not recommended if you have an externally-defined
837spec you're meant to be compatible with.)
838.PP
839The function
840.BI buf_getu suff
841reads an integer. On success, it stores the integer it read at the
842address
843.I w
844given, and returns zero; on failure, it returns \-1. The function
845.BI buf_putu suff
846write an integer. It returns zero on success or \-1 on failure.
847.PP
adec5584
MW
848For (portability to) platforms without 64-bit integers, the functions
849.B buf_getk64
850and
851.B buf_putk64
852(and
853.RB ` l '-
854and
855.RB ` b '-suffixed
856variants) perform the necessary functionality, but acting on the
857.B kludge64
858type; see
859.BR bits (3).
860.PP
861The functions
862.BR buf_getf64 ,
863.BR buf_getf64l ,
864and
865.BR buf_getf64b
866read 64-bit floating-point values
867in IEEE\ 754 Binary64 format
868from the buffer;
869as usual, the suffix indicates the byte ordering convention.
870On success, they store the result in
871.BI *x
872and return zero;
873on failure, they break the buffer and return zero.
874The functions
875.BR buf_putf64 ,
876.BR buf_putf64l ,
877and
878.BR buf_putf64b
879write floating-point numbers
880in IEEE\ 754 Binary64 format
881from the buffer.
882On success, they return zero; on failure, they return \-1.
883Note that these functions use IEEE\ 754 format
884even if this is not the platform-native floating-point representation.
885.PP
886The function
887.B buf_putstrf
888processes a
889.BR printf (3)-like
890format string and arguments,
891writing the output to the buffer.
892The function
893.B buf_vputstrf
894does the same,
895except that it reads arguments from a
896.B va_list
897captured argument tail,
898leaving the tail ready to read the next unprocessed argument.
899Both functions return the number of bytes written on success
900or \-1 on failure.
901Note that these functions apply no length framing or termination.
c4ccbbf9
MW
902They are implemented using
903.BR gprintf (3);
904the output operations table is exposed as
905.BR buf_printops ;
906the functions expect the output pointer to be the address of the output
907.BR buf .
adec5584 908.PP
9b5ac6ff 909Functions which deal with block lengths assume the length is prefixed to
adec5584
MW
910the data, and don't include themselves. They come in all of the integer
911size variants, including 64-bits even on platforms without 64-bit integers;
912they also have an additional
9b5ac6ff 913.RB ` z '
914variant, which deals with zero-terminated data. No checks are done on
915writing that the data written contains no zero bytes.
916.PP
917The function
918.BI buf_getmem suff
919fetches a block of data. On success, it returns its base address and
920stores its length at the given address; on failure, it returns null.
921The function
922.BI buf_putmem suff
923writes a block of data; it return zero on success or \-1 on failure.
924.PP
925The functon
926.BI buf_getbuf suff
927fetches a block of data and makes a second buffer point to it, i.e.,
928setting its
929.I base
930and
931.I current
932pointers to the start of the block and its
933.I limit
934pointer to just past the end. No copying of bulk data is performed.
935The function
936.BI buf_putbuf suff
937writes the contents of a buffer (i.e., between its
938.I base
939and
940.I current
941pointers). The function
942.BI buf_getdstr suff
943fetches a block of data and append it to a dynamic string (see
944.BR dstr (3)).
945The function
946.BI buf_putdstr suff
947writes the contents of a dynamic string to a buffer. Finally, the
948function
949.BI buf_putstr suff
950writes a standard C null-terminated string to a buffer. All these
951functions return zero on success or \-1 on failure.
adec5584
MW
952.PP
953The function
954.BI buf_putstrf suff
955processes a
956.BR printf (3)-like
957format string and arguments,
958writing the output to the buffer.
959The function
960.BI buf_vputstrf suff
961does the same,
962except that it reads arguments from a
963.B va_list
964captured argument tail,
965leaving the tail ready to read the next unprocessed argument.
966Both functions return the number of bytes written on success
967or \-1 on failure.
968These functions add framing around the output:
969either a length prefix, or a trailing zero byte.
970.PP
971The
972.BI BUF_ENCLOSE suff
973macros are syntactically statement heads.
974(Notice that these macros use
975.RB ` _L '
976and
977.RB ` _B '
978suffixes for little- and big-endian byte order.)
979They leave space in the buffer for appropriate length framing,
980and execute the following
981.I body
982statement
983(which, of course, can be a compound statement enclosed in braces).
984When the
985.I body
986completes, the macro fills in space
987with the length of material written by the
988.IR body .
989The
990.I mk
991argument should be a variable of type
992.B size_t
993which will be overwritten by the macro.
994If the material is so large that its won't fit in the space
995then the buffer is broken.
996The
997.B BUF_ENCLOSEZ
998macro is similar,
999except that it just writes a terminating zero byte
1000after whatever material was written by the
1001.IR body .
1002.PP
1003The
1004.BR BUF_ENCLOSE ...\&
1005macros are based on lower-level machinery.
1006The
1007.B BUF_ENCLOSEITAG
1008macro takes an additional argument
1009.IR W ;
1010it leaves
1011.BI SZ_ W
1012bytes for the length,
1013checks that the length doesn't exceed
1014.BI MASK W \fR,
1015and stores the length using
1016.BI STORE W \fR;
1017all of these constants and macros are defined in
1018.BR <mLib/bits.h> .
1019The
1020.B BUF_ENCLOSEKTAG
1021is similar, except that it uses the
1022.B kludge64
1023machinery to handle 64-bit length fields.
1024The
1025.B BUF_ENCLOSEZTAG
1026macro is superficially similar,
1027but much simpler,
1028since it all it does is write a zero byte after its
1029.I body
1030completes.
1031All of those macros also take an additional
1032.I tag
1033argument
1034used to scope the internal labels they construct:
1035see
1036.BR control (3)
1037for the details on how this works.
1038.PP
1039The
1040.B BUF_ENCLOSEITAG
1041and
1042.B BUF_ENCLOSEKTAG
1043macros are themselves built from a lower-level macro named
1044.BR BUF_ENCLOSETAG .
1045In place of the
1046.I W
1047argument, it takes three arguments:
1048.I check
1049is an expression which should evaluate true if the length
1050.B _delta
1051can be represented;
1052.I poke
1053is a macro, invoked as
1054.IB poke "(unsigned char *" p ", " size_t n ")" \fR,
1055which should store
1056.I n
1057at address
1058.IR p ,
1059formatted in whatever way is appropriate;
1060and
1061.I lensz
1062is the amount of space, in bytes, to save for the length.
1063.
1064.SS "Dynamic buffers"
1065The type
1066.B dbuf
1067is a
1068.IR "dynamic buffer" .
1069It contains a buffer structure,
1070accessible using the
1071p.B DBUF_BUF
1072macro.
1073The ordinary buffer functions and macros can be used on this buffer,
1074though, for convenience,
1075there are similarly named functions and macros
1076which accept a
1077.B dbuf
1078argument directly.
1079There is
1080.I "no difference"
1081between the behaviour of the
1082.B "buf"
1083and
1084.B "dbuf"
1085functions.
1086.PP
1087A dynamic buffer is created by statically initializing it with
1088.BR DBUF_INIT ,
1089or by calling
1090.BR dbuf_create
1091or its macro equivalent
1092.BR DBCREATE .
1093The memory backing a dynamic buffer can be freed by
1094.BR dbuf_destroy
1095or the macro equivalent
1096.BR DBDESTROY ;
1097these leave the buffer in the state established by initialization:
1098the buffer holds no resources, but is ready for immediate use.
1099.PP
1100A dynamic buffer contains an
1101.B buf
1102buffer,
1103called its
1104.I underlying
1105buffer.
1106The underlying buffer is accessible through the
1107.B DBUF_BUF
1108macro.
1109All of the above functions and macros can be applied
1110to a dynamic buffer's underlying buffer.
1111As a convenience,
1112corresponding to each of the functions and macros described above,
1113there is a version named with an initial
1114.RB ` d '
1115or
1116.RB ` D '
1117as appropriate,
1118which accepts a pointer to a dynamic buffer
1119rather than an ordinary buffer,
1120and acts on its underlying buffer.
1121Note that these functions are in no way special.
1122A dynamic buffer will grow automatically
1123in response to either kind of functions.
1124.PP
1125A freshly created buffer is in
1126.I write
1127mode,
1128and is empty, with.
1129In this state, it will automatically extend its backing storage
1130in response to
1131.B BENSURE
1132calls, rather than breaking.
1133As a result,
1134an
1135.I "a priori"
1136unpredictable amount of data can be written to a dynamic buffer
1137and it will automatically grow as necessary to accommodate it.
1138Of course, the
1139.B BSZ
1140and
1141.B BLEFT
1142queries are somewhat meaningless when applied to dynamic buffers \(en
1143though perfectly valid.
1144The critical function for this is
1145.B buf_tryextend
1146(also accessible as
1147.BR dbuf_tryextend )
1148which attempts to arrange that at least
1149.I sz
1150unused bytes are available in the buffer \(en
1151i.e., that
1152.B BLEFT
1153would return at least
1154.IR sz .
1155If it succeeds, it returns zero;
1156it will fail if the buffer is not in write mode,
1157or if the buffer is not dynamic,
1158in which case it returns \-1.
1159It is unlikely that applications will call this function directly.
1160.PP
1161The
1162.B buf_flip
1163(or its macro equivalent)
1164switches the buffer to
1165.I read
1166mode,
1167in addition to its usual behaviour of
1168setting the buffer's limit to its current position
1169and its current position to its base.
1170In read mode, a dynamic buffer will no longer grow dynamically,
1171as one would expect.
1172.PP
1173The
1174.B dbuf_reset
1175function,
1176and its macro equivalent
1177.B DBRESET
1178(which may evaluate its argument multiple times)
1179will return a dynamic buffer to write mode,
1180and also restore its current position to its base and
1181clear its broken flag.
1182.
c4ccbbf9 1183.\"--------------------------------------------------------------------------
9b5ac6ff 1184.SH "SEE ALSO"
c4ccbbf9 1185.
adec5584
MW
1186.BR bits (3),
1187.BR control (3),
9b5ac6ff 1188.BR dstr (3),
c4ccbbf9 1189.BR gprintf (3),
9b5ac6ff 1190.BR mLib (3).
adec5584 1191.
c4ccbbf9 1192.\"--------------------------------------------------------------------------
9b5ac6ff 1193.SH AUTHOR
c4ccbbf9 1194.
9b5ac6ff 1195Mark Wooding, <mdw@distorted.org.uk>
c4ccbbf9
MW
1196.
1197.\"----- That's all, folks --------------------------------------------------