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