@@@ man wip
[mLib] / buf / pkbuf.3
CommitLineData
1e7e4330 1.\" -*-nroff-*-
fbf20b5b 2.TH pkbuf 3 "16 July 2000" "Straylight/Edgeware" "mLib utilities library"
1e7e4330 3.SH "NAME"
4pkbuf \- split packets out of asynchronously received blocks
5.\" @pkbuf_flush
6.\" @pkbuf_close
7.\" @pkbuf_free
8.\" @pkbuf_snarf
9.\" @pkbuf_want
10.\" @pkbuf_init
11.\" @pkbuf_destroy
12.SH "SYNOPSIS"
13.nf
adec5584 14.ta 2n
1e7e4330 15.B "#include <mLib/pkbuf.h>"
16
4729aa69 17.B "enum {"
adec5584 18.B " PKBUF_ENABLE = ..."
4729aa69
MW
19.B "};"
20
21.B "typedef struct {"
adec5584
MW
22.B " unsigned f;"
23.B " ..."
4729aa69
MW
24.B "} pkbuf;"
25
adec5584
MW
26.ta \w'\fBtypedef void pkbuf_func('u
27.B "typedef void pkbuf_func(octet *" b ", size_t " sz ", pkbuf *" p ,
28.BI " size_t *" keep ", void *" p );
4729aa69 29
1e7e4330 30.BI "void pkbuf_flush(pkbuf *" pk ", octet *" p ", size_t " len );
31.BI "void pkbuf_close(pkbuf *" pk );
32.BI "size_t pkbuf_free(pkbuf *" pk ", octet **" p );
33.BI "void pkbuf_snarf(pkbuf *" pk ", const void *" p ", size_t " sz );
34.BI "void pkbuf_want(pkbuf *" pk ", size_t " want );
0daaeb18 35.BI "void pkbuf_init(pkbuf *" pk ", pkbuf_func *" func ", void *" p );
1e7e4330 36.BI "void pkbuf_destroy(pkbuf *" pk );
37.fi
38.SH "DESCRIPTION"
39The declarations in
40.B <mLib/pkbuf.h>
41implement a
42.IR "packet buffer" .
43Given unpredictably-sized chunks of data, the packet buffer extracts
44completed packets of data, with sizes ascertained by a handler
d4efbcd9 45function.
1e7e4330 46.PP
47The state of a packet buffer is stored in an object of type
48.BR pkbuf .
49This is a structure which must be allocated by the caller. The
50structure should normally be considered opaque (see the section on
51.B Disablement
52for an exception to this).
53.SS "Initialization and finalization"
54The function
55.B pkbuf_init
56initializes a packet buffer ready for use. It is given three arguments:
57.TP
58.BI "pkbuf *" pk
59A pointer to the block of memory to use for the packet buffer. The packet
60buffer will allocate memory to store incoming data automatically: this
61structure just contains bookkeeping information.
62.TP
0daaeb18 63.BI "pkbuf_func *" func
1e7e4330 64The
65.I packet-handler
66function to which the packet buffer should pass packets of data when
0daaeb18 67they're received. See
68.B "Packet breaking and the handler function"
69below.
1e7e4330 70.TP
71.BI "void *" p
72A pointer argument to be passed to the function when a packet arrives.
73.PP
74By default, the buffer is
75allocated from the current arena,
76.BR arena_global (3);
77this may be changed by altering the buffer's
78.B a
79member to refer to a different arena at any time when the buffer is
80unallocated.
81.PP
82A packet buffer must be destroyed after use by calling
83.BR pkbuf_destroy ,
84passing it the address of the buffer block.
85.SS "Inserting data into the buffer"
86There are two interfaces for inserting data into the buffer. One's much
87simpler than the other, although it's less expressive.
88.PP
89The simple interface is
90.BR pkbuf_snarf .
91This function is given three arguments: a pointer
92.I pk
93to a packet buffer structure; a pointer
94.I p
528c8b4d 95to a chunk of data to read; and the size
1e7e4330 96.I sz
97of the chunk of data. The data is pushed through the packet buffer and
98any complete packets are passed on to the packet handler.
99.PP
100The complex interface is the pair of functions
101.I pkbuf_free
102and
103.IR pkbuf_flush .
104.PP
d4efbcd9 105The
1e7e4330 106.B pkbuf_free
107function returns the address and size of a free portion of the packet
108buffer's memory into which data may be written. The function is passed
d4efbcd9 109the address
1e7e4330 110.I pk
111of the packet buffer. Its result is the size of the free area, and it
112writes the base address of this free space to the location pointed to by
113the argument
114.IR p .
115The caller's data must be written to ascending memory locations starting
116at
117.BI * p
118and no data may be written beyond the end of the free space. However,
119it isn't necessary to completely fill the buffer.
120.PP
121Once the free area has had some data written to it,
122.B pkbuf_flush
123is called to examine the new data and break it into packets. This is
124given three arguments:
125.TP
126.BI "pkbuf *" pk
127The address of the packet buffer.
128.TP
129.BI "octet *" p
130The address at which the new data has been written. This must be the
131base address returned from
132.BR pkbuf_free .
133.TP
134.BI "size_t " len
135The number of bytes which have been written to the buffer.
136.PP
137The
138.B pkbuf_flush
139function breaks the new data into packets as described below, and passes
140each one in turn to the packet-handler function.
141.PP
142The
143.B pkbuf_snarf
144function is trivially implemented in terms of the more complex
528c8b4d 145.BR pkbuf_free / pkbuf_flush
1e7e4330 146interface.
0daaeb18 147.SS "Packet breaking and the handler function"
1e7e4330 148The function
149.B pkbuf_want
150is used to inform the packet buffer of the expected length of the next
151packet. It is given the pointer
152.I pk
153to the packet buffer and a size
154.I sz
155of the packet.
156.PP
4729aa69
MW
157When enough data has arrived, the packet-handler function is called. It
158is passed:
1e7e4330 159.TP
160.BI "octet *" b
161A pointer to the packet data in the buffer, or zero to signify
162end-of-file.
163.TP
164.BI "size_t " sz
165The size of the packet, as previously configured via
166.BR pkbuf_want .
167.TP
168.BI "pkbuf *" pk
169A pointer to the packet buffer.
170.TP
171.BI "size_t *" keep
172A location in which to store the number of bytes of the current packet
173to be retained. The bytes kept are from the end of the current packet:
174if you want to keep bytes from the beginning of the packet, you should
175move them into the right place.
176.TP
177.BI "void *" p
178The pointer which was set up in the call to
179.BR pkbuf_init .
180.PP
181.SS "Flushing the remaining data"
182When the client program knows that there's no more data arriving (for
183example, an end-of-file condition exists on its data source) it should
184call the function
185.BR pkbuf_close .
186This will call the handler one final time with a null pointer to inform
187it of the end-of-file.
188.SS "Disablement"
189The packet buffer is intended to be used in higher-level program
190objects, such as the packet selector described in
191.BR selpk (3).
192Unfortunately, a concept from this high level needs to exist at the
193packet buffer level, which complicates the description somewhat. The
194idea is that, when a packet-handler attached to some higher-level object
195decides that it's read enough, it can
196.I disable
197the object so that it doesn't see any more data.
198.PP
199Clearly, since an
200.B pkbuf_flush
528c8b4d 201call can emit more than one packet, it must be aware that the packet
1e7e4330 202handler isn't interested in any more packet. However, this fact must
203also be signalled to the higher-level object so that it can detach
204itself from its data source.
205.PP
206Rather than invent some complex interface for this, the packet buffer
3bc42912 207exports one of its structure members, a flags words called
208.BR f .
1e7e4330 209A higher-level object wishing to disable the packet buffer simply clears
210the bit
211.B PKBUF_ENABLE
3bc42912 212in this flags word.
1e7e4330 213.PP
214Disabling a buffer causes an immediate return from
215.BR pkbuf_flush .
216However, it is not permitted for the functions
217.B pkbuf_flush
218or
219.B pkbuf_close
220to be called on a disabled buffer. (This condition isn't checked for;
221it'll just do the wrong thing.) Furthermore, the
222.B pkbuf_snarf
223function does not handle disablement at all, because it would complicate
224the interface so much that it wouldn't have any advantage over the more
225general
226.BR pkbuf_free / pkbuf_flush .
227.SH "SEE ALSO"
228.BR lbuf (3),
229.BR selpk (3),
230.BR mLib (3).
231.SH "AUTHOR"
9b5ac6ff 232Mark Wooding, <mdw@distorted.org.uk>