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