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