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